13344563e90509b028edbf6b301ca7d8edb7ee76
[occt.git] / src / AIS / AIS_InteractiveContext.cxx
1 // Created on: 1997-01-17
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1997-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 #include <AIS_InteractiveContext.hxx>
18
19 #include <AIS_DataMapIteratorOfDataMapOfIOStatus.hxx>
20 #include <AIS_ConnectedInteractive.hxx>
21 #include <AIS_GlobalStatus.hxx>
22 #include <AIS_InteractiveObject.hxx>
23 #include <AIS_MultipleConnectedInteractive.hxx>
24 #include <Precision.hxx>
25 #include <Prs3d_DatumAspect.hxx>
26 #include <Prs3d_IsoAspect.hxx>
27 #include <Prs3d_LineAspect.hxx>
28 #include <Prs3d_PlaneAspect.hxx>
29 #include <Prs3d_PointAspect.hxx>
30 #include <Prs3d_ShadingAspect.hxx>
31 #include <SelectMgr_EntityOwner.hxx>
32 #include <TColStd_MapIteratorOfMapOfTransient.hxx>
33 #include <TopLoc_Location.hxx>
34 #include <V3d_View.hxx>
35 #include <V3d_Viewer.hxx>
36
37 #include <AIS_Shape.hxx>
38 #include <StdSelect_BRepOwner.hxx>
39 #include <TopoDS_Shape.hxx>
40
41 IMPLEMENT_STANDARD_RTTIEXT(AIS_InteractiveContext, Standard_Transient)
42
43 namespace
44 {
45   typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), Handle(SelectMgr_IndexedMapOfOwner)> AIS_MapOfObjectOwners;
46   typedef NCollection_DataMap<Handle(SelectMgr_SelectableObject), Handle(SelectMgr_IndexedMapOfOwner)>::Iterator AIS_MapIteratorOfMapOfObjectOwners;
47
48   //! Initialize default highlighting attributes.
49   static void initDefaultHilightAttributes (const Handle(Prs3d_Drawer)& theDrawer,
50                                             const Quantity_Color& theColor)
51   {
52     theDrawer->SetMethod (Aspect_TOHM_COLOR);
53     theDrawer->SetDisplayMode (0);
54     theDrawer->SetColor (theColor);
55
56     theDrawer->SetupOwnShadingAspect();
57     theDrawer->SetupOwnPointAspect();
58     theDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
59     *theDrawer->LineAspect()->Aspect() = *theDrawer->Link()->LineAspect()->Aspect();
60     theDrawer->SetWireAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
61     *theDrawer->WireAspect()->Aspect() = *theDrawer->Link()->WireAspect()->Aspect();
62     theDrawer->SetPlaneAspect (new Prs3d_PlaneAspect());
63     *theDrawer->PlaneAspect()->EdgesAspect() = *theDrawer->Link()->PlaneAspect()->EdgesAspect();
64     theDrawer->SetFreeBoundaryAspect   (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
65     *theDrawer->FreeBoundaryAspect()->Aspect() = *theDrawer->Link()->FreeBoundaryAspect()->Aspect();
66     theDrawer->SetUnFreeBoundaryAspect (new Prs3d_LineAspect (Quantity_NOC_BLACK, Aspect_TOL_SOLID, 1.0));
67     *theDrawer->UnFreeBoundaryAspect()->Aspect() = *theDrawer->Link()->UnFreeBoundaryAspect()->Aspect();
68     theDrawer->SetDatumAspect (new Prs3d_DatumAspect());
69
70     theDrawer->ShadingAspect()->SetColor (theColor);
71     theDrawer->WireAspect()->SetColor (theColor);
72     theDrawer->LineAspect()->SetColor (theColor);
73     theDrawer->PlaneAspect()->ArrowAspect()->SetColor (theColor);
74     theDrawer->PlaneAspect()->IsoAspect()->SetColor (theColor);
75     theDrawer->PlaneAspect()->EdgesAspect()->SetColor (theColor);
76     theDrawer->FreeBoundaryAspect()->SetColor (theColor);
77     theDrawer->UnFreeBoundaryAspect()->SetColor (theColor);
78     theDrawer->PointAspect()->SetColor (theColor);
79     for (Standard_Integer aPartIter = 0; aPartIter < Prs3d_DatumParts_None; ++aPartIter)
80     {
81       if (Handle(Prs3d_LineAspect) aLineAsp = theDrawer->DatumAspect()->LineAspect ((Prs3d_DatumParts )aPartIter))
82       {
83         aLineAsp->SetColor (theColor);
84       }
85     }
86
87     theDrawer->WireAspect()->SetWidth (2.0);
88     theDrawer->LineAspect()->SetWidth (2.0);
89     theDrawer->PlaneAspect()->EdgesAspect()->SetWidth (2.0);
90     theDrawer->FreeBoundaryAspect()  ->SetWidth (2.0);
91     theDrawer->UnFreeBoundaryAspect()->SetWidth (2.0);
92     theDrawer->PointAspect()->SetTypeOfMarker (Aspect_TOM_O_POINT);
93     theDrawer->PointAspect()->SetScale (2.0);
94
95     // the triangulation should be computed using main presentation attributes,
96     // and should not be overridden by highlighting
97     theDrawer->SetAutoTriangulation (Standard_False);
98   }
99 }
100
101 //=======================================================================
102 //function : AIS_InteractiveContext
103 //purpose  : 
104 //=======================================================================
105
106 AIS_InteractiveContext::AIS_InteractiveContext(const Handle(V3d_Viewer)& MainViewer):
107 myMainPM (new PrsMgr_PresentationManager (MainViewer->StructureManager())),
108 myMainVwr(MainViewer),
109 myToHilightSelected(Standard_True),
110 mySelection(new AIS_Selection()),
111 myFilters (new SelectMgr_AndOrFilter(SelectMgr_FilterType_OR)),
112 myDefaultDrawer(new Prs3d_Drawer()),
113 myCurDetected(0),
114 myCurHighlighted(0),
115 myPickingStrategy (SelectMgr_PickingStrategy_FirstAcceptable),
116 myAutoHilight(Standard_True),
117 myIsAutoActivateSelMode(Standard_True)
118 {
119   mgrSelector = new SelectMgr_SelectionManager (new StdSelect_ViewerSelector3d());
120
121   myStyles[Prs3d_TypeOfHighlight_None]          = myDefaultDrawer;
122   myStyles[Prs3d_TypeOfHighlight_Selected]      = new Prs3d_Drawer();
123   myStyles[Prs3d_TypeOfHighlight_Dynamic]       = new Prs3d_Drawer();
124   myStyles[Prs3d_TypeOfHighlight_LocalSelected] = new Prs3d_Drawer();
125   myStyles[Prs3d_TypeOfHighlight_LocalDynamic]  = new Prs3d_Drawer();
126   myStyles[Prs3d_TypeOfHighlight_SubIntensity]  = new Prs3d_Drawer();
127
128   myDefaultDrawer->SetupOwnDefaults();
129   myDefaultDrawer->SetZLayer(Graphic3d_ZLayerId_Default);
130   myDefaultDrawer->SetDisplayMode(0);
131   {
132     const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_Dynamic];
133     aStyle->Link (myDefaultDrawer);
134     initDefaultHilightAttributes (aStyle, Quantity_NOC_CYAN1);
135     aStyle->SetZLayer(Graphic3d_ZLayerId_Top);
136   }
137   {
138     const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_LocalDynamic];
139     aStyle->Link (myDefaultDrawer);
140     initDefaultHilightAttributes (aStyle, Quantity_NOC_CYAN1);
141     aStyle->SetZLayer(Graphic3d_ZLayerId_Topmost);
142   }
143   {
144     const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_Selected];
145     aStyle->Link (myDefaultDrawer);
146     initDefaultHilightAttributes (aStyle, Quantity_NOC_GRAY80);
147     aStyle->SetZLayer(Graphic3d_ZLayerId_UNKNOWN);
148   }
149   {
150     const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_LocalSelected];
151     aStyle->Link (myDefaultDrawer);
152     initDefaultHilightAttributes (aStyle, Quantity_NOC_GRAY80);
153     aStyle->SetZLayer(Graphic3d_ZLayerId_UNKNOWN);
154   }
155   {
156     const Handle(Prs3d_Drawer)& aStyle = myStyles[Prs3d_TypeOfHighlight_SubIntensity];
157     aStyle->SetZLayer(Graphic3d_ZLayerId_UNKNOWN);
158     aStyle->SetMethod(Aspect_TOHM_COLOR);
159     aStyle->SetColor (Quantity_NOC_GRAY40);
160   }
161
162   InitAttributes();
163 }
164
165 //=======================================================================
166 //function : ~AIS_InteractiveContext
167 //purpose  :
168 //=======================================================================
169 AIS_InteractiveContext::~AIS_InteractiveContext()
170 {
171   // clear the current selection
172   mySelection->Clear();
173   mgrSelector.Nullify();
174
175   Handle(AIS_InteractiveContext) aNullContext;
176   for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
177   {
178     const Handle(AIS_InteractiveObject)& anObj = anObjIter.Key();
179     anObj->SetContext (aNullContext);
180     for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
181     {
182       aSelIter.Value()->UpdateBVHStatus (SelectMgr_TBU_Renew);
183     }
184   }
185 }
186
187 //=======================================================================
188 //function : LastActiveView
189 //purpose  :
190 //=======================================================================
191 Handle(V3d_View) AIS_InteractiveContext::LastActiveView() const
192 {
193   if (myLastActiveView == NULL
194    || myMainVwr.IsNull())
195   {
196     return Handle(V3d_View)();
197   }
198
199   // as a precaution - check that myLastActiveView pointer is a valid active View
200   for (V3d_ListOfViewIterator aViewIter = myMainVwr->ActiveViewIterator(); aViewIter.More(); aViewIter.Next())
201   {
202     if (aViewIter.Value() == myLastActiveView)
203     {
204       return aViewIter.Value();
205     }
206   }
207   return Handle(V3d_View)();
208 }
209
210 //=======================================================================
211 //function : UpdateCurrentViewer
212 //purpose  : 
213 //=======================================================================
214
215 void AIS_InteractiveContext::UpdateCurrentViewer()
216 {
217   if (!myMainVwr.IsNull())
218     myMainVwr->Update();
219 }
220
221 //=======================================================================
222 //function : DisplayedObjects
223 //purpose  :
224 //=======================================================================
225 void AIS_InteractiveContext::DisplayedObjects (AIS_ListOfInteractive& theListOfIO) const
226 {
227   for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
228   {
229     if (anObjIter.Key()->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
230     {
231       theListOfIO.Append (anObjIter.Key());
232     }
233   }
234 }
235
236 //=======================================================================
237 //function : DisplayedObjects
238 //purpose  :
239 //=======================================================================
240 void AIS_InteractiveContext::DisplayedObjects (const AIS_KindOfInteractive theKind,
241                                                const Standard_Integer      theSign,
242                                                AIS_ListOfInteractive&      theListOfIO) const
243 {
244   ObjectsByDisplayStatus (theKind, theSign, PrsMgr_DisplayStatus_Displayed, theListOfIO);
245 }
246
247 //=======================================================================
248 //function : ErasedObjects
249 //purpose  :
250 //=======================================================================
251 void AIS_InteractiveContext::ErasedObjects (AIS_ListOfInteractive& theListOfIO) const
252 {
253   ObjectsByDisplayStatus (PrsMgr_DisplayStatus_Erased, theListOfIO);
254 }
255
256 //=======================================================================
257 //function : ErasedObjects
258 //purpose  :
259 //=======================================================================
260 void AIS_InteractiveContext::ErasedObjects (const AIS_KindOfInteractive theKind,
261                                             const Standard_Integer      theSign,
262                                             AIS_ListOfInteractive&      theListOfIO) const
263 {
264   ObjectsByDisplayStatus (theKind, theSign, PrsMgr_DisplayStatus_Erased, theListOfIO);
265 }
266
267 //=======================================================================
268 //function : ObjectsByDisplayStatus
269 //purpose  :
270 //=======================================================================
271 void AIS_InteractiveContext::ObjectsByDisplayStatus (const PrsMgr_DisplayStatus theStatus,
272                                                      AIS_ListOfInteractive&  theListOfIO) const
273 {
274   for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
275   {
276     if (anObjIter.Key()->DisplayStatus() == theStatus)
277     {
278       theListOfIO.Append (anObjIter.Key());
279     }
280   }
281 }
282
283 //=======================================================================
284 //function : ObjectsByDisplayStatus
285 //purpose  :
286 //=======================================================================
287 void AIS_InteractiveContext::ObjectsByDisplayStatus (const AIS_KindOfInteractive theKind,
288                                                      const Standard_Integer      theSign,
289                                                      const PrsMgr_DisplayStatus  theStatus,
290                                                      AIS_ListOfInteractive&      theListOfIO) const
291 {
292   for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
293   {
294     if (theStatus != PrsMgr_DisplayStatus_None
295      && anObjIter.Key()->DisplayStatus() != theStatus)
296     {
297       continue;
298     }
299     else if (anObjIter.Key()->Type() != theKind)
300     {
301       continue;
302     }
303
304     if (theSign == -1
305      || anObjIter.Key()->Signature() == theSign)
306     {
307       theListOfIO.Append (anObjIter.Key());
308     }
309   }
310 }
311
312 //=======================================================================
313 //function : ObjectsInside
314 //purpose  :
315 //=======================================================================
316 void AIS_InteractiveContext::ObjectsInside (AIS_ListOfInteractive&      theListOfIO,
317                                             const AIS_KindOfInteractive theKind,
318                                             const Standard_Integer      theSign) const
319 {
320   if (theKind == AIS_KindOfInteractive_None
321    && theSign == -1)
322   {
323     for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
324     {
325       theListOfIO.Append (anObjIter.Key());
326     }
327     return;
328   }
329
330   for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
331   {
332     if (anObjIter.Key()->Type() != theKind)
333     {
334       continue;
335     }
336
337     if (theSign == -1
338      || anObjIter.Key()->Signature() == theSign)
339     {
340       theListOfIO.Append (anObjIter.Key());
341     }
342   }
343 }
344
345 //=======================================================================
346 //function : ObjectsForView
347 //purpose  :
348 //=======================================================================
349 void AIS_InteractiveContext::ObjectsForView (AIS_ListOfInteractive&  theListOfIO,
350                                              const Handle(V3d_View)& theView,
351                                              const Standard_Boolean  theIsVisibleInView,
352                                              const PrsMgr_DisplayStatus theStatus) const
353 {
354   Handle(Graphic3d_CView) aViewImpl = theView->View();
355   const Standard_Integer  aViewId   = aViewImpl->Identification();
356   for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
357   {
358     if (theStatus != PrsMgr_DisplayStatus_None
359      && anObjIter.Key()->DisplayStatus() != theStatus)
360     {
361       theListOfIO.Append (anObjIter.Key());
362       continue;
363     }
364
365     Handle(Graphic3d_ViewAffinity) anAffinity = anObjIter.Key()->ViewAffinity();
366     const Standard_Boolean isVisible = anAffinity->IsVisible (aViewId);
367     if (isVisible == theIsVisibleInView)
368     {
369       theListOfIO.Append (anObjIter.Key());
370     }
371   }
372 }
373
374 //=======================================================================
375 //function : Display
376 //purpose  :
377 //=======================================================================
378 void AIS_InteractiveContext::Display (const Handle(AIS_InteractiveObject)& theIObj,
379                                       const Standard_Boolean               theToUpdateViewer)
380 {
381   if (theIObj.IsNull())
382   {
383     return;
384   }
385
386   Standard_Integer aDispMode = 0, aHiMod = -1, aSelMode = -1;
387   GetDefModes (theIObj, aDispMode, aHiMod, aSelMode);
388   Display (theIObj, aDispMode, myIsAutoActivateSelMode ? aSelMode : -1, theToUpdateViewer);
389 }
390
391 //=======================================================================
392 //function : SetViewAffinity
393 //purpose  :
394 //=======================================================================
395 void AIS_InteractiveContext::SetViewAffinity (const Handle(AIS_InteractiveObject)& theIObj,
396                                               const Handle(V3d_View)&              theView,
397                                               const Standard_Boolean               theIsVisible)
398 {
399   if (theIObj.IsNull()
400   || !myObjects.IsBound (theIObj))
401   {
402     return;
403   }
404
405   Handle(Graphic3d_ViewAffinity) anAffinity = theIObj->ViewAffinity();
406   Handle(Graphic3d_CView) aViewImpl = theView->View();
407   anAffinity->SetVisible (aViewImpl->Identification(), theIsVisible == Standard_True);
408 }
409
410 //=======================================================================
411 //function : Display
412 //purpose  :
413 //=======================================================================
414 void AIS_InteractiveContext::Display (const Handle(AIS_InteractiveObject)& theIObj,
415                                       const Standard_Integer               theDispMode,
416                                       const Standard_Integer               theSelectionMode,
417                                       const Standard_Boolean               theToUpdateViewer,
418                                       const PrsMgr_DisplayStatus           theDispStatus)
419 {
420   if (theIObj.IsNull())
421   {
422     return;
423   }
424
425   if (theDispStatus == PrsMgr_DisplayStatus_Erased)
426   {
427     Erase  (theIObj, theToUpdateViewer);
428     Load (theIObj, theSelectionMode);
429     if (Handle(AIS_GlobalStatus)* aStatusPtr = myObjects.ChangeSeek (theIObj))
430     {
431       (*aStatusPtr)->SetDisplayMode (theDispMode);
432     }
433     return;
434   }
435
436   setContextToObject (theIObj);
437   if (!myObjects.IsBound (theIObj))
438   {
439     setObjectStatus (theIObj, PrsMgr_DisplayStatus_Displayed, theDispMode, theSelectionMode);
440     theIObj->ViewAffinity()->SetVisible (true); // reset view affinity mask
441     myMainVwr->StructureManager()->RegisterObject (theIObj, theIObj->ViewAffinity());
442     myMainPM->Display(theIObj, theDispMode);
443     if (theSelectionMode != -1)
444     {
445       const Handle(SelectMgr_SelectableObject)& anObj = theIObj; // to avoid ambiguity
446       if (!mgrSelector->Contains (anObj))
447       {
448         mgrSelector->Load (theIObj);
449       }
450       mgrSelector->Activate (theIObj, theSelectionMode);
451     }
452   }
453   else
454   {
455     Handle(AIS_GlobalStatus) aStatus = myObjects (theIObj);
456
457     // Mark the presentation modes hidden of interactive object different from aDispMode.
458     // Then make sure aDispMode is displayed and maybe highlighted.
459     // Finally, activate selection mode <SelMode> if not yet activated.
460     const Standard_Integer anOldMode = aStatus->DisplayMode();
461     if (anOldMode != theDispMode)
462     {
463       if(myMainPM->IsHighlighted (theIObj, anOldMode))
464       {
465         unhighlightGlobal (theIObj);
466       }
467       myMainPM->SetVisibility (theIObj, anOldMode, Standard_False);
468     }
469
470     aStatus->SetDisplayMode (theDispMode);
471
472     theIObj->SetDisplayStatus (PrsMgr_DisplayStatus_Displayed);
473     myMainPM->Display (theIObj, theDispMode);
474     if (aStatus->IsHilighted())
475     {
476       highlightGlobal (theIObj, aStatus->HilightStyle(), theDispMode);
477     }
478     if (theSelectionMode != -1)
479     {
480       const Handle(SelectMgr_SelectableObject)& anObj = theIObj; // to avoid ambiguity
481       if (!mgrSelector->Contains (anObj))
482       {
483         mgrSelector->Load (theIObj);
484       }
485       if (!mgrSelector->IsActivated (theIObj, theSelectionMode))
486       {
487         aStatus->AddSelectionMode (theSelectionMode);
488         mgrSelector->Activate (theIObj, theSelectionMode);
489       }
490     }
491   }
492
493   if (theToUpdateViewer)
494   {
495     myMainVwr->Update();
496   }
497 }
498
499 //=======================================================================
500 //function : Load
501 //purpose  :
502 //=======================================================================
503 void AIS_InteractiveContext::Load (const Handle(AIS_InteractiveObject)& theIObj,
504                                    const Standard_Integer               theSelMode)
505 {
506   if (theIObj.IsNull())
507   {
508     return;
509   }
510
511   setContextToObject (theIObj);
512   if (!myObjects.IsBound (theIObj))
513   {
514     Standard_Integer aDispMode, aHiMod, aSelModeDef;
515     GetDefModes (theIObj, aDispMode, aHiMod, aSelModeDef);
516     setObjectStatus (theIObj, PrsMgr_DisplayStatus_Erased, aDispMode, theSelMode != -1 ? theSelMode : aSelModeDef);
517     theIObj->ViewAffinity()->SetVisible (true); // reset view affinity mask
518     myMainVwr->StructureManager()->RegisterObject (theIObj, theIObj->ViewAffinity());
519   }
520
521   // Register theIObj in the selection manager to prepare further activation of selection
522   const Handle(SelectMgr_SelectableObject)& anObj = theIObj; // to avoid ambiguity
523   if (!mgrSelector->Contains (anObj))
524   {
525     mgrSelector->Load (theIObj);
526   }
527 }
528
529 //=======================================================================
530 //function : Erase
531 //purpose  :
532 //=======================================================================
533 void AIS_InteractiveContext::Erase (const Handle(AIS_InteractiveObject)& theIObj,
534                                     const Standard_Boolean               theToUpdateViewer)
535 {
536   if (theIObj.IsNull())
537   {
538     return;
539   }
540   
541   if (!theIObj->IsAutoHilight())
542   {
543     theIObj->ClearSelected();
544   }
545
546   EraseGlobal (theIObj, Standard_False);
547   if (theToUpdateViewer)
548   {
549     myMainVwr->Update();
550   }
551 }
552
553 //=======================================================================
554 //function : EraseAll
555 //purpose  :
556 //=======================================================================
557 void AIS_InteractiveContext::EraseAll (const Standard_Boolean theToUpdateViewer)
558 {
559   for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
560   {
561     if (anObjIter.Key()->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
562     {
563       Erase (anObjIter.Key(), Standard_False);
564     }
565   }
566
567   if (theToUpdateViewer)
568   {
569     myMainVwr->Update();
570   }
571 }
572
573 //=======================================================================
574 //function : DisplayAll
575 //purpose  :
576 //=======================================================================
577 void AIS_InteractiveContext::DisplayAll (const Standard_Boolean theToUpdateViewer)
578 {
579   for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
580   {
581     const PrsMgr_DisplayStatus aStatus = anObjIter.Key()->DisplayStatus();
582     if (aStatus == PrsMgr_DisplayStatus_Erased)
583     {
584       Display (anObjIter.Key(), Standard_False);
585     }
586   }
587
588   if (theToUpdateViewer)
589   {
590     myMainVwr->Update();
591   }
592 }
593
594 //=======================================================================
595 //function : DisplaySelected
596 //purpose  :
597 //=======================================================================
598 void AIS_InteractiveContext::DisplaySelected (const Standard_Boolean theToUpdateViewer)
599 {
600   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
601   {
602     Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (aSelIter.Value()->Selectable());
603     Display (anObj, Standard_False);
604   }
605
606   if (theToUpdateViewer && !mySelection->Objects().IsEmpty())
607   {
608     myMainVwr->Update();
609   }
610 }
611
612 //=======================================================================
613 //function : EraseSelected
614 //purpose  :
615 //=======================================================================
616 void AIS_InteractiveContext::EraseSelected (const Standard_Boolean theToUpdateViewer)
617 {
618   Standard_Boolean isFound = Standard_False;
619   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Init (mySelection->Objects()))
620   {
621     Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (aSelIter.Value()->Selectable());
622     Erase (anObj, Standard_False);
623     isFound = Standard_True;
624   }
625
626   if (isFound && theToUpdateViewer)
627   {
628     myMainVwr->Update();
629   }
630 }
631
632 //=======================================================================
633 //function : DisplayStatus
634 //purpose  :
635 //=======================================================================
636 PrsMgr_DisplayStatus AIS_InteractiveContext::DisplayStatus (const Handle(AIS_InteractiveObject)& theIObj) const
637 {
638   if (theIObj.IsNull())
639   {
640     return PrsMgr_DisplayStatus_None;
641   }
642   const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIObj);
643   return aStatus != NULL ? theIObj->DisplayStatus() : PrsMgr_DisplayStatus_None;
644 }
645
646 //=======================================================================
647 //function : Remove
648 //purpose  :
649 //=======================================================================
650 void AIS_InteractiveContext::Remove (const Handle(AIS_InteractiveObject)& theIObj,
651                                      const Standard_Boolean               theToUpdateViewer)
652 {
653   if (theIObj.IsNull())
654   {
655     return;
656   }
657
658   if (theIObj->HasInteractiveContext())
659   {
660     if (theIObj->myCTXPtr != this)
661     {
662       throw Standard_ProgramError("AIS_InteractiveContext - object has been displayed in another context!");
663     }
664     theIObj->SetContext (Handle(AIS_InteractiveContext)());
665   }
666   ClearGlobal (theIObj, theToUpdateViewer);
667 }
668
669 //=======================================================================
670 //function : RemoveAll
671 //purpose  :
672 //=======================================================================
673 void AIS_InteractiveContext::RemoveAll (const Standard_Boolean theToUpdateViewer)
674 {
675   ClearDetected();
676
677   AIS_ListOfInteractive aList;
678   ObjectsInside (aList);
679   for (AIS_ListOfInteractive::Iterator aListIterator (aList); aListIterator.More(); aListIterator.Next())
680   {
681     Remove (aListIterator.Value(), Standard_False);
682   }
683
684   if (theToUpdateViewer)
685   {
686     myMainVwr->Update();
687   }
688 }
689
690 //=======================================================================
691 //function : HilightWithColor
692 //purpose  : 
693 //=======================================================================
694 void AIS_InteractiveContext::HilightWithColor(const Handle(AIS_InteractiveObject)& theObj,
695                                               const Handle(Prs3d_Drawer)& theStyle,
696                                               const Standard_Boolean theIsToUpdate)
697 {
698   if (theObj.IsNull())
699   {
700     return;
701   }
702
703   setContextToObject (theObj);
704   if (!myObjects.IsBound (theObj))
705   {
706     return;
707   }
708
709   const Handle(AIS_GlobalStatus)& aStatus = myObjects (theObj);
710   aStatus->SetHilightStatus (Standard_True);
711
712   if (theObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
713   {
714     highlightGlobal (theObj, theStyle, aStatus->DisplayMode());
715     aStatus->SetHilightStyle (theStyle);
716   }
717
718   if (theIsToUpdate)
719   {
720     myMainVwr->Update();
721   }
722 }
723
724 //=======================================================================
725 //function : Unhilight
726 //purpose  : 
727 //=======================================================================
728 void AIS_InteractiveContext::Unhilight (const Handle(AIS_InteractiveObject)& theObj,
729                                         const Standard_Boolean theToUpdateViewer)
730 {
731   Handle(AIS_GlobalStatus)* aStatus = !theObj.IsNull() ? myObjects.ChangeSeek (theObj) : NULL;
732   if (aStatus == NULL)
733   {
734     return;
735   }
736
737   (*aStatus)->SetHilightStatus (Standard_False);
738   (*aStatus)->SetHilightStyle (Handle(Prs3d_Drawer)());
739   if (theObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
740   {
741     unhighlightGlobal (theObj);
742   }
743
744   if (theToUpdateViewer)
745   {
746     myMainVwr->Update();
747   }
748 }
749
750 //=======================================================================
751 //function : IsHilighted
752 //purpose  : Returns true if the objects global status is set to highlighted.
753 //=======================================================================
754 Standard_Boolean AIS_InteractiveContext::IsHilighted (const Handle(AIS_InteractiveObject)& theObj) const
755 {
756   const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theObj);
757   return aStatus != NULL
758       && (*aStatus)->IsHilighted();
759 }
760
761 //=======================================================================
762 //function : IsHilighted
763 //purpose  : Returns true if the owner is highlighted with selection style.
764 //=======================================================================
765 Standard_Boolean AIS_InteractiveContext::IsHilighted (const Handle(SelectMgr_EntityOwner)& theOwner) const
766 {
767   if (theOwner.IsNull() || !theOwner->HasSelectable())
768     return Standard_False;
769
770   const Handle(AIS_InteractiveObject) anObj =
771     Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
772
773   if (anObj->GlobalSelOwner() == theOwner)
774   {
775     if (!myObjects.IsBound (anObj))
776       return Standard_False;
777
778     return myObjects (anObj)->IsHilighted();
779   }
780
781   const Handle(Prs3d_Drawer)& aStyle = getSelStyle (anObj, theOwner);
782   const Standard_Integer aHiMode = getHilightMode (anObj, aStyle, -1);
783   return theOwner->IsHilighted (myMainPM, aHiMode);
784 }
785
786 //=======================================================================
787 //function : HighlightStyle
788 //purpose  :
789 //=======================================================================
790 Standard_Boolean AIS_InteractiveContext::HighlightStyle (const Handle(AIS_InteractiveObject)& theObj,
791                                                          Handle(Prs3d_Drawer)& theStyle) const
792 {
793   const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theObj);
794   if (aStatus != NULL
795    && (*aStatus)->IsHilighted())
796   {
797     theStyle = (*aStatus)->HilightStyle();
798     return Standard_True;
799   }
800
801   theStyle.Nullify();
802   return Standard_False;
803 }
804
805 //=======================================================================
806 //function : HighlightStyle
807 //purpose  :
808 //=======================================================================
809 Standard_Boolean AIS_InteractiveContext::HighlightStyle (const Handle(SelectMgr_EntityOwner)& theOwner,
810                                                          Handle(Prs3d_Drawer)& theStyle) const
811 {
812   if (theOwner.IsNull() || !theOwner->HasSelectable())
813     return Standard_False;
814
815   if (IsHilighted (theOwner))
816   {
817     const Handle(AIS_InteractiveObject) anObj =
818       Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
819     if (anObj->GlobalSelOwner() == theOwner)
820     {
821       theStyle = myObjects (anObj)->HilightStyle();
822     }
823     else
824     {
825       // since part selection style is not stored in global status,
826       // check if the object has own selection style. If not, it can
827       // only be highlighted with default selection style (because
828       // sub-intensity does not modify any selection states)
829       theStyle = getSelStyle (anObj, theOwner);
830     }
831     return Standard_True;
832   }
833   else
834   {
835     theStyle.Nullify();
836     return Standard_False;
837   }
838 }
839
840 //=======================================================================
841 //function : IsDisplayed
842 //purpose  : 
843 //=======================================================================
844
845 Standard_Boolean AIS_InteractiveContext::IsDisplayed(const Handle(AIS_InteractiveObject)& theObj) const 
846 {
847   if(theObj.IsNull()) return Standard_False;
848
849   const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theObj);
850   return aStatus != NULL
851       && theObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed;
852 }
853
854 //=======================================================================
855 //function : IsDisplayed
856 //purpose  :
857 //=======================================================================
858 Standard_Boolean AIS_InteractiveContext::IsDisplayed (const Handle(AIS_InteractiveObject)& theIObj,
859                                                       const Standard_Integer               theMode) const
860 {
861   if (theIObj.IsNull())
862   {
863     return Standard_False;
864   }
865
866   const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIObj);
867   return aStatus != NULL
868       && theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
869       && (*aStatus)->DisplayMode() == theMode;
870 }
871
872 //=======================================================================
873 //function : DisplayPriority
874 //purpose  :
875 //=======================================================================
876 Graphic3d_DisplayPriority AIS_InteractiveContext::DisplayPriority (const Handle(AIS_InteractiveObject)& theIObj) const
877 {
878   if (theIObj.IsNull())
879   {
880     return Graphic3d_DisplayPriority_INVALID;
881   }
882
883   const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIObj);
884   if (aStatus != NULL
885    && (theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
886     || theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Erased))
887   {
888     Standard_Integer aDispMode = theIObj->HasDisplayMode()
889                                ? theIObj->DisplayMode()
890                                : (theIObj->AcceptDisplayMode (myDefaultDrawer->DisplayMode())
891                                 ? myDefaultDrawer->DisplayMode()
892                                 : 0);
893     return myMainPM->DisplayPriority (theIObj, aDispMode);
894   }
895   return Graphic3d_DisplayPriority_INVALID;
896 }
897
898 //=======================================================================
899 //function : SetDisplayPriority
900 //purpose  :
901 //=======================================================================
902 void AIS_InteractiveContext::SetDisplayPriority (const Handle(AIS_InteractiveObject)& theIObj,
903                                                  const Graphic3d_DisplayPriority      thePriority)
904 {
905   if (theIObj.IsNull())
906   {
907     return;
908   }
909
910   setContextToObject (theIObj);
911   const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIObj);
912   if (aStatus != NULL
913    && (theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
914     || theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Erased))
915   {
916     Standard_Integer aDisplayMode = theIObj->HasDisplayMode()
917                                   ? theIObj->DisplayMode()
918                                   : (theIObj->AcceptDisplayMode (myDefaultDrawer->DisplayMode())
919                                     ? myDefaultDrawer->DisplayMode()
920                                     : 0);
921     myMainPM->SetDisplayPriority (theIObj, aDisplayMode, thePriority);
922   }
923 }
924
925 //=======================================================================
926 //function : Redisplay
927 //purpose  :
928 //=======================================================================
929 void AIS_InteractiveContext::Redisplay (const Handle(AIS_InteractiveObject)& theIObj,
930                                         const Standard_Boolean               theToUpdateViewer,
931                                         const Standard_Boolean               theAllModes)
932 {
933   RecomputePrsOnly (theIObj, theToUpdateViewer, theAllModes);
934   RecomputeSelectionOnly (theIObj);
935 }
936
937 //=======================================================================
938 //function : Redisplay
939 //purpose  :
940 //=======================================================================
941 void AIS_InteractiveContext::Redisplay (const AIS_KindOfInteractive theKOI,
942                                         const Standard_Integer    /*theSign*/,
943                                         const Standard_Boolean      theToUpdateViewer)
944 {
945   Standard_Boolean isRedisplayed = Standard_False;
946   for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
947   {
948     const Handle(AIS_InteractiveObject)& anObj = anObjIter.Key();
949     if (anObj->Type() != theKOI)
950     {
951       continue;
952     }
953
954     Redisplay (anObj, Standard_False);
955     isRedisplayed = anObjIter.Key()->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
956                  || isRedisplayed;
957   }
958
959   if (theToUpdateViewer
960    && isRedisplayed)
961   {
962     myMainVwr->Update();
963   }
964 }
965
966 //=======================================================================
967 //function : RecomputePrsOnly
968 //purpose  :
969 //=======================================================================
970 void AIS_InteractiveContext::RecomputePrsOnly (const Handle(AIS_InteractiveObject)& theIObj,
971                                                const Standard_Boolean               theToUpdateViewer,
972                                                const Standard_Boolean               theAllModes)
973 {
974   if (theIObj.IsNull())
975   {
976     return;
977   }
978
979   theIObj->SetToUpdate();
980   theIObj->UpdatePresentations (theAllModes);
981   if (!theToUpdateViewer)
982   {
983     return;
984   }
985
986   const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIObj);
987   if (aStatus != NULL
988    && theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
989   {
990     myMainVwr->Update();
991   }
992 }
993 //=======================================================================
994 //function : RecomputeSelectionOnly
995 //purpose  : 
996 //=======================================================================
997 void AIS_InteractiveContext::RecomputeSelectionOnly (const Handle(AIS_InteractiveObject)& theIO)
998 {
999   if (theIO.IsNull())
1000   {
1001     return;
1002   }
1003
1004   TColStd_ListOfInteger aModes;
1005   ActivatedModes (theIO, aModes);
1006
1007   for (TColStd_ListIteratorOfListOfInteger aModesIter (aModes); aModesIter.More(); aModesIter.Next())
1008   {
1009     mgrSelector->Deactivate (theIO, aModesIter.Value());
1010   }
1011
1012   mgrSelector->RecomputeSelection (theIO);
1013
1014   const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIO);
1015   if (aStatus == NULL
1016    || theIO->DisplayStatus() != PrsMgr_DisplayStatus_Displayed)
1017   {
1018     return;
1019   }
1020
1021   for (TColStd_ListIteratorOfListOfInteger aModesIter (aModes); aModesIter.More(); aModesIter.Next())
1022   {
1023     mgrSelector->Activate (theIO, aModesIter.Value());
1024   }
1025 }
1026
1027 //=======================================================================
1028 //function : Update
1029 //purpose  :
1030 //=======================================================================
1031 void AIS_InteractiveContext::Update (const Handle(AIS_InteractiveObject)& theIObj,
1032                                      const Standard_Boolean               theUpdateViewer)
1033 {
1034   if (theIObj.IsNull())
1035   {
1036     return;
1037   }
1038
1039   theIObj->UpdatePresentations();
1040   mgrSelector->Update(theIObj);
1041
1042   if (theUpdateViewer)
1043   {
1044     const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theIObj);
1045     if (aStatus != NULL
1046      && theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
1047     {
1048       myMainVwr->Update();
1049     }
1050   }
1051 }
1052
1053 //=======================================================================
1054 //function : SetLocation
1055 //purpose  :
1056 //=======================================================================
1057 void AIS_InteractiveContext::SetLocation (const Handle(AIS_InteractiveObject)& theIObj,
1058                                           const TopLoc_Location&               theLoc)
1059 {
1060   if (theIObj.IsNull())
1061   {
1062     return;
1063   }
1064
1065   if (theIObj->HasTransformation()
1066    && theLoc.IsIdentity())
1067   {
1068     theIObj->ResetTransformation();
1069     mgrSelector->Update (theIObj, Standard_False);
1070     return;
1071   }
1072   else if (theLoc.IsIdentity())
1073   {
1074     return;
1075   }
1076
1077   // first reset the previous location to properly clean everything...
1078   if (theIObj->HasTransformation())
1079   {
1080     theIObj->ResetTransformation();
1081   }
1082
1083   theIObj->SetLocalTransformation (theLoc.Transformation());
1084
1085   mgrSelector->Update (theIObj, Standard_False);
1086
1087   // if the object or its part is highlighted dynamically, it is necessary to apply location transformation
1088   // to its highlight structure immediately
1089   if (!myLastPicked.IsNull() && myLastPicked->IsSameSelectable (theIObj))
1090   {
1091     const Standard_Integer aHiMod = theIObj->HasHilightMode() ? theIObj->HilightMode() : 0;
1092     myLastPicked->UpdateHighlightTrsf (myMainVwr,
1093                                        myMainPM,
1094                                        aHiMod);
1095   }
1096 }
1097
1098 //=======================================================================
1099 //function : ResetLocation
1100 //purpose  :
1101 //=======================================================================
1102 void AIS_InteractiveContext::ResetLocation (const Handle(AIS_InteractiveObject)& theIObj)
1103 {
1104   if (theIObj.IsNull())
1105   {
1106     return;
1107   }
1108
1109   theIObj->ResetTransformation();
1110   mgrSelector->Update (theIObj, Standard_False);
1111 }
1112
1113 //=======================================================================
1114 //function : HasLocation
1115 //purpose  :
1116 //=======================================================================
1117 Standard_Boolean AIS_InteractiveContext::HasLocation (const Handle(AIS_InteractiveObject)& theIObj) const
1118 {
1119   return !theIObj.IsNull()
1120        && theIObj->HasTransformation();
1121 }
1122
1123 //=======================================================================
1124 //function : Location
1125 //purpose  :
1126 //=======================================================================
1127 TopLoc_Location AIS_InteractiveContext::Location (const Handle(AIS_InteractiveObject)& theIObj) const
1128 {
1129   return theIObj->Transformation();
1130 }
1131
1132 //=======================================================================
1133 //function : SetDisplayMode
1134 //purpose  :
1135 //=======================================================================
1136 void AIS_InteractiveContext::SetDisplayMode(const Standard_Integer theMode,
1137                                             const Standard_Boolean theToUpdateViewer)
1138 {
1139   if (theMode == myDefaultDrawer->DisplayMode())
1140   {
1141     return;
1142   }
1143
1144   for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjIter (myObjects); anObjIter.More(); anObjIter.Next())
1145   {
1146     Handle(AIS_InteractiveObject) anObj = anObjIter.Key();
1147     Standard_Boolean toProcess = anObj->IsKind (STANDARD_TYPE(AIS_Shape))
1148                               || anObj->IsKind (STANDARD_TYPE(AIS_ConnectedInteractive))
1149                               || anObj->IsKind (STANDARD_TYPE(AIS_MultipleConnectedInteractive));
1150     
1151     if (!toProcess
1152      ||  anObj->HasDisplayMode()
1153      || !anObj->AcceptDisplayMode (theMode))
1154     {
1155       continue;
1156     }
1157
1158     const Handle(AIS_GlobalStatus)& aStatus = anObjIter.Value();
1159     aStatus->SetDisplayMode (theMode);
1160
1161     if (anObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
1162     {
1163       myMainPM->Display (anObj, theMode);
1164       if (!myLastPicked.IsNull() && myLastPicked->IsSameSelectable (anObj))
1165       {
1166         myMainPM->BeginImmediateDraw();
1167         unhighlightGlobal (anObj);
1168         myMainPM->EndImmediateDraw (myMainVwr);
1169       }
1170       if (aStatus->IsSubIntensityOn())
1171       {
1172         highlightWithSubintensity (anObj, theMode);
1173       }
1174       myMainPM->SetVisibility (anObj, myDefaultDrawer->DisplayMode(), Standard_False);
1175     }
1176   }
1177
1178   myDefaultDrawer->SetDisplayMode (theMode);
1179   if (theToUpdateViewer)
1180   {
1181     myMainVwr->Update();
1182   }
1183 }
1184
1185 //=======================================================================
1186 //function : SetDisplayMode
1187 //purpose  :
1188 //=======================================================================
1189 void AIS_InteractiveContext::SetDisplayMode (const Handle(AIS_InteractiveObject)& theIObj,
1190                                              const Standard_Integer               theMode,
1191                                              const Standard_Boolean               theToUpdateViewer)
1192 {
1193   setContextToObject (theIObj);
1194   if (!myObjects.IsBound (theIObj))
1195   {
1196     theIObj->SetDisplayMode (theMode);
1197     return;
1198   }
1199   else if (!theIObj->AcceptDisplayMode (theMode))
1200   {
1201     return;
1202   }
1203
1204   Handle(AIS_GlobalStatus) aStatus = myObjects (theIObj);
1205   if (theIObj->DisplayStatus() != PrsMgr_DisplayStatus_Displayed)
1206   {
1207     aStatus->SetDisplayMode (theMode);
1208     theIObj->SetDisplayMode (theMode);
1209     return;
1210   }
1211
1212   // erase presentations for all display modes different from <aMode>
1213   const Standard_Integer anOldMode = aStatus->DisplayMode();
1214   if (anOldMode != theMode)
1215   {
1216     if (myMainPM->IsHighlighted (theIObj, anOldMode))
1217     {
1218       unhighlightGlobal (theIObj);
1219     }
1220     myMainPM->SetVisibility (theIObj, anOldMode, Standard_False);
1221   }
1222
1223   aStatus->SetDisplayMode (theMode);
1224
1225   myMainPM->Display (theIObj, theMode);
1226   if (aStatus->IsHilighted())
1227   {
1228     highlightGlobal (theIObj, getSelStyle (theIObj, theIObj->GlobalSelOwner()), theMode);
1229   }
1230   if (aStatus->IsSubIntensityOn())
1231   {
1232     highlightWithSubintensity (theIObj, theMode);
1233   }
1234
1235   if (theToUpdateViewer)
1236   {
1237     myMainVwr->Update();
1238   }
1239   theIObj->SetDisplayMode (theMode);
1240 }
1241
1242 //=======================================================================
1243 //function : UnsetDisplayMode
1244 //purpose  :
1245 //=======================================================================
1246 void AIS_InteractiveContext::UnsetDisplayMode (const Handle(AIS_InteractiveObject)& theIObj,
1247                                                const Standard_Boolean               theToUpdateViewer)
1248 {
1249   if (theIObj.IsNull()
1250   || !theIObj->HasDisplayMode())
1251   {
1252     return;
1253   }
1254
1255   if (!myObjects.IsBound (theIObj))
1256   {
1257     theIObj->UnsetDisplayMode();
1258     return;
1259   }
1260
1261   const Standard_Integer anOldMode = theIObj->DisplayMode();
1262   if (myDefaultDrawer->DisplayMode() == anOldMode)
1263   {
1264     return;
1265   }
1266
1267   const Handle(AIS_GlobalStatus)& aStatus = myObjects (theIObj);
1268   aStatus->SetDisplayMode (myDefaultDrawer->DisplayMode());
1269
1270   if (theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
1271   {
1272     if (myMainPM->IsHighlighted (theIObj, anOldMode))
1273     {
1274       unhighlightGlobal (theIObj);
1275     }
1276     myMainPM->SetVisibility (theIObj, anOldMode, Standard_False);
1277     myMainPM->Display (theIObj, myDefaultDrawer->DisplayMode());
1278     if (aStatus->IsHilighted())
1279     {
1280       highlightSelected (theIObj->GlobalSelOwner());
1281     }
1282     if (aStatus->IsSubIntensityOn())
1283     {
1284       highlightWithSubintensity (theIObj, myDefaultDrawer->DisplayMode());
1285     }
1286
1287     if (theToUpdateViewer)
1288     {
1289       myMainVwr->Update();
1290     }
1291   }
1292
1293   theIObj->UnsetDisplayMode();
1294 }
1295
1296 //=======================================================================
1297 //function : SetCurrentFacingModel
1298 //purpose  :
1299 //=======================================================================
1300 void AIS_InteractiveContext::SetCurrentFacingModel (const Handle(AIS_InteractiveObject)& theIObj,
1301                                                     const Aspect_TypeOfFacingModel       theModel)
1302 {
1303   if (!theIObj.IsNull())
1304   {
1305     theIObj->SetCurrentFacingModel (theModel);
1306   }
1307 }
1308
1309 //=======================================================================
1310 //function : SetColor
1311 //purpose  :
1312 //=======================================================================
1313 void AIS_InteractiveContext::SetColor (const Handle(AIS_InteractiveObject)& theIObj,
1314                                        const Quantity_Color&                theColor,
1315                                        const Standard_Boolean               theToUpdateViewer)
1316 {
1317   if (theIObj.IsNull())
1318   {
1319     return;
1320   }
1321
1322   setContextToObject (theIObj);
1323   theIObj->SetColor (theColor);
1324   theIObj->UpdatePresentations();
1325   if (theToUpdateViewer)
1326   {
1327     UpdateCurrentViewer();
1328   }
1329 }
1330
1331 //=======================================================================
1332 //function : SetIsoOnTriangulation
1333 //purpose  :
1334 //=======================================================================
1335 void AIS_InteractiveContext::IsoOnTriangulation (const Standard_Boolean theIsEnabled,
1336                                                  const Handle(AIS_InteractiveObject)& theObject)
1337 {
1338   if (theObject.IsNull())
1339   {
1340     return;
1341   }
1342
1343   theObject->SetIsoOnTriangulation (theIsEnabled);
1344 }
1345
1346 //=======================================================================
1347 //function : SetDeviationCoefficient
1348 //purpose  :
1349 //=======================================================================
1350 void AIS_InteractiveContext::SetDeviationCoefficient (const Handle(AIS_InteractiveObject)& theIObj,
1351                                                       const Standard_Real                  theCoefficient,
1352                                                       const Standard_Boolean               theToUpdateViewer)
1353 {
1354   if (theIObj.IsNull())
1355   {
1356     return;
1357   }
1358
1359   // to be modified after the related methods of AIS_Shape are passed to InteractiveObject
1360   setContextToObject (theIObj);
1361   if (theIObj->Type() != AIS_KindOfInteractive_Object
1362    && theIObj->Type() != AIS_KindOfInteractive_Shape)
1363   {
1364     return;
1365   }
1366   else if (theIObj->Signature() != 0)
1367   {
1368     return;
1369   }
1370
1371   Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (theIObj);
1372   aShape->SetOwnDeviationCoefficient (theCoefficient);
1373   aShape->UpdatePresentations();
1374   if (theToUpdateViewer)
1375   {
1376     UpdateCurrentViewer();
1377   }
1378 }
1379
1380 //=======================================================================
1381 //function : SetDeviationAngle
1382 //purpose  :
1383 //=======================================================================
1384 void AIS_InteractiveContext::SetDeviationAngle (const Handle(AIS_InteractiveObject)& theIObj,
1385                                                 const Standard_Real                  theAngle,
1386                                                 const Standard_Boolean               theToUpdateViewer)
1387 {
1388   if (theIObj.IsNull())
1389   {
1390     return;
1391   }
1392
1393   // To be modified after the related methods of AIS_Shape are passed to InteractiveObject
1394   setContextToObject (theIObj);
1395   if (theIObj->Type() != AIS_KindOfInteractive_Shape)
1396   {
1397     return;
1398   }
1399   else if (theIObj->Signature() != 0)
1400   {
1401     return;
1402   }
1403
1404   Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (theIObj);
1405   aShape->SetOwnDeviationAngle (theAngle);
1406   aShape->UpdatePresentations();
1407   if (theToUpdateViewer)
1408   {
1409     UpdateCurrentViewer();
1410   }
1411 }
1412
1413 //=======================================================================
1414 //function : SetAngleAndDeviation
1415 //purpose  :
1416 //=======================================================================
1417 void AIS_InteractiveContext::SetAngleAndDeviation (const Handle(AIS_InteractiveObject)& theIObj,
1418                                                    const Standard_Real                  theAngle,
1419                                                    const Standard_Boolean               theToUpdateViewer)
1420 {
1421   if (theIObj.IsNull())
1422   {
1423     return;
1424   }
1425
1426   // To be modified after the related methods of AIS_Shape are passed to InteractiveObject
1427   setContextToObject (theIObj);
1428   if (theIObj->Type() != AIS_KindOfInteractive_Shape)
1429   {
1430     return;
1431   }
1432   if (theIObj->Signature() != 0)
1433   {
1434     return;
1435   }
1436
1437   Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (theIObj);
1438   aShape->SetAngleAndDeviation (theAngle);
1439   aShape->UpdatePresentations();
1440   if (theToUpdateViewer)
1441   {
1442     UpdateCurrentViewer();
1443   }
1444 }
1445
1446 //=======================================================================
1447 //function : UnsetColor
1448 //purpose  :
1449 //=======================================================================
1450 void AIS_InteractiveContext::UnsetColor (const Handle(AIS_InteractiveObject)& theIObj,
1451                                          const Standard_Boolean               theToUpdateViewer)
1452 {
1453   if (theIObj.IsNull())
1454   {
1455     return;
1456   }
1457
1458   theIObj->UnsetColor();
1459   theIObj->UpdatePresentations();
1460   if (theToUpdateViewer)
1461   {
1462     UpdateCurrentViewer();
1463   }
1464 }
1465
1466 //=======================================================================
1467 //function : HasColor
1468 //purpose  :
1469 //=======================================================================
1470 Standard_Boolean AIS_InteractiveContext::HasColor (const Handle(AIS_InteractiveObject)& theIObj) const
1471 {
1472   return theIObj->HasColor();
1473 }
1474
1475 //=======================================================================
1476 //function : Color
1477 //purpose  :
1478 //=======================================================================
1479 void AIS_InteractiveContext::Color (const Handle(AIS_InteractiveObject)& theIObj,
1480                                     Quantity_Color&                      theColor) const
1481 {
1482   theIObj->Color (theColor);
1483 }
1484
1485 //=======================================================================
1486 //function : Width
1487 //purpose  :
1488 //=======================================================================
1489 Standard_Real AIS_InteractiveContext::Width (const Handle(AIS_InteractiveObject)& theIObj) const
1490 {
1491   return theIObj->Width();
1492 }
1493
1494 //=======================================================================
1495 //function : SetWidth
1496 //purpose  :
1497 //=======================================================================
1498 void AIS_InteractiveContext::SetWidth (const Handle(AIS_InteractiveObject)& theIObj,
1499                                        const Standard_Real                  theWidth,
1500                                        const Standard_Boolean               theToUpdateViewer)
1501 {
1502   if (theIObj.IsNull())
1503   {
1504     return;
1505   }
1506
1507   setContextToObject (theIObj);
1508   theIObj->SetWidth (theWidth);
1509   theIObj->UpdatePresentations();
1510   if (!myLastPicked.IsNull() && myLastPicked->IsSameSelectable (theIObj))
1511   {
1512     if (myLastPicked->IsAutoHilight())
1513     {
1514       const Standard_Integer aHiMode = theIObj->HasHilightMode() ? theIObj->HilightMode() : 0;
1515       myLastPicked->HilightWithColor (myMainPM,
1516                                       myLastPicked->IsSelected() ? getSelStyle (theIObj, myLastPicked) : getHiStyle (theIObj, myLastPicked),
1517                                       aHiMode);
1518     }
1519     else
1520     {
1521       theIObj->HilightOwnerWithColor (myMainPM,
1522                                       myLastPicked->IsSelected() ? getSelStyle (theIObj, myLastPicked) : getHiStyle (theIObj, myLastPicked),
1523                                       myLastPicked);
1524     }
1525   }
1526   if (theToUpdateViewer)
1527   {
1528     UpdateCurrentViewer();
1529   }
1530 }
1531
1532 //=======================================================================
1533 //function : UnsetWidth
1534 //purpose  :
1535 //=======================================================================
1536 void AIS_InteractiveContext::UnsetWidth (const Handle(AIS_InteractiveObject)& theIObj,
1537                                          const Standard_Boolean               theToUpdateViewer)
1538 {
1539   if (theIObj.IsNull())
1540   {
1541     return;
1542   }
1543
1544   theIObj->UnsetWidth();
1545   theIObj->UpdatePresentations();
1546   if (theToUpdateViewer)
1547   {
1548     UpdateCurrentViewer();
1549   }
1550 }
1551
1552 //=======================================================================
1553 //function : SetMaterial
1554 //purpose  :
1555 //=======================================================================
1556 void AIS_InteractiveContext::SetMaterial (const Handle(AIS_InteractiveObject)& theIObj,
1557                                           const Graphic3d_MaterialAspect&      theMaterial,
1558                                           const Standard_Boolean               theToUpdateViewer)
1559 {
1560   if (theIObj.IsNull())
1561   {
1562     return;
1563   }
1564
1565   setContextToObject (theIObj);
1566   theIObj->SetMaterial (theMaterial);
1567   theIObj->UpdatePresentations();
1568   if (theToUpdateViewer)
1569   {
1570     UpdateCurrentViewer();
1571   }
1572 }
1573
1574 //=======================================================================
1575 //function : UnsetMaterial
1576 //purpose  :
1577 //=======================================================================
1578 void AIS_InteractiveContext::UnsetMaterial (const Handle(AIS_InteractiveObject)& theIObj,
1579                                             const Standard_Boolean               theToUpdateViewer)
1580 {
1581   if (theIObj.IsNull())
1582   {
1583     return;
1584   }
1585   theIObj->UnsetMaterial();
1586   theIObj->UpdatePresentations();
1587   if (theToUpdateViewer)
1588   {
1589     UpdateCurrentViewer();
1590   }
1591 }
1592
1593 //=======================================================================
1594 //function : SetTransparency
1595 //purpose  :
1596 //=======================================================================
1597 void AIS_InteractiveContext::SetTransparency (const Handle(AIS_InteractiveObject)& theIObj,
1598                                               const Standard_Real                  theValue,
1599                                               const Standard_Boolean               theToUpdateViewer)
1600 {
1601   if (theIObj.IsNull())
1602   {
1603     return;
1604   }
1605
1606   setContextToObject (theIObj);
1607   if (!theIObj->IsTransparent()
1608     && theValue <= 0.005)
1609   {
1610     return;
1611   }
1612
1613   if (theValue <= 0.005)
1614   {
1615     UnsetTransparency (theIObj, theToUpdateViewer);
1616     return;
1617   }
1618
1619   theIObj->SetTransparency (theValue);
1620   theIObj->UpdatePresentations();
1621   if (theToUpdateViewer)
1622   {
1623     UpdateCurrentViewer();
1624   }
1625 }
1626
1627 //=======================================================================
1628 //function : UnsetTransparency
1629 //purpose  :
1630 //=======================================================================
1631 void AIS_InteractiveContext::UnsetTransparency (const Handle(AIS_InteractiveObject)& theIObj,
1632                                                 const Standard_Boolean               theToUpdateViewer)
1633 {
1634   if (theIObj.IsNull())
1635   {
1636     return;
1637   }
1638
1639   theIObj->UnsetTransparency();
1640   theIObj->UpdatePresentations();
1641   if (theToUpdateViewer)
1642   {
1643     UpdateCurrentViewer();
1644   }
1645 }
1646
1647 //=======================================================================
1648 //function : SetSelectedAspect
1649 //purpose  :
1650 //=======================================================================
1651 void AIS_InteractiveContext::SetSelectedAspect (const Handle(Prs3d_BasicAspect)& theAspect,
1652                                                 const Standard_Boolean           theToUpdateViewer)
1653 {
1654   Standard_DISABLE_DEPRECATION_WARNINGS
1655   Standard_Boolean isFound = Standard_False;
1656   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
1657   {
1658     isFound = Standard_True;
1659     Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (aSelIter.Value()->Selectable());
1660     anObj->SetAspect (theAspect);
1661   }
1662   Standard_ENABLE_DEPRECATION_WARNINGS
1663
1664   if (isFound && theToUpdateViewer)
1665   {
1666     myMainVwr->Update();
1667   }
1668 }
1669
1670 //=======================================================================
1671 //function : SetLocalAttributes
1672 //purpose  :
1673 //=======================================================================
1674 void AIS_InteractiveContext::SetLocalAttributes (const Handle(AIS_InteractiveObject)& theIObj,
1675                                                  const Handle(Prs3d_Drawer)&          theDrawer,
1676                                                  const Standard_Boolean               theToUpdateViewer)
1677 {
1678   if (theIObj.IsNull())
1679   {
1680     return;
1681   }
1682
1683   setContextToObject (theIObj);
1684   theIObj->SetAttributes (theDrawer);
1685   Update (theIObj, theToUpdateViewer);
1686 }
1687
1688 //=======================================================================
1689 //function : UnsetLocalAttributes
1690 //purpose  :
1691 //=======================================================================
1692 void AIS_InteractiveContext::UnsetLocalAttributes (const Handle(AIS_InteractiveObject)& theIObj,
1693                                                    const Standard_Boolean               theToUpdateViewer)
1694 {
1695   if (theIObj.IsNull())
1696   {
1697     return;
1698   }
1699
1700   setContextToObject (theIObj);
1701   theIObj->UnsetAttributes();
1702   Update (theIObj, theToUpdateViewer);
1703 }
1704
1705 //=======================================================================
1706 //function : Status
1707 //purpose  :
1708 //=======================================================================
1709 void AIS_InteractiveContext::Status (const Handle(AIS_InteractiveObject)& theIObj,
1710                                      TCollection_ExtendedString&          theStatus) const
1711 {
1712   theStatus = "";
1713   if (theIObj.IsNull()
1714   || !myObjects.IsBound (theIObj))
1715   {
1716     return;
1717   }
1718
1719   theStatus += "\t ____________________________________________";
1720   theStatus += "\t| Known at Neutral Point:\n\tDisplayStatus:";
1721   const Handle(AIS_GlobalStatus)& aStatus = myObjects (theIObj);
1722   switch (theIObj->DisplayStatus())
1723   {
1724     case PrsMgr_DisplayStatus_Displayed:
1725     {
1726       theStatus += "\t| -->Displayed\n";
1727       break;
1728     }
1729     case PrsMgr_DisplayStatus_Erased:
1730     {
1731       theStatus += "\t| -->Erased\n";
1732       break;
1733     }
1734     default:
1735       break;
1736   }
1737
1738   theStatus += "\t| Active Display Modes in the MainViewer :\n";
1739   theStatus += "\t|\t Mode ";
1740   theStatus += TCollection_AsciiString (aStatus->DisplayMode());
1741   theStatus += "\n";
1742
1743   if (IsSelected(theIObj)) theStatus +="\t| Selected\n";
1744
1745   theStatus += "\t| Active Selection Modes in the MainViewer :\n";
1746   for (TColStd_ListIteratorOfListOfInteger aSelModeIter (aStatus->SelectionModes()); aSelModeIter.More(); aSelModeIter.Next())
1747   {
1748     theStatus += "\t\t Mode ";
1749     theStatus += TCollection_AsciiString (aSelModeIter.Value());
1750     theStatus += "\n";
1751   }
1752   theStatus += "\t ____________________________________________";
1753 }
1754
1755 //=======================================================================
1756 //function : GetDefModes
1757 //purpose  :
1758 //=======================================================================
1759 void AIS_InteractiveContext::GetDefModes (const Handle(AIS_InteractiveObject)& theIObj,
1760                                           Standard_Integer&                    theDispMode,
1761                                           Standard_Integer&                    theHiMode,
1762                                           Standard_Integer&                    theSelMode) const
1763 {
1764   if (theIObj.IsNull())
1765   {
1766     return;
1767   }
1768
1769   theDispMode = theIObj->HasDisplayMode()
1770               ? theIObj->DisplayMode()
1771               : (theIObj->AcceptDisplayMode (myDefaultDrawer->DisplayMode())
1772                ? myDefaultDrawer->DisplayMode()
1773                : 0);
1774   theHiMode  = theIObj->HasHilightMode()   ? theIObj->HilightMode()   : theDispMode;
1775   theSelMode = theIObj->GlobalSelectionMode();
1776 }
1777
1778 //=======================================================================
1779 //function : EraseGlobal
1780 //purpose  :
1781 //=======================================================================
1782 void AIS_InteractiveContext::EraseGlobal (const Handle(AIS_InteractiveObject)& theIObj,
1783                                           const Standard_Boolean               theToUpdateviewer)
1784 {
1785   Handle(AIS_GlobalStatus) aStatus;
1786   if (theIObj.IsNull()
1787   || !myObjects.Find (theIObj, aStatus)
1788   ||  theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Erased)
1789   {
1790     return;
1791   }
1792
1793   const Standard_Integer aDispMode = theIObj->HasHilightMode() ? theIObj->HilightMode() : 0;
1794   unselectOwners (theIObj);
1795   myMainPM->SetVisibility (theIObj, aStatus->DisplayMode(), Standard_False);
1796
1797   if (!myLastPicked.IsNull()
1798     && myLastPicked->IsSameSelectable (theIObj))
1799   {
1800     clearDynamicHighlight();
1801   }
1802
1803   // make sure highlighting presentations are properly erased
1804   theIObj->ErasePresentations (false);
1805
1806   if (IsSelected (theIObj)
1807    && aStatus->DisplayMode() != aDispMode)
1808   {
1809     myMainPM->SetVisibility (theIObj, aDispMode, Standard_False);
1810   }
1811
1812   for (TColStd_ListIteratorOfListOfInteger aSelModeIter (aStatus->SelectionModes()); aSelModeIter.More(); aSelModeIter.Next())
1813   {
1814     mgrSelector->Deactivate (theIObj, aSelModeIter.Value());
1815   }
1816   aStatus->ClearSelectionModes();
1817   theIObj->SetDisplayStatus (PrsMgr_DisplayStatus_Erased);
1818
1819   if (theToUpdateviewer)
1820   {
1821     myMainVwr->Update();
1822   }
1823 }
1824
1825 //=======================================================================
1826 //function : unselectOwners
1827 //purpose  :
1828 //=======================================================================
1829 void AIS_InteractiveContext::unselectOwners (const Handle(AIS_InteractiveObject)& theObject)
1830 {
1831   SelectMgr_SequenceOfOwner aSeq;
1832   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
1833   {
1834     if (aSelIter.Value()->IsSameSelectable (theObject))
1835     {
1836       aSeq.Append (aSelIter.Value());
1837     }
1838   }
1839   for (SelectMgr_SequenceOfOwner::Iterator aDelIter (aSeq); aDelIter.More(); aDelIter.Next())
1840   {
1841     AddOrRemoveSelected (aDelIter.Value(), Standard_False);
1842   }
1843 }
1844
1845 //=======================================================================
1846 //function : ClearGlobal
1847 //purpose  :
1848 //=======================================================================
1849 void AIS_InteractiveContext::ClearGlobal (const Handle(AIS_InteractiveObject)& theIObj,
1850                                           const Standard_Boolean               theToUpdateviewer)
1851 {
1852   Handle(AIS_GlobalStatus) aStatus;
1853   if (theIObj.IsNull()
1854   || !myObjects.Find (theIObj, aStatus))
1855   {
1856     // for cases when reference shape of connected interactives was not displayed
1857     // but its selection primitives were calculated
1858     const Handle(SelectMgr_SelectableObject)& anObj = theIObj; // to avoid ambiguity
1859     mgrSelector->Remove (anObj);
1860     return;
1861   }
1862
1863   unselectOwners (theIObj);
1864
1865   myMainPM->Erase (theIObj, -1);
1866   theIObj->ErasePresentations (true); // make sure highlighting presentations are properly erased
1867
1868   // Object removes from Detected sequence
1869   for (Standard_Integer aDetIter = myDetectedSeq.Lower(); aDetIter <= myDetectedSeq.Upper();)
1870   {
1871     Handle(SelectMgr_EntityOwner) aPicked = MainSelector()->Picked (myDetectedSeq (aDetIter));
1872     Handle(AIS_InteractiveObject) anObj;
1873     if (!aPicked.IsNull())
1874     {
1875       anObj = Handle(AIS_InteractiveObject)::DownCast (aPicked->Selectable());
1876     }
1877
1878     if (!anObj.IsNull()
1879       && anObj == theIObj)
1880     {
1881       myDetectedSeq.Remove (aDetIter);
1882       if (myCurDetected == aDetIter)
1883       {
1884         myCurDetected = Min (myDetectedSeq.Upper(), aDetIter);
1885       }
1886       if (myCurHighlighted == aDetIter)
1887       {
1888         myCurHighlighted = 0;
1889       }
1890     }
1891     else
1892     {
1893       aDetIter++;
1894     }
1895   }
1896
1897   // remove IO from the selection manager to avoid memory leaks
1898   const Handle(SelectMgr_SelectableObject)& anObj = theIObj; // to avoid ambiguity
1899   mgrSelector->Remove (anObj);
1900
1901   setObjectStatus (theIObj, PrsMgr_DisplayStatus_None, -1, -1);
1902   theIObj->ViewAffinity()->SetVisible (true); // reset view affinity mask
1903   myMainVwr->StructureManager()->UnregisterObject (theIObj);
1904
1905   if (!myLastPicked.IsNull())
1906   {
1907     if (myLastPicked->IsSameSelectable (theIObj))
1908     {
1909       clearDynamicHighlight();
1910       myLastPicked.Nullify();
1911     }
1912   }
1913
1914   if (theToUpdateviewer
1915    && theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
1916   {
1917     myMainVwr->Update();
1918   }
1919 }
1920
1921 //=======================================================================
1922 //function : ClearGlobalPrs
1923 //purpose  :
1924 //=======================================================================
1925 void AIS_InteractiveContext::ClearGlobalPrs (const Handle(AIS_InteractiveObject)& theIObj,
1926                                              const Standard_Integer               theMode,
1927                                              const Standard_Boolean               theToUpdateViewer)
1928 {
1929   const Handle(AIS_GlobalStatus)* aStatus = !theIObj.IsNull() ? myObjects.Seek (theIObj) : NULL;
1930   if (aStatus == NULL)
1931   {
1932     return;
1933   }
1934
1935   if ((*aStatus)->DisplayMode() == theMode)
1936   {
1937     const Standard_Integer aDispMode = theIObj->HasHilightMode() ? theIObj->HilightMode() : 0;
1938     if (aDispMode == theMode
1939      && myMainPM->IsHighlighted (theIObj, theMode))
1940     {
1941       unhighlightGlobal (theIObj);
1942     }
1943
1944     myMainPM->Erase (theIObj, theMode);
1945   }
1946
1947   if (theIObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
1948    && theToUpdateViewer)
1949   {
1950     myMainVwr->Update();
1951   }
1952 }
1953
1954 //=======================================================================
1955 //function : ClearDetected
1956 //purpose  :
1957 //=======================================================================
1958 Standard_Boolean AIS_InteractiveContext::ClearDetected (Standard_Boolean theToRedrawImmediate)
1959 {
1960   myCurDetected = 0;
1961   myCurHighlighted = 0;
1962   myDetectedSeq.Clear();
1963   Standard_Boolean toUpdate = Standard_False;
1964   if (!myLastPicked.IsNull() && myLastPicked->HasSelectable())
1965   {
1966     toUpdate = Standard_True;
1967     clearDynamicHighlight();
1968   }
1969   myLastPicked.Nullify();
1970   MainSelector()->ClearPicked();
1971   if (toUpdate && theToRedrawImmediate)
1972   {
1973     myMainVwr->RedrawImmediate();
1974   }
1975   return toUpdate;
1976 }
1977
1978 //=======================================================================
1979 //function : SetIsoNumber
1980 //purpose  :
1981 //=======================================================================
1982 void AIS_InteractiveContext::SetIsoNumber (const Standard_Integer theNb,
1983                                            const AIS_TypeOfIso    theType)
1984 {
1985   switch (theType)
1986   {
1987     case AIS_TOI_IsoU:
1988       myDefaultDrawer->UIsoAspect()->SetNumber (theNb);
1989       break;
1990     case AIS_TOI_IsoV:
1991       myDefaultDrawer->VIsoAspect()->SetNumber (theNb);
1992       break;
1993     case AIS_TOI_Both:
1994       myDefaultDrawer->UIsoAspect()->SetNumber (theNb);
1995       myDefaultDrawer->VIsoAspect()->SetNumber (theNb);
1996       break;
1997   }
1998 }
1999
2000 //=======================================================================
2001 //function : IsoNumber
2002 //purpose  :
2003 //=======================================================================
2004 Standard_Integer AIS_InteractiveContext::IsoNumber (const AIS_TypeOfIso theType)
2005 {
2006   switch (theType)
2007   {
2008     case AIS_TOI_IsoU: return myDefaultDrawer->UIsoAspect()->Number();
2009     case AIS_TOI_IsoV: return myDefaultDrawer->VIsoAspect()->Number();
2010     case AIS_TOI_Both: return myDefaultDrawer->UIsoAspect()->Number() == myDefaultDrawer->VIsoAspect()->Number()
2011                             ? myDefaultDrawer->UIsoAspect()->Number()
2012                             : -1;
2013   }
2014   return 0;
2015 }
2016
2017 //=======================================================================
2018 //function : SetPixelTolerance
2019 //purpose  :
2020 //=======================================================================
2021 void AIS_InteractiveContext::SetPixelTolerance (const Standard_Integer thePrecision)
2022 {
2023   MainSelector()->SetPixelTolerance (thePrecision);
2024 }
2025
2026 //=======================================================================
2027 //function : PixelTolerance
2028 //purpose  :
2029 //=======================================================================
2030 Standard_Integer AIS_InteractiveContext::PixelTolerance() const
2031 {
2032   return MainSelector()->PixelTolerance();
2033 }
2034
2035 //=======================================================================
2036 //function : SetSelectionSensitivity
2037 //purpose  : Allows to manage sensitivity of a particular selection of interactive object theObject
2038 //=======================================================================
2039 void AIS_InteractiveContext::SetSelectionSensitivity (const Handle(AIS_InteractiveObject)& theObject,
2040                                                       const Standard_Integer theMode,
2041                                                       const Standard_Integer theNewSensitivity)
2042 {
2043   mgrSelector->SetSelectionSensitivity (theObject, theMode, theNewSensitivity);
2044 }
2045
2046 //=======================================================================
2047 //function : InitAttributes
2048 //purpose  :
2049 //=======================================================================
2050 void AIS_InteractiveContext::InitAttributes()
2051 {
2052   Graphic3d_MaterialAspect aMat (Graphic3d_NameOfMaterial_Brass);
2053   myDefaultDrawer->ShadingAspect()->SetMaterial (aMat);
2054
2055 //  myDefaultDrawer->ShadingAspect()->SetColor(Quantity_NOC_GRAY70);
2056   Handle(Prs3d_LineAspect) aLineAspect = myDefaultDrawer->HiddenLineAspect();
2057   aLineAspect->SetColor      (Quantity_NOC_GRAY20);
2058   aLineAspect->SetWidth      (1.0);
2059   aLineAspect->SetTypeOfLine (Aspect_TOL_DASH);
2060
2061   // tolerance to 2 pixels...
2062   SetPixelTolerance (2);
2063
2064   // Customizing the drawer for trihedrons and planes...
2065   Handle(Prs3d_DatumAspect) aTrihAspect = myDefaultDrawer->DatumAspect();
2066   const Standard_Real aLength = 100.0;
2067   aTrihAspect->SetAxisLength (aLength, aLength, aLength);
2068   const Quantity_Color aColor = Quantity_NOC_LIGHTSTEELBLUE4;
2069   aTrihAspect->LineAspect(Prs3d_DatumParts_XAxis)->SetColor (aColor);
2070   aTrihAspect->LineAspect(Prs3d_DatumParts_YAxis)->SetColor (aColor);
2071   aTrihAspect->LineAspect(Prs3d_DatumParts_ZAxis)->SetColor (aColor);
2072
2073   Handle(Prs3d_PlaneAspect) aPlaneAspect = myDefaultDrawer->PlaneAspect();
2074   const Standard_Real aPlaneLength = 200.0;
2075   aPlaneAspect->SetPlaneLength (aPlaneLength, aPlaneLength);
2076   aPlaneAspect->EdgesAspect()->SetColor (Quantity_NOC_SKYBLUE);
2077 }
2078
2079 //=======================================================================
2080 //function : TrihedronSize
2081 //purpose  :
2082 //=======================================================================
2083 Standard_Real AIS_InteractiveContext::TrihedronSize() const
2084 {
2085   return myDefaultDrawer->DatumAspect()->AxisLength(Prs3d_DatumParts_XAxis);
2086 }
2087
2088 //=======================================================================
2089 //function : SetTrihedronSize
2090 //purpose  :
2091 //=======================================================================
2092 void AIS_InteractiveContext::SetTrihedronSize (const Standard_Real    theVal,
2093                                                const Standard_Boolean /*updateviewer*/)
2094 {
2095   myDefaultDrawer->DatumAspect()->SetAxisLength (theVal, theVal, theVal);
2096   Redisplay (AIS_KindOfInteractive_Datum, 3, Standard_False);
2097   Redisplay (AIS_KindOfInteractive_Datum, 4, Standard_True);
2098 }
2099
2100 //=======================================================================
2101 //function : SetPlaneSize
2102 //purpose  :
2103 //=======================================================================
2104 void AIS_InteractiveContext::SetPlaneSize(const Standard_Real    theValX,
2105                                           const Standard_Real    theValY,
2106                                           const Standard_Boolean theToUpdateViewer)
2107 {
2108   myDefaultDrawer->PlaneAspect()->SetPlaneLength (theValX, theValY);
2109   Redisplay (AIS_KindOfInteractive_Datum, 7, theToUpdateViewer);
2110 }
2111
2112 //=======================================================================
2113 //function : SetPlaneSize
2114 //purpose  :
2115 //=======================================================================
2116 void AIS_InteractiveContext::SetPlaneSize (const Standard_Real    theVal,
2117                                            const Standard_Boolean theToUpdateViewer)
2118 {
2119   SetPlaneSize (theVal, theVal, theToUpdateViewer);
2120 }
2121
2122 //=======================================================================
2123 //function : PlaneSize
2124 //purpose  :
2125 //=======================================================================
2126 Standard_Boolean AIS_InteractiveContext::PlaneSize (Standard_Real& theX,
2127                                                     Standard_Real& theY) const
2128 {
2129   theX = myDefaultDrawer->PlaneAspect()->PlaneXLength();
2130   theY = myDefaultDrawer->PlaneAspect()->PlaneYLength();
2131   return (Abs (theX - theY) <= Precision::Confusion());
2132 }
2133
2134 //=======================================================================
2135 //function : SetZLayer
2136 //purpose  :
2137 //=======================================================================
2138 void AIS_InteractiveContext::SetZLayer (const Handle(AIS_InteractiveObject)& theIObj,
2139                                         const Graphic3d_ZLayerId theLayerId)
2140 {
2141   if (theIObj.IsNull())
2142     return;
2143
2144   theIObj->SetZLayer (theLayerId);
2145 }
2146
2147 //=======================================================================
2148 //function : GetZLayer
2149 //purpose  :
2150 //=======================================================================
2151 Graphic3d_ZLayerId AIS_InteractiveContext::GetZLayer (const Handle(AIS_InteractiveObject)& theIObj) const
2152 {
2153   return !theIObj.IsNull()
2154        ?  theIObj->ZLayer()
2155        :  Graphic3d_ZLayerId_UNKNOWN;
2156 }
2157
2158 //=======================================================================
2159 //function : RebuildSelectionStructs
2160 //purpose  : Rebuilds 1st level of BVH selection forcibly
2161 //=======================================================================
2162 void AIS_InteractiveContext::RebuildSelectionStructs()
2163 {
2164   MainSelector()->RebuildObjectsTree (Standard_True);
2165 }
2166
2167 //=======================================================================
2168 //function : Disconnect
2169 //purpose  : Disconnects selectable object from an assembly and updates selection structures
2170 //=======================================================================
2171 void AIS_InteractiveContext::Disconnect (const Handle(AIS_InteractiveObject)& theAssembly,
2172                                          const Handle(AIS_InteractiveObject)& theObjToDisconnect)
2173 {
2174   if (theAssembly->IsInstance ("AIS_MultipleConnectedInteractive"))
2175   {
2176     Handle(AIS_MultipleConnectedInteractive) theObj (Handle(AIS_MultipleConnectedInteractive)::DownCast (theAssembly));
2177     theObj->Disconnect (theObjToDisconnect);
2178     if (!myObjects.IsBound (theObjToDisconnect))
2179     {
2180       // connected presentation might contain displayed presentations
2181       myMainPM->Erase (theObjToDisconnect, -1);
2182       theObjToDisconnect->ErasePresentations (true);
2183     }
2184
2185     const Handle(SelectMgr_SelectableObject)& anObj = theObjToDisconnect; // to avoid ambiguity
2186     mgrSelector->Remove (anObj);
2187   }
2188   else if (theAssembly->IsInstance ("AIS_ConnectedInteractive") && theObjToDisconnect.IsNull())
2189   {
2190     Handle(AIS_ConnectedInteractive) theObj (Handle(AIS_ConnectedInteractive)::DownCast (theAssembly));
2191     theObj->Disconnect();
2192     const Handle(SelectMgr_SelectableObject)& anObj = theObj; // to avoid ambiguity
2193     mgrSelector->Remove (anObj);
2194   }
2195   else
2196     return;
2197 }
2198
2199 //=======================================================================
2200 //function : FitSelected
2201 //purpose  : Fits the view corresponding to the bounds of selected objects
2202 //=======================================================================
2203 void AIS_InteractiveContext::FitSelected (const Handle(V3d_View)& theView)
2204 {
2205   FitSelected (theView, 0.01, Standard_True);
2206 }
2207
2208 //=======================================================================
2209 //function : BoundingBoxOfSelection
2210 //purpose  :
2211 //=======================================================================
2212 Bnd_Box AIS_InteractiveContext::BoundingBoxOfSelection (const Handle(V3d_View)& theView) const
2213 {
2214   Bnd_Box aBndSelected;
2215   AIS_MapOfObjectOwners anObjectOwnerMap;
2216   const Standard_Integer aViewId = !theView.IsNull() ? theView->View()->Identification() : -1;
2217   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
2218   {
2219     const Handle(SelectMgr_EntityOwner)& anOwner = aSelIter.Value();
2220     Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast(anOwner->Selectable());
2221     if (anObj->IsInfinite())
2222     {
2223       continue;
2224     }
2225
2226     Handle(Graphic3d_ViewAffinity) anAffinity = anObj->ViewAffinity();
2227     const Standard_Boolean isVisible = aViewId == -1 || anAffinity->IsVisible (aViewId);
2228     if (!isVisible)
2229     {
2230       continue;
2231     }
2232
2233     if (anOwner == anObj->GlobalSelOwner())
2234     {
2235       Bnd_Box aTmpBnd;
2236       anObj->BoundingBox (aTmpBnd);
2237       aBndSelected.Add (aTmpBnd);
2238     }
2239     else
2240     {
2241       Handle(SelectMgr_IndexedMapOfOwner) anOwnerMap;
2242       if (!anObjectOwnerMap.Find (anOwner->Selectable(), anOwnerMap))
2243       {
2244         anOwnerMap = new SelectMgr_IndexedMapOfOwner();
2245         anObjectOwnerMap.Bind (anOwner->Selectable(), anOwnerMap);
2246       }
2247
2248       anOwnerMap->Add (anOwner);
2249     }
2250   }
2251
2252   for (AIS_MapIteratorOfMapOfObjectOwners anIter (anObjectOwnerMap); anIter.More(); anIter.Next())
2253   {
2254     const Handle(SelectMgr_SelectableObject)& anObject = anIter.Key();
2255     Bnd_Box aTmpBox = anObject->BndBoxOfSelected (anIter.ChangeValue());
2256     aBndSelected.Add (aTmpBox);
2257   }
2258
2259   return aBndSelected;
2260 }
2261
2262 //=======================================================================
2263 //function : FitSelected
2264 //purpose  : Fits the view corresponding to the bounds of selected objects
2265 //=======================================================================
2266 void AIS_InteractiveContext::FitSelected (const Handle(V3d_View)& theView,
2267                                           const Standard_Real theMargin,
2268                                           const Standard_Boolean theToUpdate)
2269 {
2270   Bnd_Box aBndSelected = BoundingBoxOfSelection (theView);
2271   if (!aBndSelected.IsVoid())
2272   {
2273     theView->FitAll (aBndSelected, theMargin, theToUpdate);
2274   }
2275 }
2276
2277 //=======================================================================
2278 //function : SetTransformPersistence
2279 //purpose  :
2280 //=======================================================================
2281 void AIS_InteractiveContext::SetTransformPersistence (const Handle(AIS_InteractiveObject)& theObject,
2282                                                       const Handle(Graphic3d_TransformPers)& theTrsfPers)
2283 {
2284   theObject->SetTransformPersistence (theTrsfPers);
2285   if (!myObjects.IsBound (theObject))
2286   {
2287     return;
2288   }
2289
2290   mgrSelector->UpdateSelection (theObject);
2291
2292   const Graphic3d_ZLayerId  aLayerId   = theObject->ZLayer();
2293   const Handle(V3d_Viewer)& aCurViewer = CurrentViewer();
2294   for (V3d_ListOfViewIterator anActiveViewIter (aCurViewer->ActiveViewIterator()); anActiveViewIter.More(); anActiveViewIter.Next())
2295   {
2296     anActiveViewIter.Value()->View()->InvalidateBVHData (aLayerId);
2297     anActiveViewIter.Value()->View()->InvalidateZLayerBoundingBox (aLayerId);
2298   }
2299 }
2300
2301 //=======================================================================
2302 //function : GravityPoint
2303 //purpose  :
2304 //=======================================================================
2305 gp_Pnt AIS_InteractiveContext::GravityPoint (const Handle(V3d_View)& theView) const
2306 {
2307   return theView->GravityPoint();
2308 }
2309
2310 //=======================================================================
2311 //function : setContextToObject
2312 //purpose  :
2313 //=======================================================================
2314 void AIS_InteractiveContext::setContextToObject (const Handle(AIS_InteractiveObject)& theObj)
2315 {
2316   if (theObj->HasInteractiveContext())
2317   {
2318     if (theObj->myCTXPtr != this)
2319     {
2320       throw Standard_ProgramError("AIS_InteractiveContext - object has been already displayed in another context!");
2321     }
2322   }
2323   else
2324   {
2325     theObj->SetContext (this);
2326   }
2327
2328   for (PrsMgr_ListOfPresentableObjectsIter aPrsIter (theObj->Children()); aPrsIter.More(); aPrsIter.Next())
2329   {
2330     if (Handle(AIS_InteractiveObject) aChild = Handle(AIS_InteractiveObject)::DownCast (aPrsIter.Value()))
2331     {
2332       setContextToObject (aChild);
2333     }
2334   }
2335 }
2336
2337 //=======================================================================
2338 //function : setObjectStatus
2339 //purpose  :
2340 //=======================================================================
2341 void AIS_InteractiveContext::setObjectStatus (const Handle(AIS_InteractiveObject)& theIObj,
2342                                               const PrsMgr_DisplayStatus theStatus,
2343                                               const Standard_Integer theDispMode,
2344                                               const Standard_Integer theSelectionMode)
2345 {
2346   theIObj->SetDisplayStatus (theStatus);
2347   if (theStatus != PrsMgr_DisplayStatus_None)
2348   {
2349     Handle(AIS_GlobalStatus) aStatus = new AIS_GlobalStatus();
2350     aStatus->SetDisplayMode (theDispMode);
2351     if (theSelectionMode != -1)
2352     {
2353       aStatus->AddSelectionMode (theSelectionMode);
2354     }
2355     myObjects.Bind (theIObj, aStatus);
2356   }
2357   else
2358   {
2359     myObjects.UnBind (theIObj);
2360   }
2361
2362   for (PrsMgr_ListOfPresentableObjectsIter aPrsIter (theIObj->Children()); aPrsIter.More(); aPrsIter.Next())
2363   {
2364     Handle(AIS_InteractiveObject) aChild (Handle(AIS_InteractiveObject)::DownCast (aPrsIter.Value()));
2365     if (aChild.IsNull())
2366     {
2367       continue;
2368     }
2369
2370     setObjectStatus (aChild, theStatus, theDispMode, theSelectionMode);
2371   }
2372 }
2373
2374 //=======================================================================
2375 //function : highlightWithColor
2376 //purpose  :
2377 //=======================================================================
2378 void AIS_InteractiveContext::highlightWithColor (const Handle(SelectMgr_EntityOwner)& theOwner,
2379                                                  const Handle(V3d_Viewer)& theViewer)
2380 {
2381   const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
2382   if (anObj.IsNull())
2383   {
2384     return;
2385   }
2386
2387   const Handle(Prs3d_Drawer)& aStyle = getHiStyle (anObj, theOwner);
2388   const Standard_Integer aHiMode = getHilightMode (anObj, aStyle, -1);
2389
2390   myMainPM->BeginImmediateDraw();
2391   theOwner->HilightWithColor (myMainPM, aStyle, aHiMode);
2392   myMainPM->EndImmediateDraw (theViewer.IsNull() ? myMainVwr : theViewer);
2393 }
2394
2395 //=======================================================================
2396 //function : highlightSelected
2397 //purpose  :
2398 //=======================================================================
2399 void AIS_InteractiveContext::highlightSelected (const Handle(SelectMgr_EntityOwner)& theOwner)
2400 {
2401   AIS_NListOfEntityOwner anOwners;
2402   const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
2403   if (anObj.IsNull())
2404   {
2405     return;
2406   }
2407
2408   if (!theOwner->IsAutoHilight())
2409   {
2410     SelectMgr_SequenceOfOwner aSeq;
2411     for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
2412     {
2413       if (aSelIter.Value()->IsSameSelectable (anObj))
2414       {
2415         anOwners.Append (aSelIter.Value());
2416       }
2417     }
2418   }
2419   else
2420   {
2421     anOwners.Append (theOwner);
2422   }
2423   highlightOwners (anOwners, Handle(Prs3d_Drawer)());
2424 }
2425
2426 //=======================================================================
2427 //function : highlightGlobal
2428 //purpose  :
2429 //=======================================================================
2430 void AIS_InteractiveContext::highlightGlobal (const Handle(AIS_InteractiveObject)& theObj,
2431                                               const Handle(Prs3d_Drawer)& theStyle,
2432                                               const Standard_Integer theDispMode)
2433 {
2434   if (theObj.IsNull())
2435   {
2436     return;
2437   }
2438
2439   const Standard_Integer aHiMode = getHilightMode (theObj, theStyle, theDispMode);
2440   const Handle(SelectMgr_EntityOwner)& aGlobOwner = theObj->GlobalSelOwner();
2441
2442   if (aGlobOwner.IsNull())
2443   {
2444     myMainPM->Color (theObj, theStyle, aHiMode);
2445     return;
2446   }
2447
2448   AIS_NListOfEntityOwner anOwners;
2449   if (!aGlobOwner->IsAutoHilight())
2450   {
2451     SelectMgr_SequenceOfOwner aSeq;
2452     for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
2453     {
2454       if (aSelIter.Value()->IsSameSelectable (theObj))
2455       {
2456         anOwners.Append (aSelIter.Value());
2457       }
2458     }
2459   }
2460   else
2461   {
2462     anOwners.Append (aGlobOwner);
2463   }
2464   highlightOwners (anOwners, theStyle);
2465 }
2466
2467 //=======================================================================
2468 //function : unhighlightSelected
2469 //purpose  :
2470 //=======================================================================
2471 void AIS_InteractiveContext::unhighlightSelected (const Standard_Boolean theIsToHilightSubIntensity)
2472 {
2473   unhighlightOwners (mySelection->Objects(), theIsToHilightSubIntensity);
2474 }
2475
2476 //=======================================================================
2477 //function : unhighlightOwners
2478 //purpose  :
2479 //=======================================================================
2480 void AIS_InteractiveContext::unhighlightOwners (const AIS_NListOfEntityOwner& theOwners,
2481                                                 const Standard_Boolean theIsToHilightSubIntensity)
2482 {
2483   NCollection_IndexedMap<Handle(AIS_InteractiveObject)> anObjToClear;
2484   for (AIS_NListOfEntityOwner::Iterator aSelIter (theOwners); aSelIter.More(); aSelIter.Next())
2485   {
2486     const Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
2487     const Handle(AIS_InteractiveObject) anInteractive = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
2488     Handle(AIS_GlobalStatus)* aStatusPtr = myObjects.ChangeSeek (anInteractive);
2489     if (!aStatusPtr)
2490     {
2491       continue;
2492     }
2493
2494     if (anOwner->IsAutoHilight())
2495     {
2496       anOwner->Unhilight (myMainPM);
2497       if (theIsToHilightSubIntensity)
2498       {
2499         if ((*aStatusPtr)->IsSubIntensityOn())
2500         {
2501           const Standard_Integer aHiMode = getHilightMode (anInteractive, (*aStatusPtr)->HilightStyle(), (*aStatusPtr)->DisplayMode());
2502           highlightWithSubintensity (anOwner, aHiMode);
2503         }
2504       }
2505     }
2506     else
2507     {
2508       anObjToClear.Add (anInteractive);
2509     }
2510     if (anOwner == anInteractive->GlobalSelOwner())
2511     {
2512       (*aStatusPtr)->SetHilightStatus (Standard_False);
2513     }
2514     (*aStatusPtr)->SetHilightStyle (Handle(Prs3d_Drawer)());
2515   }
2516   for (NCollection_IndexedMap<Handle(AIS_InteractiveObject)>::Iterator anIter (anObjToClear); anIter.More(); anIter.Next())
2517   {
2518     const Handle(AIS_InteractiveObject)& anObj = anIter.Value();
2519     myMainPM->Unhighlight (anObj);
2520     anObj->ClearSelected();
2521   }
2522 }
2523
2524 //=======================================================================
2525 //function : unhighlightGlobal
2526 //purpose  :
2527 //=======================================================================
2528 void AIS_InteractiveContext::unhighlightGlobal (const Handle(AIS_InteractiveObject)& theObj)
2529 {
2530   if (theObj.IsNull())
2531   {
2532     return;
2533   }
2534
2535   const Handle(SelectMgr_EntityOwner)& aGlobOwner = theObj->GlobalSelOwner();
2536   if (aGlobOwner.IsNull())
2537   {
2538     myMainPM->Unhighlight (theObj);
2539     return;
2540   }
2541
2542   AIS_NListOfEntityOwner anOwners;
2543   anOwners.Append (aGlobOwner);
2544   unhighlightOwners (anOwners);
2545 }
2546
2547 //=======================================================================
2548 //function : turnOnSubintensity
2549 //purpose  :
2550 //=======================================================================
2551 void AIS_InteractiveContext::turnOnSubintensity (const Handle(AIS_InteractiveObject)& theObject,
2552                                                  const Standard_Integer theDispMode,
2553                                                  const Standard_Boolean theIsDisplayedOnly) const
2554 {
2555   // the only differ with selection highlight is color, so sync transparency values
2556   const Handle(Prs3d_Drawer)& aSubStyle = myStyles[Prs3d_TypeOfHighlight_SubIntensity];
2557   aSubStyle->SetTransparency (myStyles[Prs3d_TypeOfHighlight_Selected]->Transparency());
2558
2559   if (theObject.IsNull())
2560   {
2561     for (AIS_DataMapIteratorOfDataMapOfIOStatus anObjsIter (myObjects); anObjsIter.More(); anObjsIter.Next())
2562     {
2563       const Handle(AIS_GlobalStatus)& aStatus = anObjsIter.Value();
2564       if (theObject->DisplayStatus() != PrsMgr_DisplayStatus_Displayed && theIsDisplayedOnly)
2565       {
2566         continue;
2567       }
2568
2569       aStatus->SetSubIntensity (true);
2570       myMainPM->Color (anObjsIter.Key(), aSubStyle, theDispMode != -1 ? theDispMode : aStatus->DisplayMode());
2571     }
2572   }
2573   else
2574   {
2575     Handle(AIS_GlobalStatus) aStatus;
2576     if (!myObjects.Find (theObject, aStatus))
2577     {
2578       return;
2579     }
2580
2581     if (theObject->DisplayStatus() != PrsMgr_DisplayStatus_Displayed && theIsDisplayedOnly)
2582     {
2583       return;
2584     }
2585
2586     aStatus->SetSubIntensity (true);
2587     myMainPM->Color (theObject, aSubStyle, theDispMode != -1 ? theDispMode : aStatus->DisplayMode());
2588   }
2589 }
2590
2591 //=======================================================================
2592 //function : highlightWithSubintensity
2593 //purpose  :
2594 //=======================================================================
2595 void AIS_InteractiveContext::highlightWithSubintensity (const Handle(AIS_InteractiveObject)& theObject,
2596                                                         const Standard_Integer theMode) const
2597 {
2598   // the only differ with selection highlight is color, so
2599   // sync transparency values
2600   myStyles[Prs3d_TypeOfHighlight_SubIntensity]->SetTransparency (myStyles[Prs3d_TypeOfHighlight_Selected]->Transparency());
2601
2602   myMainPM->Color (theObject, myStyles[Prs3d_TypeOfHighlight_SubIntensity], theMode);
2603 }
2604
2605 //=======================================================================
2606 //function : highlightWithSubintensity
2607 //purpose  :
2608 //=======================================================================
2609 void AIS_InteractiveContext::highlightWithSubintensity (const Handle(SelectMgr_EntityOwner)& theOwner,
2610                                                         const Standard_Integer theMode) const
2611 {
2612   // the only differ with selection highlight is color, so
2613   // sync transparency values
2614   myStyles[Prs3d_TypeOfHighlight_SubIntensity]->SetTransparency (myStyles[Prs3d_TypeOfHighlight_Selected]->Transparency());
2615
2616   theOwner->HilightWithColor (myMainPM, myStyles[Prs3d_TypeOfHighlight_SubIntensity], theMode);
2617 }
2618
2619 //=======================================================================
2620 //function : isSlowHiStyle
2621 //purpose  :
2622 //=======================================================================
2623 Standard_Boolean AIS_InteractiveContext::isSlowHiStyle (const Handle(SelectMgr_EntityOwner)& theOwner,
2624                                                         const Handle(V3d_Viewer)& theViewer) const
2625 {
2626   if (const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable()))
2627   {
2628     const Handle(Prs3d_Drawer)& aHiStyle = getHiStyle (anObj, myLastPicked);
2629     return aHiStyle->ZLayer() == Graphic3d_ZLayerId_UNKNOWN
2630        || !theViewer->ZLayerSettings (aHiStyle->ZLayer()).IsImmediate();
2631   }
2632   return Standard_False;
2633 }
2634
2635 //=======================================================================
2636 //function : MoveTo
2637 //purpose  :
2638 //=======================================================================
2639 AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const Standard_Integer  theXPix,
2640                                                       const Standard_Integer  theYPix,
2641                                                       const Handle(V3d_View)& theView,
2642                                                       const Standard_Boolean  theToRedrawOnUpdate)
2643 {
2644   if (theView->Viewer() != myMainVwr)
2645   {
2646     throw Standard_ProgramError ("AIS_InteractiveContext::MoveTo() - invalid argument");
2647   }
2648   MainSelector()->Pick (theXPix, theYPix, theView);
2649   return moveTo (theView, theToRedrawOnUpdate);
2650 }
2651
2652 //=======================================================================
2653 //function : MoveTo
2654 //purpose  :
2655 //=======================================================================
2656 AIS_StatusOfDetection AIS_InteractiveContext::MoveTo (const gp_Ax1& theAxis,
2657                                                       const Handle(V3d_View)& theView,
2658                                                       const Standard_Boolean  theToRedrawOnUpdate)
2659 {
2660   if (theView->Viewer() != myMainVwr)
2661   {
2662     throw Standard_ProgramError ("AIS_InteractiveContext::MoveTo() - invalid argument");
2663   }
2664   MainSelector()->Pick (theAxis, theView);
2665   return moveTo (theView, theToRedrawOnUpdate);
2666 }
2667
2668 //=======================================================================
2669 //function : moveTo
2670 //purpose  :
2671 //=======================================================================
2672 AIS_StatusOfDetection AIS_InteractiveContext::moveTo (const Handle(V3d_View)& theView,
2673                                                       const Standard_Boolean  theToRedrawOnUpdate)
2674 {
2675   myCurDetected = 0;
2676   myCurHighlighted = 0;
2677   myDetectedSeq.Clear();
2678   myLastActiveView = theView.get();
2679
2680   // preliminaries
2681   AIS_StatusOfDetection aStatus        = AIS_SOD_Nothing;
2682   Standard_Boolean      toUpdateViewer = Standard_False;
2683
2684   // filling of myAISDetectedSeq sequence storing information about detected AIS objects
2685   // (the objects must be AIS_Shapes)
2686   const Standard_Integer aDetectedNb = MainSelector()->NbPicked();
2687   Standard_Integer aNewDetected = 0;
2688   Standard_Boolean toIgnoreDetTop = Standard_False;
2689   for (Standard_Integer aDetIter = 1; aDetIter <= aDetectedNb; ++aDetIter)
2690   {
2691     Handle(SelectMgr_EntityOwner) anOwner = MainSelector()->Picked (aDetIter);
2692     if (anOwner.IsNull()
2693      || !myFilters->IsOk (anOwner))
2694     {
2695       if (myPickingStrategy == SelectMgr_PickingStrategy_OnlyTopmost)
2696       {
2697         toIgnoreDetTop = Standard_True;
2698       }
2699       continue;
2700     }
2701
2702     if (aNewDetected < 1
2703     && !toIgnoreDetTop)
2704     {
2705       aNewDetected = aDetIter;
2706     }
2707
2708     myDetectedSeq.Append (aDetIter);
2709   }
2710
2711   if (aNewDetected >= 1)
2712   {
2713     myCurHighlighted = myDetectedSeq.Lower();
2714
2715     // Does nothing if previously detected object is equal to the current one.
2716     // However in advanced selection modes the owners comparison
2717     // is not effective because in that case only one owner manage the
2718     // selection in current selection mode. It is necessary to check the current detected
2719     // entity and hilight it only if the detected entity is not the same as
2720     // previous detected (IsForcedHilight call)
2721     Handle(SelectMgr_EntityOwner) aNewPickedOwner = MainSelector()->Picked (aNewDetected);
2722     if (aNewPickedOwner == myLastPicked && !aNewPickedOwner->IsForcedHilight())
2723     {
2724       return myLastPicked->IsSelected()
2725            ? AIS_SOD_Selected
2726            : AIS_SOD_OnlyOneDetected;
2727     }
2728
2729     // Previously detected object is unhilighted if it is not selected or hilighted
2730     // with selection color if it is selected. Such highlighting with selection color
2731     // is needed only if myToHilightSelected flag is true. In this case previously detected
2732     // object has been already highlighted with myHilightColor during previous MoveTo()
2733     // method call. As result it is necessary to rehighligt it with mySelectionColor.
2734     if (!myLastPicked.IsNull() && myLastPicked->HasSelectable())
2735     {
2736       if (isSlowHiStyle (myLastPicked, theView->Viewer()))
2737       {
2738         theView->Viewer()->Invalidate();
2739       }
2740
2741       clearDynamicHighlight();
2742       toUpdateViewer = Standard_True;
2743     }
2744
2745     // initialize myLastPicked field with currently detected object
2746     myLastPicked = aNewPickedOwner;
2747
2748     // highlight detected object if it is not selected or myToHilightSelected flag is true
2749     if (myLastPicked->HasSelectable())
2750     {
2751       if (myAutoHilight
2752        && (!myLastPicked->IsSelected()
2753          || myToHilightSelected))
2754       {
2755         if (isSlowHiStyle (myLastPicked, theView->Viewer()))
2756         {
2757           theView->Viewer()->Invalidate();
2758         }
2759
2760         highlightWithColor (myLastPicked, theView->Viewer());
2761         toUpdateViewer = Standard_True;
2762       }
2763
2764       aStatus = myLastPicked->IsSelected()
2765               ? AIS_SOD_Selected
2766               : AIS_SOD_OnlyOneDetected;
2767     }
2768   }
2769   else
2770   {
2771     // previously detected object is unhilighted if it is not selected or hilighted
2772     // with selection color if it is selected
2773     aStatus = AIS_SOD_Nothing;
2774     if (myAutoHilight
2775     && !myLastPicked.IsNull()
2776      && myLastPicked->HasSelectable())
2777     {
2778       if (isSlowHiStyle (myLastPicked, theView->Viewer()))
2779       {
2780         theView->Viewer()->Invalidate();
2781       }
2782
2783       clearDynamicHighlight();
2784       toUpdateViewer = Standard_True;
2785     }
2786
2787     myLastPicked.Nullify();
2788   }
2789
2790   if (toUpdateViewer
2791    && theToRedrawOnUpdate)
2792   {
2793     if (theView->ComputedMode())
2794     {
2795       theView->Viewer()->Update();
2796     }
2797     else
2798     {
2799       if (theView->IsInvalidated())
2800       {
2801         theView->Viewer()->Redraw();
2802       }
2803       else
2804       {
2805         theView->Viewer()->RedrawImmediate();
2806       }
2807     }
2808   }
2809
2810   return aStatus;
2811 }
2812
2813 //=======================================================================
2814 //function : AddSelect
2815 //purpose  :
2816 //=======================================================================
2817 AIS_StatusOfPick AIS_InteractiveContext::AddSelect (const Handle(SelectMgr_EntityOwner)& theObject)
2818 {
2819   mySelection->AddSelect (theObject);
2820
2821   Standard_Integer aSelNum = NbSelected();
2822   return (aSelNum == 0) ? AIS_SOP_NothingSelected
2823                         : (aSelNum == 1) ? AIS_SOP_OneSelected
2824                                          : AIS_SOP_SeveralSelected;
2825 }
2826
2827 //=======================================================================
2828 //function : SelectRectangle
2829 //purpose  :
2830 //=======================================================================
2831 AIS_StatusOfPick AIS_InteractiveContext::SelectRectangle (const Graphic3d_Vec2i&    thePntMin,
2832                                                           const Graphic3d_Vec2i&    thePntMax,
2833                                                           const Handle(V3d_View)&   theView,
2834                                                           const AIS_SelectionScheme theSelScheme)
2835 {
2836   if (theView->Viewer() != myMainVwr)
2837   {
2838     throw Standard_ProgramError ("AIS_InteractiveContext::SelectRectangle() - invalid argument");
2839   }
2840
2841   myLastActiveView = theView.get();
2842   MainSelector()->Pick (thePntMin.x(), thePntMin.y(), thePntMax.x(), thePntMax.y(), theView);
2843
2844   AIS_NArray1OfEntityOwner aPickedOwners;
2845   if (MainSelector()->NbPicked() > 0)
2846   {
2847     aPickedOwners.Resize (1, MainSelector()->NbPicked(), false);
2848     for (Standard_Integer aPickIter = 1; aPickIter <= MainSelector()->NbPicked(); ++aPickIter)
2849     {
2850       aPickedOwners.SetValue (aPickIter, MainSelector()->Picked (aPickIter));
2851     }
2852   }
2853
2854   return Select (aPickedOwners, theSelScheme);
2855 }
2856
2857 //=======================================================================
2858 //function : SelectPolygon
2859 //purpose  :
2860 //=======================================================================
2861 AIS_StatusOfPick AIS_InteractiveContext::SelectPolygon (const TColgp_Array1OfPnt2d& thePolyline,
2862                                                         const Handle(V3d_View)&     theView,
2863                                                         const AIS_SelectionScheme   theSelScheme)
2864 {
2865   if (theView->Viewer() != myMainVwr)
2866   {
2867     throw Standard_ProgramError ("AIS_InteractiveContext::SelectPolygon() - invalid argument");
2868   }
2869
2870   myLastActiveView = theView.get();
2871   MainSelector()->Pick (thePolyline, theView);
2872
2873   AIS_NArray1OfEntityOwner aPickedOwners;
2874   if (MainSelector()->NbPicked() > 0)
2875   {
2876     aPickedOwners.Resize (1, MainSelector()->NbPicked(), false);
2877     for (Standard_Integer aPickIter = 1; aPickIter <= MainSelector()->NbPicked(); ++aPickIter)
2878     {
2879       aPickedOwners.SetValue (aPickIter, MainSelector()->Picked (aPickIter));
2880     }
2881   }
2882
2883   return Select (aPickedOwners, theSelScheme);
2884 }
2885
2886 //=======================================================================
2887 //function : SelectPoint
2888 //purpose  :
2889 //=======================================================================
2890 AIS_StatusOfPick AIS_InteractiveContext::SelectPoint (const Graphic3d_Vec2i&    thePnt,
2891                                                       const Handle(V3d_View)&   theView,
2892                                                       const AIS_SelectionScheme theSelScheme)
2893 {
2894   if (theView->Viewer() != myMainVwr)
2895   {
2896     throw Standard_ProgramError ("AIS_InteractiveContext::SelectPoint() - invalid argument");
2897   }
2898
2899   myLastActiveView = theView.get();
2900   MainSelector()->Pick (thePnt.x(), thePnt.y(), theView);
2901
2902   AIS_NArray1OfEntityOwner aPickedOwners;
2903   if (MainSelector()->NbPicked() > 0)
2904   {
2905     aPickedOwners.Resize (1, MainSelector()->NbPicked(), false);
2906     for (Standard_Integer aPickIter = 1; aPickIter <= MainSelector()->NbPicked(); ++aPickIter)
2907     {
2908       aPickedOwners.SetValue (aPickIter, MainSelector()->Picked (aPickIter));
2909     }
2910   }
2911
2912   return Select (aPickedOwners, theSelScheme);
2913 }
2914
2915 //=======================================================================
2916 //function : SelectDetected
2917 //purpose  :
2918 //=======================================================================
2919 AIS_StatusOfPick AIS_InteractiveContext::SelectDetected (const AIS_SelectionScheme theSelScheme)
2920 {
2921   if (theSelScheme == AIS_SelectionScheme_Replace && !myLastPicked.IsNull())
2922   {
2923     Graphic3d_Vec2i aMousePos (-1, -1);
2924     gp_Pnt2d aMouseRealPos = MainSelector()->GetManager().GetMousePosition();
2925     if (!Precision::IsInfinite (aMouseRealPos.X()) &&
2926         !Precision::IsInfinite (aMouseRealPos.Y()))
2927     {
2928       aMousePos.SetValues ((Standard_Integer )aMouseRealPos.X(), (Standard_Integer )aMouseRealPos.Y());
2929     }
2930     if (myLastPicked->HandleMouseClick (aMousePos, Aspect_VKeyMouse_LeftButton, Aspect_VKeyFlags_NONE, false))
2931     {
2932       return AIS_SOP_NothingSelected;
2933     }
2934   }
2935
2936   AIS_NArray1OfEntityOwner aPickedOwners (1, 1);
2937   aPickedOwners.SetValue (1, myLastPicked);
2938   return Select (aPickedOwners, theSelScheme);
2939 }
2940
2941 //=======================================================================
2942 //function : Select
2943 //purpose  :
2944 //=======================================================================
2945 AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Integer  theXPMin,
2946                                                  const Standard_Integer  theYPMin,
2947                                                  const Standard_Integer  theXPMax,
2948                                                  const Standard_Integer  theYPMax,
2949                                                  const Handle(V3d_View)& theView,
2950                                                  const Standard_Boolean  theToUpdateViewer)
2951 {
2952   AIS_StatusOfPick aStatus = SelectRectangle (Graphic3d_Vec2i (theXPMin, theYPMin),
2953                                               Graphic3d_Vec2i (theXPMax, theYPMax),
2954                                               theView);
2955   if (theToUpdateViewer)
2956   {
2957     UpdateCurrentViewer();
2958   }
2959   return aStatus;
2960 }
2961
2962 //=======================================================================
2963 //function : Select
2964 //purpose  : Selection by polyline
2965 //=======================================================================
2966 AIS_StatusOfPick AIS_InteractiveContext::Select (const TColgp_Array1OfPnt2d& thePolyline,
2967                                                  const Handle(V3d_View)&     theView,
2968                                                  const Standard_Boolean      theToUpdateViewer)
2969 {
2970   AIS_StatusOfPick aStatus = SelectPolygon (thePolyline, theView);
2971   if (theToUpdateViewer)
2972   {
2973     UpdateCurrentViewer();
2974   }
2975   return aStatus;
2976 }
2977
2978 //=======================================================================
2979 //function : Select
2980 //purpose  :
2981 //=======================================================================
2982 AIS_StatusOfPick AIS_InteractiveContext::Select (const Standard_Boolean theToUpdateViewer)
2983 {
2984   AIS_StatusOfPick aStatus = SelectDetected();
2985   if (theToUpdateViewer)
2986   {
2987     UpdateCurrentViewer();
2988   }
2989   return aStatus;
2990 }
2991
2992 //=======================================================================
2993 //function : ShiftSelect
2994 //purpose  :
2995 //=======================================================================
2996 AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Boolean theToUpdateViewer)
2997 {
2998   AIS_StatusOfPick aStatus = SelectDetected (AIS_SelectionScheme_XOR);
2999   if (theToUpdateViewer)
3000   {
3001     UpdateCurrentViewer();
3002   }
3003   return aStatus;
3004 }
3005
3006 //=======================================================================
3007 //function : ShiftSelect
3008 //purpose  :
3009 //=======================================================================
3010 AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const Standard_Integer theXPMin,
3011                                                       const Standard_Integer theYPMin,
3012                                                       const Standard_Integer theXPMax,
3013                                                       const Standard_Integer theYPMax,
3014                                                       const Handle(V3d_View)& theView,
3015                                                       const Standard_Boolean theToUpdateViewer)
3016 {
3017   AIS_StatusOfPick aStatus = SelectRectangle (Graphic3d_Vec2i (theXPMin, theYPMin),
3018                                               Graphic3d_Vec2i (theXPMax, theYPMax),
3019                                               theView,
3020                                               AIS_SelectionScheme_XOR);
3021   if (theToUpdateViewer)
3022   {
3023     UpdateCurrentViewer();
3024   }
3025   return aStatus;
3026 }
3027
3028 //=======================================================================
3029 //function : ShiftSelect
3030 //purpose  :
3031 //=======================================================================
3032 AIS_StatusOfPick AIS_InteractiveContext::ShiftSelect (const TColgp_Array1OfPnt2d& thePolyline,
3033                                                       const Handle(V3d_View)& theView,
3034                                                       const Standard_Boolean theToUpdateViewer)
3035 {
3036   AIS_StatusOfPick aStatus = SelectPolygon (thePolyline, theView, AIS_SelectionScheme_XOR);
3037   if (theToUpdateViewer)
3038   {
3039     UpdateCurrentViewer();
3040   }
3041   return aStatus;
3042 }
3043
3044 //=======================================================================
3045 //function : Select
3046 //purpose  :
3047 //=======================================================================
3048 AIS_StatusOfPick AIS_InteractiveContext::Select (const AIS_NArray1OfEntityOwner& theOwners,
3049                                                  const AIS_SelectionScheme theSelScheme)
3050 {
3051   NCollection_IndexedMap<Handle(SelectMgr_EntityOwner)> aSelOwnerMap (myAutoHilight ? mySelection->Objects().Size() : 0);
3052   if (myAutoHilight)
3053   {
3054     clearDynamicHighlight();
3055
3056     // collect currently selected owners
3057     for (AIS_NListOfEntityOwner::Iterator anOwnerIter (mySelection->Objects()); anOwnerIter.More(); anOwnerIter.Next())
3058     {
3059       aSelOwnerMap.Add (anOwnerIter.Value());
3060     }
3061   }
3062
3063   mySelection->SelectOwners (theOwners, theSelScheme, MainSelector()->GetManager().IsOverlapAllowed(), myFilters);
3064
3065   if (myAutoHilight)
3066   {
3067     // collect lists of owners to unhighlight (unselected) and to highlight (selected)
3068     AIS_NListOfEntityOwner anOwnersToUnhighlight, anOwnersToHighlight;
3069     for (AIS_NListOfEntityOwner::Iterator anOwnerIter (mySelection->Objects()); anOwnerIter.More(); anOwnerIter.Next())
3070     {
3071       // add newly selected owners
3072       const Handle(SelectMgr_EntityOwner)& anOwner = anOwnerIter.Value();
3073       if (!aSelOwnerMap.RemoveKey (anOwner))
3074       {
3075         // newly selected owner
3076         anOwnersToHighlight.Append (anOwner);
3077       }
3078       else
3079       {
3080         // already selected owner
3081         if (!anOwner->IsAutoHilight()
3082           && theSelScheme != AIS_SelectionScheme_XOR
3083           && theSelScheme != AIS_SelectionScheme_Add)
3084         {
3085           // hack to perform AIS_InteractiveObject::ClearSelected() before highlighting
3086           anOwnersToUnhighlight.Append (anOwner);
3087           anOwnersToHighlight.Append (anOwner);
3088         }
3089         else if (anOwner->IsForcedHilight()
3090              || !anOwner->IsAutoHilight())
3091         {
3092           anOwnersToHighlight.Append (anOwner);
3093         }
3094       }
3095     }
3096
3097     for (NCollection_IndexedMap<Handle(SelectMgr_EntityOwner)>::Iterator anOwnerIter (aSelOwnerMap); anOwnerIter.More(); anOwnerIter.Next())
3098     {
3099       // owners removed from selection
3100       const Handle(SelectMgr_EntityOwner)& anOwner = anOwnerIter.Value();
3101       anOwnersToUnhighlight.Append (anOwner);
3102     }
3103
3104     unhighlightOwners (anOwnersToUnhighlight);
3105     highlightOwners (anOwnersToHighlight, Handle(Prs3d_Drawer)());
3106   }
3107
3108   Standard_Integer aSelNum = NbSelected();
3109   return (aSelNum == 0) ? AIS_SOP_NothingSelected
3110                         : (aSelNum == 1) ? AIS_SOP_OneSelected
3111                                          : AIS_SOP_SeveralSelected;
3112 }
3113
3114 //=======================================================================
3115 //function : HilightSelected
3116 //purpose  :
3117 //=======================================================================
3118 void AIS_InteractiveContext::HilightSelected (const Standard_Boolean theToUpdateViewer)
3119 {
3120   // In case of selection without using local context
3121   clearDynamicHighlight();
3122
3123   highlightOwners (mySelection->Objects(), Handle(Prs3d_Drawer)());
3124
3125   if (theToUpdateViewer)
3126   {
3127     UpdateCurrentViewer();
3128   }
3129 }
3130
3131 //=======================================================================
3132 //function : highlightOwners
3133 //purpose  :
3134 //=======================================================================
3135 void AIS_InteractiveContext::highlightOwners (const AIS_NListOfEntityOwner& theOwners,
3136                                               const Handle(Prs3d_Drawer)& theStyle)
3137 {
3138   NCollection_DataMap<Handle(AIS_InteractiveObject), NCollection_Handle<SelectMgr_SequenceOfOwner> > anObjOwnerMap;
3139   for (AIS_NListOfEntityOwner::Iterator aSelIter (theOwners); aSelIter.More(); aSelIter.Next())
3140   {
3141     const Handle(SelectMgr_EntityOwner) anOwner = aSelIter.Value();
3142     const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
3143     if (anObj.IsNull())
3144       continue;
3145
3146     const Handle(Prs3d_Drawer)& anObjSelStyle = !theStyle.IsNull() ? theStyle : getSelStyle (anObj, anOwner);
3147     Handle(AIS_GlobalStatus)* aStatusPtr = myObjects.ChangeSeek (anObj);
3148     if (!aStatusPtr)
3149     {
3150       continue;
3151     }
3152     if (anOwner == anObj->GlobalSelOwner())
3153     {
3154       (*aStatusPtr)->SetHilightStatus (Standard_True);
3155       (*aStatusPtr)->SetHilightStyle (anObjSelStyle);
3156     }
3157     if (!anOwner->IsAutoHilight())
3158     {
3159       NCollection_Handle<SelectMgr_SequenceOfOwner> aSeq;
3160       if (anObjOwnerMap.Find (anObj, aSeq))
3161       {
3162         aSeq->Append (anOwner);
3163       }
3164       else
3165       {
3166         aSeq = new SelectMgr_SequenceOfOwner();
3167         aSeq->Append (anOwner);
3168         anObjOwnerMap.Bind (anObj, aSeq);
3169       }
3170     }
3171     else
3172     {
3173       const Standard_Integer aHiMode = getHilightMode (anObj, anObjSelStyle, (*aStatusPtr)->DisplayMode());
3174       anOwner->HilightWithColor (myMainPM, anObjSelStyle, aHiMode);
3175     }
3176   }
3177
3178   if (!anObjOwnerMap.IsEmpty())
3179   {
3180     for (NCollection_DataMap<Handle(AIS_InteractiveObject), NCollection_Handle<SelectMgr_SequenceOfOwner> >::Iterator anIter (anObjOwnerMap);
3181          anIter.More(); anIter.Next())
3182     {
3183       anIter.Key()->HilightSelected (myMainPM, *anIter.Value());
3184     }
3185     anObjOwnerMap.Clear();
3186   }
3187 }
3188
3189 //=======================================================================
3190 //function : UnhilightSelected
3191 //purpose  :
3192 //=======================================================================
3193 void AIS_InteractiveContext::UnhilightSelected (const Standard_Boolean theToUpdateViewer)
3194 {
3195   unhighlightSelected();
3196
3197   if (theToUpdateViewer)
3198   {
3199     UpdateCurrentViewer();
3200   }
3201 }
3202
3203 //=======================================================================
3204 //function : ClearSelected
3205 //purpose  :
3206 //=======================================================================
3207 void AIS_InteractiveContext::ClearSelected (const Standard_Boolean theToUpdateViewer)
3208 {
3209   if (NbSelected() == 0)
3210   {
3211     return;
3212   }
3213
3214   if (myAutoHilight)
3215   {
3216     unhighlightSelected();
3217   }
3218
3219   mySelection->Clear();
3220   if (myAutoHilight)
3221   {
3222     clearDynamicHighlight();
3223   }
3224
3225   if (theToUpdateViewer)
3226   {
3227     UpdateCurrentViewer();
3228   }
3229 }
3230
3231 //=======================================================================
3232 //function : isDetected
3233 //purpose  :
3234 //=======================================================================
3235 Standard_Boolean AIS_InteractiveContext::isDetected (const Handle(AIS_InteractiveObject)& theObject)
3236 {
3237   for (Standard_Integer aDetIter = myDetectedSeq.Lower(); aDetIter <= myDetectedSeq.Upper(); aDetIter++)
3238   {
3239     Handle(SelectMgr_EntityOwner) aPicked = MainSelector()->Picked(myDetectedSeq(aDetIter));
3240     Handle(AIS_InteractiveObject) anObj;
3241     if (!aPicked.IsNull())
3242     {
3243       anObj = Handle(AIS_InteractiveObject)::DownCast(aPicked->Selectable());
3244     }
3245
3246     if (!anObj.IsNull()
3247       && anObj == theObject)
3248     {
3249       return Standard_True;
3250     }
3251   }
3252   return Standard_False;
3253 }
3254
3255 //=======================================================================
3256 //function : SetSelected
3257 //purpose  : Sets the whole object as selected and highlights it with selection color
3258 //=======================================================================
3259 void AIS_InteractiveContext::SetSelected (const Handle(AIS_InteractiveObject)& theObject,
3260                                           const Standard_Boolean theToUpdateViewer)
3261 {
3262   if (theObject.IsNull())
3263   {
3264     return;
3265   }
3266
3267   if (!myObjects.IsBound (theObject))
3268   {
3269     return;
3270   }
3271
3272   Handle(SelectMgr_EntityOwner) anOwner = theObject->GlobalSelOwner();
3273   if (anOwner.IsNull())
3274   {
3275     return;
3276   }
3277
3278   const Handle(Prs3d_Drawer)& anObjSelStyle = getSelStyle (theObject, anOwner);
3279   if (NbSelected() == 1 && myObjects (theObject)->IsHilighted() && myAutoHilight)
3280   {
3281     Handle(Prs3d_Drawer) aCustomStyle;
3282     if (HighlightStyle (theObject, aCustomStyle))
3283     {
3284       if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
3285       {
3286         HilightWithColor (theObject, anObjSelStyle, theToUpdateViewer);
3287       }
3288     }
3289     return;
3290   }
3291
3292   for (AIS_NListOfEntityOwner::Iterator aSelIter (mySelection->Objects()); aSelIter.More(); aSelIter.Next())
3293   {
3294     const Handle(SelectMgr_EntityOwner)& aSelOwner = aSelIter.Value();
3295     if (!myFilters->IsOk (aSelOwner))
3296     {
3297       continue;
3298     }
3299
3300     Handle(AIS_InteractiveObject) aSelectable = Handle(AIS_InteractiveObject)::DownCast (aSelOwner->Selectable());
3301     if (myAutoHilight)
3302     {
3303       Unhilight (aSelectable, Standard_False);
3304     }
3305     if (aSelOwner == aSelectable->GlobalSelOwner())
3306     {
3307       if (Handle(AIS_GlobalStatus)* aStatusPtr = myObjects.ChangeSeek (aSelectable))
3308       {
3309         (*aStatusPtr)->SetHilightStatus (Standard_False);
3310       }
3311     }
3312   }
3313
3314   // added to avoid untimely viewer update...
3315   const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
3316   mySelection->ClearAndSelect (anOwner, myFilters, isDetected (anObj));
3317
3318   if (myAutoHilight)
3319   {
3320     Handle(Prs3d_Drawer) aCustomStyle;
3321     if (HighlightStyle (theObject, aCustomStyle))
3322     {
3323       if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
3324       {
3325         HilightWithColor (theObject, anObjSelStyle, Standard_False);
3326       }
3327     }
3328     else
3329     {
3330       HilightWithColor (theObject, anObjSelStyle, Standard_False);
3331     }
3332   }
3333
3334   if (theToUpdateViewer)
3335   {
3336     UpdateCurrentViewer();
3337   }
3338 }
3339
3340 //=======================================================================
3341 //function : SetSelected
3342 //purpose  : Sets the whole object as selected and highlights it with selection color
3343 //=======================================================================
3344 void AIS_InteractiveContext::SetSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
3345                                           const Standard_Boolean theToUpdateViewer)
3346 {
3347   if (theOwner.IsNull() || !theOwner->HasSelectable() || !myFilters->IsOk (theOwner))
3348   {
3349     return;
3350   }
3351
3352   const Handle(AIS_InteractiveObject) anObject = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
3353   const Handle(Prs3d_Drawer)& anObjSelStyle = getSelStyle (anObject, theOwner);
3354   if (NbSelected() == 1 && theOwner->IsSelected() && !theOwner->IsForcedHilight())
3355   {
3356     Handle(Prs3d_Drawer) aCustomStyle;
3357     if (myAutoHilight && HighlightStyle (theOwner, aCustomStyle))
3358     {
3359       if (!aCustomStyle.IsNull() && anObjSelStyle != aCustomStyle)
3360       {
3361         const Standard_Integer aHiMode = anObject->HasHilightMode() ? anObject->HilightMode() : 0;
3362         theOwner->HilightWithColor (myMainPM, anObjSelStyle, aHiMode);
3363       }
3364     }
3365     return;
3366   }
3367
3368   if (!myObjects.IsBound (anObject))
3369   {
3370     return;
3371   }
3372
3373   if (myAutoHilight)
3374   {
3375     unhighlightSelected();
3376   }
3377
3378   mySelection->ClearAndSelect (theOwner, myFilters, isDetected (anObject));
3379   if (myAutoHilight)
3380   {
3381     Handle(Prs3d_Drawer) aCustomStyle;
3382     if (!HighlightStyle (theOwner, aCustomStyle) ||
3383       (!aCustomStyle.IsNull() && aCustomStyle != anObjSelStyle))
3384     {
3385       highlightSelected (theOwner);
3386     }
3387   }
3388
3389   if (theToUpdateViewer)
3390   {
3391     UpdateCurrentViewer();
3392   }
3393 }
3394
3395 //=======================================================================
3396 //function : AddOrRemoveSelected
3397 //purpose  :
3398 //=======================================================================
3399 void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(AIS_InteractiveObject)& theObject,
3400                                                   const Standard_Boolean theToUpdateViewer)
3401 {
3402   if (theObject.IsNull()
3403   || !myObjects.IsBound (theObject))
3404   {
3405     return;
3406   }
3407
3408   const Handle(SelectMgr_EntityOwner) anOwner = theObject->GlobalSelOwner();
3409   if (!anOwner.IsNull()
3410     && anOwner->HasSelectable())
3411   {
3412     AddOrRemoveSelected (anOwner, theToUpdateViewer);
3413   }
3414 }
3415
3416 //=======================================================================
3417 //function : AddOrRemoveSelected
3418 //purpose  : Allows to highlight or unhighlight the owner given depending on
3419 //           its selection status
3420 //=======================================================================
3421 void AIS_InteractiveContext::AddOrRemoveSelected (const Handle(SelectMgr_EntityOwner)& theOwner,
3422                                                   const Standard_Boolean theToUpdateViewer)
3423 {
3424   if (theOwner.IsNull() || !theOwner->HasSelectable())
3425   {
3426     return;
3427   }
3428
3429   if (!myFilters->IsOk (theOwner) && !theOwner->IsSelected())
3430   {
3431     return;
3432   }
3433
3434   AIS_SelectionScheme aSelScheme = theOwner->IsSelected() ? AIS_SelectionScheme_Remove : AIS_SelectionScheme_Add;
3435   const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast (theOwner->Selectable());
3436   mySelection->Select (theOwner, myFilters, aSelScheme, isDetected (anObj));
3437
3438   if (myAutoHilight)
3439   {
3440     Handle(AIS_GlobalStatus)* aStatusPtr = myObjects.ChangeSeek (anObj);
3441     if (!aStatusPtr)
3442     {
3443       return;
3444     }
3445
3446     if (theOwner->IsSelected())
3447     {
3448       highlightSelected (theOwner);
3449     }
3450     else
3451     {
3452       AIS_NListOfEntityOwner anOwners;
3453       anOwners.Append (theOwner);
3454       unhighlightOwners (anOwners);
3455
3456       (*aStatusPtr)->SetHilightStyle (Handle(Prs3d_Drawer)());
3457     }
3458   }
3459
3460   if (theToUpdateViewer)
3461   {
3462     UpdateCurrentViewer();
3463   }
3464 }
3465
3466 // =======================================================================
3467 // function : SetSelectedState
3468 // purpose  :
3469 // =======================================================================
3470 Standard_Boolean AIS_InteractiveContext::SetSelectedState (const Handle(SelectMgr_EntityOwner)& theEntity,
3471                                                            const Standard_Boolean theIsSelected)
3472 {
3473   if (theEntity.IsNull())
3474   {
3475     throw Standard_ProgramError ("Internal error: AIS_InteractiveContext::SetSelectedState() called with NO object");
3476   }
3477
3478   if (!theEntity->HasSelectable()
3479     || mySelection->IsSelected (theEntity) == theIsSelected)
3480   {
3481     return false;
3482   }
3483
3484   if (theEntity->IsAutoHilight())
3485   {
3486     AddOrRemoveSelected (theEntity, false);
3487     return true;
3488   }
3489
3490   if (theIsSelected)
3491   {
3492     const AIS_SelectStatus aSelStatus = mySelection->AddSelect (theEntity);
3493     theEntity->SetSelected (true);
3494     return aSelStatus == AIS_SS_Added;
3495   }
3496   else
3497   {
3498     const Handle(AIS_InteractiveObject) anObj = Handle(AIS_InteractiveObject)::DownCast(theEntity->Selectable());
3499     const AIS_SelectStatus aSelStatus = mySelection->Select (theEntity, myFilters, AIS_SelectionScheme_Remove, isDetected (anObj));
3500     theEntity->SetSelected (false);
3501     return aSelStatus == AIS_SS_Removed;
3502   }
3503 }
3504
3505 //=======================================================================
3506 //function : IsSelected
3507 //purpose  :
3508 //=======================================================================
3509 Standard_Boolean AIS_InteractiveContext::IsSelected (const Handle(AIS_InteractiveObject)& theObj) const
3510 {
3511   if (theObj.IsNull())
3512   {
3513     return Standard_False;
3514   }
3515
3516   const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theObj);
3517   if (aStatus == NULL)
3518   {
3519     return Standard_False;
3520   }
3521
3522   const Standard_Integer aGlobalSelMode = theObj->GlobalSelectionMode();
3523   const TColStd_ListOfInteger& anActivatedModes = (*aStatus)->SelectionModes();
3524   for (TColStd_ListIteratorOfListOfInteger aModeIter (anActivatedModes); aModeIter.More(); aModeIter.Next())
3525   {
3526     if (aModeIter.Value() == aGlobalSelMode)
3527     {
3528       if (Handle(SelectMgr_EntityOwner) aGlobOwner = theObj->GlobalSelOwner())
3529       {
3530         return aGlobOwner->IsSelected();
3531       }
3532       return Standard_False;
3533     }
3534   }
3535   return Standard_False;
3536 }
3537
3538 //=======================================================================
3539 //function : FirstSelectedObject
3540 //purpose  :
3541 //=======================================================================
3542 Handle(AIS_InteractiveObject) AIS_InteractiveContext::FirstSelectedObject() const
3543 {
3544   return !mySelection->Objects().IsEmpty()
3545         ? Handle(AIS_InteractiveObject)::DownCast (mySelection->Objects().First()->Selectable())
3546         : Handle(AIS_InteractiveObject)();
3547 }
3548
3549 //=======================================================================
3550 //function : HasSelectedShape
3551 //purpose  :
3552 //=======================================================================
3553 Standard_Boolean AIS_InteractiveContext::HasSelectedShape() const
3554 {
3555   if (!mySelection->More())
3556   {
3557     return Standard_False;
3558   }
3559
3560   const Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
3561   return !anOwner.IsNull() && anOwner->HasShape();
3562 }
3563
3564 //=======================================================================
3565 //function : SelectedShape
3566 //purpose  :
3567 //=======================================================================
3568 TopoDS_Shape AIS_InteractiveContext::SelectedShape() const
3569 {
3570   if (!mySelection->More())
3571   {
3572     return TopoDS_Shape();
3573   }
3574
3575   const Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast (mySelection->Value());
3576   if (anOwner.IsNull() || !anOwner->HasSelectable())
3577   {
3578     return TopoDS_Shape();
3579   }
3580
3581   return anOwner->Shape().Located (anOwner->Location() * anOwner->Shape().Location());
3582 }
3583
3584 //=======================================================================
3585 //function : EntityOwners
3586 //purpose  :
3587 //=======================================================================
3588 void AIS_InteractiveContext::EntityOwners (Handle(SelectMgr_IndexedMapOfOwner)& theOwners,
3589                                            const Handle(AIS_InteractiveObject)& theIObj,
3590                                            const Standard_Integer theMode) const
3591 {
3592   if (theIObj.IsNull())
3593   {
3594     return;
3595   }
3596
3597   TColStd_ListOfInteger aModes;
3598   if (theMode == -1)
3599   {
3600     ActivatedModes (theIObj, aModes);
3601   }
3602   else
3603   {
3604     aModes.Append (theMode);
3605   }
3606
3607   if (theOwners.IsNull())
3608   {
3609     theOwners = new SelectMgr_IndexedMapOfOwner();
3610   }
3611
3612   for (TColStd_ListIteratorOfListOfInteger anItr (aModes); anItr.More(); anItr.Next())
3613   {
3614     const int aMode = anItr.Value();
3615     const Handle(SelectMgr_Selection)& aSel = theIObj->Selection (aMode);
3616     if (aSel.IsNull())
3617     {
3618       continue;
3619     }
3620
3621     for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
3622     {
3623       if (Handle(Select3D_SensitiveEntity) aEntity = aSelEntIter.Value()->BaseSensitive())
3624       {
3625         if (const Handle(SelectMgr_EntityOwner)& aOwner = aEntity->OwnerId())
3626         {
3627           theOwners->Add (aOwner);
3628         }
3629       }
3630     }
3631   }
3632 }
3633
3634 //=======================================================================
3635 //function : HasDetectedShape
3636 //purpose  :
3637 //=======================================================================
3638 Standard_Boolean AIS_InteractiveContext::HasDetectedShape() const
3639 {
3640   Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast (myLastPicked);
3641   return !anOwner.IsNull()
3642        && anOwner->HasShape();
3643 }
3644
3645 //=======================================================================
3646 //function : DetectedShape
3647 //purpose  :
3648 //=======================================================================
3649 const TopoDS_Shape& AIS_InteractiveContext::DetectedShape() const
3650 {
3651   Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast (myLastPicked);
3652   return anOwner->Shape();
3653 }
3654
3655 //=======================================================================
3656 //function : HilightNextDetected
3657 //purpose  :
3658 //=======================================================================
3659 Standard_Integer AIS_InteractiveContext::HilightNextDetected (const Handle(V3d_View)& theView,
3660                                                               const Standard_Boolean  theToRedrawImmediate)
3661 {
3662   myMainPM->ClearImmediateDraw();
3663   if (myDetectedSeq.IsEmpty())
3664   {
3665     return 0;
3666   }
3667
3668   if (++myCurHighlighted > myDetectedSeq.Upper())
3669   {
3670     myCurHighlighted = myDetectedSeq.Lower();
3671   }
3672   const Handle(SelectMgr_EntityOwner)& anOwner = MainSelector()->Picked (myDetectedSeq (myCurHighlighted));
3673   if (anOwner.IsNull())
3674   {
3675     return 0;
3676   }
3677
3678   highlightWithColor (anOwner, theView->Viewer());
3679   myLastPicked = anOwner;
3680
3681   if (theToRedrawImmediate)
3682   {
3683     myMainPM->RedrawImmediate (theView->Viewer());
3684     myMainVwr->RedrawImmediate();
3685   }
3686
3687   return myCurHighlighted;
3688 }
3689
3690 //=======================================================================
3691 //function : HilightPreviousDetected
3692 //purpose  :
3693 //=======================================================================
3694 Standard_Integer AIS_InteractiveContext::HilightPreviousDetected (const Handle(V3d_View)& theView,
3695                                                                   const Standard_Boolean  theToRedrawImmediate)
3696 {
3697   myMainPM->ClearImmediateDraw();
3698   if (myDetectedSeq.IsEmpty())
3699   {
3700     return 0;
3701   }
3702
3703   if (--myCurHighlighted < myDetectedSeq.Lower())
3704   {
3705     myCurHighlighted = myDetectedSeq.Upper();
3706   }
3707   const Handle(SelectMgr_EntityOwner)& anOwner = MainSelector()->Picked (myDetectedSeq (myCurHighlighted));
3708   if (anOwner.IsNull())
3709   {
3710     return 0;
3711   }
3712
3713   highlightWithColor (anOwner, theView->Viewer());
3714   myLastPicked = anOwner;
3715
3716   if (theToRedrawImmediate)
3717   {
3718     myMainPM->RedrawImmediate (theView->Viewer());
3719     myMainVwr->RedrawImmediate();
3720   }
3721
3722   return myCurHighlighted;
3723 }
3724
3725 //=======================================================================
3726 //function : DetectedCurrentOwner
3727 //purpose  :
3728 //=======================================================================
3729 Handle(SelectMgr_EntityOwner) AIS_InteractiveContext::DetectedCurrentOwner() const
3730 {
3731   return MoreDetected()
3732        ? MainSelector()->Picked (myDetectedSeq (myCurDetected))
3733        : Handle(SelectMgr_EntityOwner)();
3734 }
3735
3736 //=======================================================================
3737 //function : DetectedCurrentShape
3738 //purpose  :
3739 //=======================================================================
3740 const TopoDS_Shape& AIS_InteractiveContext::DetectedCurrentShape() const
3741 {
3742   static const TopoDS_Shape AIS_InteractiveContext_myDummyShape;
3743
3744   Standard_DISABLE_DEPRECATION_WARNINGS
3745   Handle(AIS_Shape) aCurrentShape = Handle(AIS_Shape)::DownCast (DetectedCurrentObject());
3746   Standard_ENABLE_DEPRECATION_WARNINGS
3747   return !aCurrentShape.IsNull()
3748         ? aCurrentShape->Shape()
3749         : AIS_InteractiveContext_myDummyShape;
3750 }
3751
3752 //=======================================================================
3753 //function : DetectedCurrentObject
3754 //purpose  :
3755 //=======================================================================
3756 Handle(AIS_InteractiveObject) AIS_InteractiveContext::DetectedCurrentObject() const
3757 {
3758   return MoreDetected()
3759        ? Handle(AIS_InteractiveObject)::DownCast (MainSelector()->Picked (myDetectedSeq (myCurDetected))->Selectable())
3760        : Handle(AIS_InteractiveObject)();
3761 }
3762
3763 //=======================================================================
3764 //function : SetSelectionModeActive
3765 //purpose  :
3766 //=======================================================================
3767 void AIS_InteractiveContext::SetSelectionModeActive (const Handle(AIS_InteractiveObject)& theObj,
3768                                                      const Standard_Integer theMode,
3769                                                      const Standard_Boolean theIsActive,
3770                                                      const AIS_SelectionModesConcurrency theActiveFilter,
3771                                                      const Standard_Boolean theIsForce)
3772 {
3773   if (theObj.IsNull())
3774   {
3775     return;
3776   }
3777
3778   const Handle(AIS_GlobalStatus)* aStat = myObjects.Seek (theObj);
3779   if (aStat == NULL)
3780   {
3781     return;
3782   }
3783
3784   if (!theIsActive
3785    || (theMode == -1
3786     && theActiveFilter == AIS_SelectionModesConcurrency_Single))
3787   {
3788     if (theObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
3789      || theIsForce)
3790     {
3791       if (theMode == -1)
3792       {
3793         for (TColStd_ListIteratorOfListOfInteger aModeIter ((*aStat)->SelectionModes()); aModeIter.More(); aModeIter.Next())
3794         {
3795           mgrSelector->Deactivate (theObj, aModeIter.Value());
3796         }
3797       }
3798       else
3799       {
3800         mgrSelector->Deactivate (theObj, theMode);
3801       }
3802     }
3803
3804     if (theMode == -1)
3805     {
3806       (*aStat)->ClearSelectionModes();
3807     }
3808     else
3809     {
3810       (*aStat)->RemoveSelectionMode (theMode);
3811     }
3812     return;
3813   }
3814   else if (theMode == -1)
3815   {
3816     return;
3817   }
3818
3819   if ((*aStat)->SelectionModes().Size() == 1
3820    && (*aStat)->SelectionModes().First() == theMode)
3821   {
3822     return;
3823   }
3824
3825   if (theObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed
3826    || theIsForce)
3827   {
3828     switch (theActiveFilter)
3829     {
3830       case AIS_SelectionModesConcurrency_Single:
3831       {
3832         for (TColStd_ListIteratorOfListOfInteger aModeIter ((*aStat)->SelectionModes()); aModeIter.More(); aModeIter.Next())
3833         {
3834           mgrSelector->Deactivate (theObj, aModeIter.Value());
3835         }
3836         (*aStat)->ClearSelectionModes();
3837         break;
3838       }
3839       case AIS_SelectionModesConcurrency_GlobalOrLocal:
3840       {
3841         const Standard_Integer aGlobSelMode = theObj->GlobalSelectionMode();
3842         TColStd_ListOfInteger aRemovedModes;
3843         for (TColStd_ListIteratorOfListOfInteger aModeIter ((*aStat)->SelectionModes()); aModeIter.More(); aModeIter.Next())
3844         {
3845           if ((theMode == aGlobSelMode && aModeIter.Value() != aGlobSelMode)
3846            || (theMode != aGlobSelMode && aModeIter.Value() == aGlobSelMode))
3847           {
3848             mgrSelector->Deactivate (theObj, aModeIter.Value());
3849             aRemovedModes.Append (aModeIter.Value());
3850           }
3851         }
3852         if (aRemovedModes.Size() == (*aStat)->SelectionModes().Size())
3853         {
3854           (*aStat)->ClearSelectionModes();
3855         }
3856         else
3857         {
3858           for (TColStd_ListIteratorOfListOfInteger aModeIter (aRemovedModes); aModeIter.More(); aModeIter.Next())
3859           {
3860             (*aStat)->RemoveSelectionMode (aModeIter.Value());
3861           }
3862         }
3863         break;
3864       }
3865       case AIS_SelectionModesConcurrency_Multiple:
3866       {
3867         break;
3868       }
3869     }
3870     mgrSelector->Activate (theObj, theMode);
3871   }
3872   (*aStat)->AddSelectionMode (theMode);
3873 }
3874
3875 // ============================================================================
3876 // function : Activate
3877 // purpose  :
3878 // ============================================================================
3879 void AIS_InteractiveContext::Activate (const Standard_Integer theMode,
3880                                        const Standard_Boolean theIsForce)
3881 {
3882   AIS_ListOfInteractive aDisplayedObjects;
3883   DisplayedObjects (aDisplayedObjects);
3884   for (AIS_ListOfInteractive::Iterator anIter (aDisplayedObjects); anIter.More(); anIter.Next())
3885   {
3886     Load (anIter.Value(), -1);
3887     Activate (anIter.Value(), theMode, theIsForce);
3888   }
3889 }
3890
3891 // ============================================================================
3892 // function : Deactivate
3893 // purpose  :
3894 // ============================================================================
3895 void AIS_InteractiveContext::Deactivate (const Standard_Integer theMode)
3896 {
3897   AIS_ListOfInteractive aDisplayedObjects;
3898   DisplayedObjects (aDisplayedObjects);
3899   for (AIS_ListOfInteractive::Iterator anIter (aDisplayedObjects); anIter.More(); anIter.Next())
3900   {
3901     Deactivate (anIter.Value(), theMode);
3902   }
3903 }
3904
3905 // ============================================================================
3906 // function : Deactivate
3907 // purpose  :
3908 // ============================================================================
3909 void AIS_InteractiveContext::Deactivate()
3910 {
3911   AIS_ListOfInteractive aDisplayedObjects;
3912   DisplayedObjects (aDisplayedObjects);
3913
3914   for (AIS_ListOfInteractive::Iterator anIter (aDisplayedObjects); anIter.More(); anIter.Next())
3915   {
3916     Deactivate (anIter.Value());
3917   }
3918 }
3919
3920 //=======================================================================
3921 //function : ActivatedModes
3922 //purpose  :
3923 //=======================================================================
3924 void AIS_InteractiveContext::ActivatedModes (const Handle(AIS_InteractiveObject)& theObj,
3925                                              TColStd_ListOfInteger& theList) const
3926 {
3927   const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theObj);
3928   if (aStatus != NULL)
3929   {
3930     for (TColStd_ListIteratorOfListOfInteger aModeIter ((*aStatus)->SelectionModes()); aModeIter.More(); aModeIter.Next())
3931     {
3932       theList.Append (aModeIter.Value());
3933     }
3934   }
3935 }
3936
3937 //=======================================================================
3938 //function : SubIntensityOn
3939 //purpose  :
3940 //=======================================================================
3941 void AIS_InteractiveContext::SubIntensityOn (const Handle(AIS_InteractiveObject)& theObj,
3942                                              const Standard_Boolean theToUpdateViewer)
3943 {
3944   turnOnSubintensity (theObj);
3945   if (theToUpdateViewer)
3946   {
3947     myMainVwr->Update();
3948   }
3949 }
3950
3951 //=======================================================================
3952 //function : SubIntensityOff
3953 //purpose  :
3954 //=======================================================================
3955 void AIS_InteractiveContext::SubIntensityOff (const Handle(AIS_InteractiveObject)& theObj,
3956                                               const Standard_Boolean theToUpdateViewer)
3957 {
3958   const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theObj);
3959   if (aStatus == NULL
3960    || !(*aStatus)->IsSubIntensityOn())
3961   {
3962     return;
3963   }
3964
3965   (*aStatus)->SetSubIntensity (false);
3966   Standard_Boolean toUpdateMain = Standard_False;
3967   if (theObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
3968   {
3969     myMainPM->Unhighlight (theObj);
3970     toUpdateMain = Standard_True;
3971   }
3972
3973   if (IsSelected (theObj))
3974   {
3975     highlightSelected (theObj->GlobalSelOwner());
3976   }
3977
3978   if (theToUpdateViewer && toUpdateMain)
3979   {
3980     myMainVwr->Update();
3981   }
3982 }
3983
3984 //=======================================================================
3985 //function : DisplayActiveSensitive
3986 //purpose  :
3987 //=======================================================================
3988 void AIS_InteractiveContext::DisplayActiveSensitive(const Handle(V3d_View)& theView)
3989 {
3990   MainSelector()->DisplaySensitive (theView);
3991 }
3992
3993 //=======================================================================
3994 //function : DisplayActiveSensitive
3995 //purpose  :
3996 //=======================================================================
3997 void AIS_InteractiveContext::DisplayActiveSensitive (const Handle(AIS_InteractiveObject)& theObj,
3998                                                      const Handle(V3d_View)& theView)
3999 {
4000   const Handle(AIS_GlobalStatus)* aStatus = myObjects.Seek (theObj);
4001   if (aStatus == NULL)
4002   {
4003     return;
4004   }
4005
4006   for (TColStd_ListIteratorOfListOfInteger aModeIter ((*aStatus)->SelectionModes()); aModeIter.More(); aModeIter.Next())
4007   {
4008     const Handle(SelectMgr_Selection)& aSel = theObj->Selection (aModeIter.Value());
4009     MainSelector()->DisplaySensitive (aSel, theObj->Transformation(), theView, Standard_False);
4010   }
4011 }
4012
4013 //=======================================================================
4014 //function : ClearActiveSensitive
4015 //purpose  :
4016 //=======================================================================
4017 void AIS_InteractiveContext::ClearActiveSensitive (const Handle(V3d_View)& theView)
4018 {
4019   MainSelector()->ClearSensitive (theView);
4020 }
4021
4022 //=======================================================================
4023 //function : IsImmediateModeOn
4024 //purpose  :
4025 //=======================================================================
4026 Standard_Boolean AIS_InteractiveContext::IsImmediateModeOn() const
4027 {
4028   return myMainPM->IsImmediateModeOn();
4029 }
4030
4031 //=======================================================================
4032 //function : BeginImmediateDraw
4033 //purpose  :
4034 //=======================================================================
4035 Standard_Boolean AIS_InteractiveContext::BeginImmediateDraw()
4036 {
4037   if (myMainPM->IsImmediateModeOn())
4038   {
4039     myMainPM->BeginImmediateDraw();
4040     return Standard_True;
4041   }
4042   return Standard_False;
4043 }
4044
4045 //=======================================================================
4046 //function : ImmediateAdd
4047 //purpose  :
4048 //=======================================================================
4049 Standard_Boolean AIS_InteractiveContext::ImmediateAdd (const Handle(AIS_InteractiveObject)& theObj,
4050                                                        const Standard_Integer theMode)
4051 {
4052   if (myMainPM->IsImmediateModeOn())
4053   {
4054     myMainPM->AddToImmediateList (myMainPM->Presentation (theObj, theMode));
4055     return Standard_True;
4056   }
4057   return Standard_False;
4058 }
4059
4060 //=======================================================================
4061 //function : EndImmediateDraw
4062 //purpose  :
4063 //=======================================================================
4064 Standard_Boolean AIS_InteractiveContext::EndImmediateDraw (const Handle(V3d_View)& theView)
4065 {
4066   if (myMainPM->IsImmediateModeOn())
4067   {
4068     myMainPM->EndImmediateDraw (theView->Viewer());
4069     return Standard_True;
4070   }
4071   return Standard_False;
4072 }
4073
4074 //=======================================================================
4075 //function : EndImmediateDraw
4076 //purpose  :
4077 //=======================================================================
4078 Standard_Boolean AIS_InteractiveContext::EndImmediateDraw()
4079 {
4080   if (myMainPM->IsImmediateModeOn())
4081   {
4082     myMainPM->EndImmediateDraw (myMainVwr);
4083     return Standard_True;
4084   }
4085   return Standard_False;
4086 }
4087
4088 //=======================================================================
4089 //function : SetPolygonOffsets
4090 //purpose  :
4091 //=======================================================================
4092 void AIS_InteractiveContext::SetPolygonOffsets (const Handle(AIS_InteractiveObject)& theObj,
4093                                                 const Standard_Integer   theMode,
4094                                                 const Standard_ShortReal theFactor,
4095                                                 const Standard_ShortReal theUnits,
4096                                                 const Standard_Boolean   theToUpdateViewer)
4097 {
4098   if (theObj.IsNull())
4099   {
4100     return;
4101   }
4102
4103   setContextToObject (theObj);
4104   theObj->SetPolygonOffsets (theMode, theFactor, theUnits);
4105
4106   const Handle(AIS_GlobalStatus)* aStatus = theToUpdateViewer ? myObjects.Seek (theObj) : NULL;
4107   if (aStatus != NULL
4108    && theObj->DisplayStatus() == PrsMgr_DisplayStatus_Displayed)
4109   {
4110     myMainVwr->Update();
4111   }
4112 }
4113
4114 //=======================================================================
4115 //function : HasPolygonOffsets
4116 //purpose  :
4117 //=======================================================================
4118 Standard_Boolean AIS_InteractiveContext::HasPolygonOffsets (const Handle(AIS_InteractiveObject)& theObj) const
4119 {
4120   return !theObj.IsNull() && theObj->HasPolygonOffsets();
4121 }
4122
4123 //=======================================================================
4124 //function : PolygonOffsets
4125 //purpose  :
4126 //=======================================================================
4127 void AIS_InteractiveContext::PolygonOffsets (const Handle(AIS_InteractiveObject)& theObj,
4128                                              Standard_Integer&   theMode,
4129                                              Standard_ShortReal& theFactor,
4130                                              Standard_ShortReal& theUnits) const
4131 {
4132   if (HasPolygonOffsets (theObj))
4133   {
4134     theObj->PolygonOffsets (theMode, theFactor, theUnits);
4135   }
4136 }
4137
4138 //=======================================================================
4139 //function : DumpJson
4140 //purpose  :
4141 //=======================================================================
4142 void AIS_InteractiveContext::DumpJson (Standard_OStream& theOStream, Standard_Integer) const
4143 {
4144   OCCT_DUMP_TRANSIENT_CLASS_BEGIN (theOStream)
4145
4146   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myObjects.Size())
4147
4148   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, mgrSelector.get())
4149   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myMainPM.get())
4150   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myMainVwr.get())
4151   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myLastActiveView)
4152
4153   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myLastPicked.get())
4154
4155   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myToHilightSelected)
4156
4157   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, mySelection.get())
4158   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myFilters.get())
4159   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myDefaultDrawer.get())
4160
4161   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myStyles[Prs3d_TypeOfHighlight_Selected])
4162   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myStyles[Prs3d_TypeOfHighlight_Dynamic])
4163   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myStyles[Prs3d_TypeOfHighlight_LocalSelected])
4164   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myStyles[Prs3d_TypeOfHighlight_LocalDynamic])
4165   OCCT_DUMP_FIELD_VALUE_POINTER (theOStream, myStyles[Prs3d_TypeOfHighlight_SubIntensity])
4166
4167   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myDetectedSeq.Size())
4168
4169   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCurDetected)
4170   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myCurHighlighted)
4171   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myPickingStrategy)
4172   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myAutoHilight)
4173   OCCT_DUMP_FIELD_VALUE_NUMERICAL (theOStream, myIsAutoActivateSelMode)
4174 }