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