]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_Displayer.cpp
Salome HOME
0eff27bb2944ec5c70e7539661fc943330c15904
[modules/shaper.git] / src / XGUI / XGUI_Displayer.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        XGUI_Displayer.cpp
4 // Created:     20 Apr 2014
5 // Author:      Natalia ERMOLAEVA
6
7 #include "XGUI_Displayer.h"
8 #include "XGUI_Workshop.h"
9 #include "XGUI_ViewerProxy.h"
10 #include "XGUI_SelectionMgr.h"
11 #include "XGUI_Selection.h"
12 #include "XGUI_CustomPrs.h"
13
14 #include <AppElements_Viewer.h>
15
16 #include <ModelAPI_Document.h>
17 #include <ModelAPI_Data.h>
18 #include <ModelAPI_Object.h>
19 #include <ModelAPI_Tools.h>
20 #include <ModelAPI_AttributeIntArray.h>
21
22 #include <ModuleBase_ResultPrs.h>
23
24 #include <GeomAPI_Shape.h>
25 #include <GeomAPI_IPresentable.h>
26 #include <GeomAPI_ICustomPrs.h>
27
28 #include <AIS_InteractiveContext.hxx>
29 #include <AIS_LocalContext.hxx>
30 #include <AIS_ListOfInteractive.hxx>
31 #include <AIS_ListIteratorOfListOfInteractive.hxx>
32 #include <AIS_DimensionSelectionMode.hxx>
33 #include <AIS_Shape.hxx>
34 #include <AIS_Dimension.hxx>
35 #include <TColStd_ListIteratorOfListOfInteger.hxx>
36 #include <SelectMgr_ListOfFilter.hxx>
37 #include <SelectMgr_ListIteratorOfListOfFilter.hxx>
38
39 #include <TColStd_MapOfTransient.hxx>
40 #include <TColStd_MapIteratorOfMapOfTransient.hxx>
41
42 #include <set>
43
44 const int MOUSE_SENSITIVITY_IN_PIXEL = 10;  ///< defines the local context mouse selection sensitivity
45
46 //#define DEBUG_DISPLAY
47 //#define DEBUG_ACTIVATE
48 //#define DEBUG_FEATURE_REDISPLAY
49 //#define DEBUG_SELECTION_FILTERS
50
51 // Workaround for bug #25637
52 void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfInteractive& theList)
53 {
54   // Get from null point
55   theAIS->DisplayedObjects(theList, true);
56   if (theAIS->HasOpenedContext()) {
57     // get from local context
58     const Handle(AIS_LocalContext)& aLC = theAIS->LocalContext();
59     TColStd_MapOfTransient aMap;
60     int NbDisp = aLC->DisplayedObjects(aMap);
61     TColStd_MapIteratorOfMapOfTransient aIt(aMap);
62
63     Handle(AIS_InteractiveObject) curIO;
64     Handle(Standard_Transient) Tr;
65     for(; aIt.More(); aIt.Next()){
66       Tr = aIt.Key();
67       curIO = *((Handle(AIS_InteractiveObject)*) &Tr);
68       theList.Append(curIO);
69     }
70   }
71 }
72
73
74 XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop)
75   : myWorkshop(theWorkshop)
76 {
77   enableUpdateViewer(true);
78   myCustomPrs = std::shared_ptr<GeomAPI_ICustomPrs>(new XGUI_CustomPrs());
79 }
80
81 XGUI_Displayer::~XGUI_Displayer()
82 {
83 }
84
85 bool XGUI_Displayer::isVisible(ObjectPtr theObject) const
86 {
87   return myResult2AISObjectMap.contains(theObject);
88 }
89
90 void XGUI_Displayer::display(ObjectPtr theObject, bool isUpdateViewer)
91 {
92   if (isVisible(theObject)) {
93     redisplay(theObject, isUpdateViewer);
94   } else {
95 #ifdef DEBUG_DISPLAY
96     FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
97     if (aFeature.get() != NULL) {
98       qDebug(QString("display feature: %1, displayed: %2").
99         arg(aFeature->data()->name().c_str()).
100         arg(displayedObjects().size()).toStdString().c_str());
101     }
102 #endif
103     AISObjectPtr anAIS;
104
105     GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
106     bool isShading = false;
107     if (aPrs.get() != NULL) {
108       anAIS = aPrs->getAISObject(anAIS);
109     } else {
110       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
111       if (aResult.get() != NULL) {
112         std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
113         if (aShapePtr.get() != NULL) {
114           anAIS = AISObjectPtr(new GeomAPI_AISObject());
115           anAIS->setImpl(new Handle(AIS_InteractiveObject)(new ModuleBase_ResultPrs(aResult)));
116           //anAIS->createShape(aShapePtr);
117           isShading = true;
118         }
119       }
120     }
121     if (anAIS)
122       display(theObject, anAIS, isShading, isUpdateViewer);
123   }
124 }
125
126 bool canBeShaded(Handle(AIS_InteractiveObject) theAIS)
127 {
128   Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(theAIS);
129   if (!aShapePrs.IsNull()) {
130     TopoDS_Shape aShape = aShapePrs->Shape();
131     TopAbs_ShapeEnum aType = aShape.ShapeType();
132     if ((aType == TopAbs_VERTEX) || (aType == TopAbs_EDGE) || (aType == TopAbs_WIRE))
133       return false;
134     else {
135       // Check that the presentation is not a sketch
136       Handle(ModuleBase_ResultPrs) aPrs = Handle(ModuleBase_ResultPrs)::DownCast(theAIS);
137       if (!aPrs.IsNull()) 
138         return !aPrs->isSketchMode();
139       return true;
140     }
141   }
142   return false;
143 }
144
145 void XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, 
146                              bool isShading, bool isUpdateViewer)
147 {
148   Handle(AIS_InteractiveContext) aContext = AISContext();
149   if (aContext.IsNull())
150     return;
151
152   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
153   if (!anAISIO.IsNull()) {
154     myResult2AISObjectMap[theObject] = theAIS;
155     bool aCanBeShaded = ::canBeShaded(anAISIO);
156     // In order to avoid extra closing/opening context
157     SelectMgr_IndexedMapOfOwner aSelectedOwners;
158     if (aCanBeShaded) {
159       myWorkshop->selector()->selection()->selectedOwners(aSelectedOwners);
160       closeLocalContexts(false);
161     }
162     aContext->Display(anAISIO, false);
163     aContext->SetDisplayMode(anAISIO, isShading? Shading : Wireframe, false);
164     if (isShading)
165       anAISIO->Attributes()->SetFaceBoundaryDraw( Standard_True );
166     emit objectDisplayed(theObject, theAIS);
167
168     bool isCustomized = customizeObject(theObject);
169     if (isCustomized)
170       aContext->Redisplay(anAISIO, false);
171
172     if (aCanBeShaded) {
173       openLocalContext();
174       activateObjects(myActiveSelectionModes);
175       myWorkshop->selector()->setSelectedOwners(aSelectedOwners, false);
176     }
177     else
178       activate(anAISIO, myActiveSelectionModes);
179  }
180   if (isUpdateViewer)
181     updateViewer();
182 }
183
184 void XGUI_Displayer::erase(ObjectPtr theObject, const bool isUpdateViewer)
185 {
186   if (!isVisible(theObject))
187     return;
188
189   Handle(AIS_InteractiveContext) aContext = AISContext();
190   if (aContext.IsNull())
191     return;
192   AISObjectPtr anObject = myResult2AISObjectMap[theObject];
193   if (anObject) {
194     Handle(AIS_InteractiveObject) anAIS = anObject->impl<Handle(AIS_InteractiveObject)>();
195     if (!anAIS.IsNull()) {
196       emit beforeObjectErase(theObject, anObject);
197       aContext->Remove(anAIS, isUpdateViewer);
198     }
199   }
200   myResult2AISObjectMap.remove(theObject);
201 }
202
203 void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer)
204 {
205   if (!isVisible(theObject))
206     return;
207
208   AISObjectPtr aAISObj = getAISObject(theObject);
209   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
210
211   GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
212   if (aPrs) {
213     AISObjectPtr aAIS_Obj = aPrs->getAISObject(aAISObj);
214     if (!aAIS_Obj) {
215       erase(theObject, isUpdateViewer);
216       return;
217     }
218     if (aAIS_Obj != aAISObj) {
219       myResult2AISObjectMap[theObject] = aAIS_Obj;
220     }
221     aAISIO = aAIS_Obj->impl<Handle(AIS_InteractiveObject)>();
222   }
223
224   if (!aAISIO.IsNull()) {
225     Handle(AIS_InteractiveContext) aContext = AISContext();
226     if (aContext.IsNull())
227       return;
228     // Check that the visualized shape is the same and the redisplay is not necessary
229     // Redisplay of AIS object leads to this object selection compute and the selection 
230     // in the browser is lost
231
232     // this check is not necessary anymore because the selection store/restore is realized
233     // before and after the values modification.
234     // Moreother, this check avoids customize and redisplay presentation if the presentable
235     // parameter is changed.
236     bool isEqualShapes = false;
237     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
238     if (aResult.get() != NULL) {
239       Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(aAISIO);
240       if (!aShapePrs.IsNull()) {
241         std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
242         if (aShapePtr.get()) {
243           const TopoDS_Shape& aShape = aShapePrs->Shape();
244           std::shared_ptr<GeomAPI_Shape> anAISShapePtr(new GeomAPI_Shape());
245           anAISShapePtr->setImpl(new TopoDS_Shape(aShape));
246
247           isEqualShapes = aShapePtr->isEqual(anAISShapePtr);
248         }
249       }
250     }
251     // Customization of presentation
252     bool isCustomized = customizeObject(theObject);
253     #ifdef DEBUG_FEATURE_REDISPLAY
254       qDebug(QString("Redisplay: %1, isEqualShapes=%2, isCustomized=%3").
255         arg(!isEqualShapes || isCustomized).arg(isEqualShapes).arg(isCustomized).toStdString().c_str());
256     #endif
257     if (!isEqualShapes || isCustomized) {
258       aContext->Redisplay(aAISIO, false);
259       #ifdef DEBUG_FEATURE_REDISPLAY
260       //qDebug("  Redisplay happens");
261       #endif
262       if (isUpdateViewer)
263         updateViewer();
264     }
265   }
266 }
267
268 void XGUI_Displayer::deactivate(ObjectPtr theObject)
269 {
270   if (isVisible(theObject)) {
271     Handle(AIS_InteractiveContext) aContext = AISContext();
272     if (aContext.IsNull())
273       return;
274
275     AISObjectPtr anObj = myResult2AISObjectMap[theObject];
276     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
277     aContext->Deactivate(anAIS);
278   }
279 }
280
281 /*void XGUI_Displayer::activate(ObjectPtr theFeature)
282 {
283   activate(theFeature, myActiveSelectionModes);
284 }
285
286 void XGUI_Displayer::activate(ObjectPtr theObject, const QIntList& theModes)
287 {
288 #ifdef DEBUG_ACTIVATE
289     FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
290
291     if (aFeature.get() != NULL) {
292       QIntList aModes;
293       getModesOfActivation(theObject, aModes);
294
295
296       qDebug(QString("activate feature: %1, theModes: %2, myActiveSelectionModes: %3, getModesOf: %4").
297         arg(aFeature->data()->name().c_str()).
298         arg(theModes.size()).
299         arg(myActiveSelectionModes.size()).
300         arg(aModes.size()).toStdString().c_str());
301     }
302 #endif
303
304   if (isVisible(theObject)) {
305     Handle(AIS_InteractiveContext) aContext = AISContext();
306     if (aContext.IsNull())
307       return;
308
309     AISObjectPtr anObj = myResult2AISObjectMap[theObject];
310     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
311
312     activate(anAIS, theModes);
313   }
314 }*/
315
316 void XGUI_Displayer::getModesOfActivation(ObjectPtr theObject, QIntList& theModes)
317 {
318   if (!isVisible(theObject))
319     return;
320
321   Handle(AIS_InteractiveContext) aContext = AISContext();
322   if (aContext.IsNull())
323     return;
324
325   AISObjectPtr aAISObj = getAISObject(theObject);
326
327   if (aAISObj.get() != NULL) {
328     Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
329     TColStd_ListOfInteger aTColModes;
330     aContext->ActivatedModes(anAISIO, aTColModes);
331     TColStd_ListIteratorOfListOfInteger itr( aTColModes );
332     for (; itr.More(); itr.Next() ) {
333       theModes.append(itr.Value());
334     }
335   }
336 }
337
338 void XGUI_Displayer::activateObjects(const QIntList& theModes)
339 {
340 #ifdef DEBUG_ACTIVATE
341   qDebug(QString("activate all features: theModes: %2, myActiveSelectionModes: %3").
342     arg(theModes.size()).
343     arg(myActiveSelectionModes.size()).
344     toStdString().c_str());
345 #endif
346   // In order to avoid doblications of selection modes
347   QIntList aNewModes;
348   foreach (int aMode, theModes) {
349     if (!aNewModes.contains(aMode))
350       aNewModes.append(aMode);
351   }
352   myActiveSelectionModes = aNewModes;
353   Handle(AIS_InteractiveContext) aContext = AISContext();
354   if (aContext.IsNull())
355     return;
356   // Open local context if there is no one
357   if (!aContext->HasOpenedContext()) 
358     return;
359
360   //aContext->UseDisplayedObjects();
361   //myUseExternalObjects = true;
362
363   AIS_ListOfInteractive aPrsList;
364   ::displayedObjects(aContext, aPrsList);
365
366   Handle(AIS_Trihedron) aTrihedron;
367   AIS_ListIteratorOfListOfInteractive aLIt(aPrsList);
368   Handle(AIS_InteractiveObject) anAISIO;
369   for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){
370     anAISIO = aLIt.Value();
371     activate(anAISIO, myActiveSelectionModes);
372   }
373 }
374
375
376 void XGUI_Displayer::deactivateObjects()
377 {
378   myActiveSelectionModes.clear();
379   Handle(AIS_InteractiveContext) aContext = AISContext();
380   // Open local context if there is no one
381   if (!aContext->HasOpenedContext()) 
382     return;
383
384   //aContext->NotUseDisplayedObjects();
385   AIS_ListOfInteractive aPrsList;
386   ::displayedObjects(aContext, aPrsList);
387
388   AIS_ListIteratorOfListOfInteractive aLIt;
389   //Handle(AIS_Trihedron) aTrihedron;
390   Handle(AIS_InteractiveObject) anAISIO;
391   for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){
392     anAISIO = aLIt.Value();
393     aContext->Deactivate(anAISIO);
394   }
395 }
396
397 bool XGUI_Displayer::isActive(ObjectPtr theObject) const
398 {
399   Handle(AIS_InteractiveContext) aContext = AISContext();
400   if (aContext.IsNull())
401     return false;
402   if (!isVisible(theObject))
403     return false;
404     
405   AISObjectPtr anObj = myResult2AISObjectMap[theObject];
406   Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
407
408   TColStd_ListOfInteger aModes;
409   aContext->ActivatedModes(anAIS, aModes);
410   return aModes.Extent() > 0;
411 }
412
413 void XGUI_Displayer::setSelected(const QObjectPtrList& theResults, const bool isUpdateViewer)
414 {
415   Handle(AIS_InteractiveContext) aContext = AISContext();
416   if (aContext.IsNull())
417     return;
418   if (aContext->HasOpenedContext()) {
419     aContext->UnhilightSelected();
420     aContext->ClearSelected();
421     foreach(ObjectPtr aResult, theResults) {
422       if (isVisible(aResult)) {
423         AISObjectPtr anObj = myResult2AISObjectMap[aResult];
424         Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
425         if (!anAIS.IsNull())
426           aContext->SetSelected(anAIS, false);
427       }
428     }
429   } else {
430     aContext->UnhilightCurrents();
431     aContext->ClearCurrents();
432     foreach(ObjectPtr aResult, theResults) {
433       if (isVisible(aResult)) {
434         AISObjectPtr anObj = myResult2AISObjectMap[aResult];
435         Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
436         if (!anAIS.IsNull())
437           aContext->SetCurrentObject(anAIS, false);
438       }
439     }
440   }
441   if (isUpdateViewer)
442     updateViewer();
443 }
444
445
446 void XGUI_Displayer::clearSelected()
447 {
448   Handle(AIS_InteractiveContext) aContext = AISContext();
449   if (aContext) {
450     aContext->UnhilightCurrents(false);
451     aContext->ClearSelected();
452   }
453 }
454
455 void XGUI_Displayer::eraseAll(const bool isUpdateViewer)
456 {
457   Handle(AIS_InteractiveContext) aContext = AISContext();
458   if (!aContext.IsNull()) {
459     foreach (ObjectPtr aObj, myResult2AISObjectMap.keys()) {
460       AISObjectPtr aAISObj = myResult2AISObjectMap[aObj];
461       // erase an object
462       Handle(AIS_InteractiveObject) anIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
463       if (!anIO.IsNull()) {
464         emit beforeObjectErase(aObj, aAISObj);
465         aContext->Remove(anIO, false);
466       }
467     }
468     if (isUpdateViewer)
469       updateViewer();
470   }
471   myResult2AISObjectMap.clear();
472 }
473
474 void XGUI_Displayer::openLocalContext()
475 {
476   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
477   if (aContext.IsNull())
478     return;
479   // Open local context if there is no one
480   if (!aContext->HasOpenedContext()) {
481     // Preserve selected objects
482     //AIS_ListOfInteractive aAisList;
483     //for (aContext->InitCurrent(); aContext->MoreCurrent(); aContext->NextCurrent())
484     //  aAisList.Append(aContext->Current());
485
486     // get the filters from the global context and append them to the local context
487     // a list of filters in the global context is not cleared and should be cleared here
488     SelectMgr_ListOfFilter aFilters;
489     aFilters.Assign(aContext->Filters());
490     // it is important to remove the filters in the global context, because there is a code
491     // in the closeLocalContex, which restore the global context filters
492     aContext->RemoveFilters();
493
494     //aContext->ClearCurrents();
495     aContext->OpenLocalContext();
496     //aContext->NotUseDisplayedObjects();
497
498     //myUseExternalObjects = false;
499
500     SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
501     for (;aIt.More(); aIt.Next()) {
502       aContext->AddFilter(aIt.Value());
503     }
504     // Restore selection
505     //AIS_ListIteratorOfListOfInteractive aIt2(aAisList);
506     //for(; aIt2.More(); aIt2.Next()) {
507     //  aContext->SetSelected(aIt2.Value(), false);
508     //}
509   }
510 }
511
512 void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer)
513 {
514   Handle(AIS_InteractiveContext) aContext = AISContext();
515   if ( (!aContext.IsNull()) && (aContext->HasOpenedContext()) ) {
516     // Preserve selected objects
517     //AIS_ListOfInteractive aAisList;
518     //for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected())
519     //  aAisList.Append(aContext->SelectedInteractive());
520
521     // get the filters from the local context and append them to the global context
522     // a list of filters in the local context is cleared
523     SelectMgr_ListOfFilter aFilters;
524     aFilters.Assign(aContext->Filters());
525
526     //aContext->ClearSelected();
527     aContext->CloseAllContexts(false);
528
529     // Redisplay all object if they were displayed in localContext
530     Handle(AIS_InteractiveObject) aAISIO;
531     foreach (AISObjectPtr aAIS, myResult2AISObjectMap) {
532       aAISIO = aAIS->impl<Handle(AIS_InteractiveObject)>();
533       if (aContext->DisplayStatus(aAISIO) != AIS_DS_Displayed) {
534         aContext->Display(aAISIO, false);
535         aContext->SetDisplayMode(aAISIO, Shading, false);
536       }
537     }
538
539     // Append the filters from the local selection in the global selection context
540     SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
541     for (;aIt.More(); aIt.Next()) {
542       Handle(SelectMgr_Filter) aFilter = aIt.Value();
543       aContext->AddFilter(aFilter);
544     }
545
546     if (isUpdateViewer)
547       updateViewer();
548     //myUseExternalObjects = false;
549
550     // Restore selection
551     //AIS_ListIteratorOfListOfInteractive aIt2(aAisList);
552     //for(; aIt2.More(); aIt2.Next()) {
553     //  if (aContext->IsDisplayed(aIt2.Value()))
554     //    aContext->SetCurrentObject(aIt2.Value(), false);
555     //}
556   }
557 }
558
559 AISObjectPtr XGUI_Displayer::getAISObject(ObjectPtr theObject) const
560 {
561   AISObjectPtr anIO;
562   if (myResult2AISObjectMap.contains(theObject))
563     anIO = myResult2AISObjectMap[theObject];
564   return anIO;
565 }
566
567 ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const
568 {
569   Handle(AIS_InteractiveObject) aRefAIS = theIO->impl<Handle(AIS_InteractiveObject)>();
570   return getObject(aRefAIS);
571 }
572
573 ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const
574 {
575   ObjectPtr aFeature;
576   foreach (ObjectPtr anObj, myResult2AISObjectMap.keys()) {
577     AISObjectPtr aAIS = myResult2AISObjectMap[anObj];
578     Handle(AIS_InteractiveObject) anAIS = aAIS->impl<Handle(AIS_InteractiveObject)>();
579     if (anAIS == theIO)
580       return anObj;
581   }
582   return aFeature;
583 }
584
585 bool XGUI_Displayer::enableUpdateViewer(const bool isEnabled)
586 {
587   bool aWasEnabled = myEnableUpdateViewer;
588
589   myEnableUpdateViewer = isEnabled;
590
591   return aWasEnabled;
592 }
593
594 void XGUI_Displayer::updateViewer()
595 {
596   Handle(AIS_InteractiveContext) aContext = AISContext();
597   if (!aContext.IsNull() && myEnableUpdateViewer)
598     aContext->UpdateCurrentViewer();
599 }
600
601 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
602 {
603   Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
604   if ((!aContext.IsNull()) && (!aContext->HasOpenedContext())) {
605     aContext->OpenLocalContext();
606   }
607   return aContext;
608 }
609
610 Handle(SelectMgr_AndFilter) XGUI_Displayer::GetFilter()
611 {
612   Handle(AIS_InteractiveContext) aContext = AISContext();
613   if (myAndFilter.IsNull() && !aContext.IsNull()) {
614     myAndFilter = new SelectMgr_AndFilter();
615     aContext->AddFilter(myAndFilter);
616   }
617   return myAndFilter;
618 }
619
620 void XGUI_Displayer::displayAIS(AISObjectPtr theAIS, bool isUpdate)
621 {
622   Handle(AIS_InteractiveContext) aContext = AISContext();
623   if (aContext.IsNull())
624     return;
625   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
626   if (!anAISIO.IsNull()) {
627     aContext->Display(anAISIO, isUpdate);
628     if (aContext->HasOpenedContext()) {
629       //if (myUseExternalObjects) {
630         if (myActiveSelectionModes.size() == 0)
631           aContext->Activate(anAISIO);
632         else {
633           foreach(int aMode, myActiveSelectionModes) {
634             aContext->Activate(anAISIO, aMode);
635           }
636         }
637       //}
638     }
639   }
640 }
641
642 void XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool isUpdate)
643 {
644   Handle(AIS_InteractiveContext) aContext = AISContext();
645   if (aContext.IsNull())
646     return;
647   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
648   if (!anAISIO.IsNull()) {
649     aContext->Remove(anAISIO, isUpdate);
650   }
651 }
652
653
654 void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool toUpdate)
655 {
656   if (theMode == NoMode)
657     return;
658
659   Handle(AIS_InteractiveContext) aContext = AISContext();
660   if (aContext.IsNull())
661     return;
662
663   AISObjectPtr aAISObj = getAISObject(theObject);
664   if (!aAISObj)
665     return;
666
667   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
668   bool aCanBeShaded = ::canBeShaded(aAISIO);
669   // In order to avoid extra closing/opening context
670   SelectMgr_IndexedMapOfOwner aSelectedOwners;
671   if (aCanBeShaded) {
672     myWorkshop->selector()->selection()->selectedOwners(aSelectedOwners);
673     closeLocalContexts(false);
674   }
675   aContext->SetDisplayMode(aAISIO, theMode, false);
676   if (aCanBeShaded) {
677     openLocalContext();
678     activateObjects(myActiveSelectionModes);
679     myWorkshop->selector()->setSelectedOwners(aSelectedOwners, false);
680   }
681   if (toUpdate)
682     updateViewer();
683 }
684
685 XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const
686 {
687   Handle(AIS_InteractiveContext) aContext = AISContext();
688   if (aContext.IsNull())
689     return NoMode;
690
691   AISObjectPtr aAISObj = getAISObject(theObject);
692   if (!aAISObj)
693     return NoMode;
694
695   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
696   return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode();
697 }
698
699 void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
700 {
701   Handle(AIS_InteractiveContext) aContext = AISContext();
702   if (aContext.IsNull())
703     return;
704   const SelectMgr_ListOfFilter& aFilters = aContext->Filters();
705   SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
706   for (; aIt.More(); aIt.Next()) {
707     if (theFilter.Access() == aIt.Value().Access())
708       return;
709   }
710   Handle(SelectMgr_CompositionFilter) aCompFilter = GetFilter();
711   const SelectMgr_ListOfFilter& aStoredFilters = aCompFilter->StoredFilters();
712   for (aIt.Initialize(aStoredFilters); aIt.More(); aIt.Next()) {
713     if (theFilter.Access() == aIt.Value().Access())
714       return;
715   }
716   aCompFilter->Add(theFilter);
717 #ifdef DEBUG_SELECTION_FILTERS
718   int aCount = GetFilter()->StoredFilters().Extent();
719   qDebug(QString("addSelectionFilter: filters.count() = %1").arg(aCount).toStdString().c_str());
720 #endif
721 }
722
723 void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
724 {
725   Handle(AIS_InteractiveContext) aContext = AISContext();
726   if (aContext.IsNull())
727     return;
728   Handle(SelectMgr_AndFilter) aCompositeFilter = GetFilter();
729   if (aCompositeFilter->IsIn(theFilter))
730     aCompositeFilter->Remove(theFilter);
731 #ifdef DEBUG_SELECTION_FILTERS
732   int aCount = GetFilter()->StoredFilters().Extent();
733   qDebug(QString("removeSelectionFilter: filters.count() = %1").arg(aCount).toStdString().c_str());
734 #endif
735 }
736
737 void XGUI_Displayer::removeFilters()
738 {
739   Handle(AIS_InteractiveContext) aContext = AISContext();
740   if (aContext.IsNull())
741     return;
742   GetFilter()->Clear();
743 }
744
745 void XGUI_Displayer::showOnly(const QObjectPtrList& theList)
746 {
747   QObjectPtrList aDispList = myResult2AISObjectMap.keys();
748   foreach(ObjectPtr aObj, aDispList) {
749     if (!theList.contains(aObj))
750       erase(aObj, false);
751   }
752   foreach(ObjectPtr aObj, theList) {
753     if (!isVisible(aObj))
754       display(aObj, false);
755   }
756   updateViewer();
757 }
758
759 bool XGUI_Displayer::canBeShaded(ObjectPtr theObject) const
760
761   if (!isVisible(theObject))
762     return false;
763
764   AISObjectPtr aAISObj = getAISObject(theObject);
765   if (aAISObj.get() == NULL)
766     return false;
767
768   Handle(AIS_InteractiveObject) anAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
769   return ::canBeShaded(anAIS);
770 }
771
772 void XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO,
773                               const QIntList& theModes) const
774 {
775   Handle(AIS_InteractiveContext) aContext = AISContext();
776   if (aContext.IsNull() || theIO.IsNull())
777     return;
778
779   // deactivate object in all modes, which are not in the list of activation
780   // It seems that after the IO deactivation the selected state of the IO's owners
781   // is modified in OCC(version: 6.8.0) and the selection of the object later is lost.
782   // By this reason, the number of the IO deactivate is decreased and the object is deactivated
783   // only if there is a difference in the current modes and the parameters modes.
784   // If the selection problem happens again, it is possible to write a test scenario and create
785   // a bug. The bug steps are the following:
786   // Create two IO, activate them in 5 modes, select the first IO, deactivate 3 modes for both,
787   // with clicked SHIFT select the second object. The result is the selection of the first IO is lost.
788   TColStd_ListOfInteger aTColModes;
789   aContext->ActivatedModes(theIO, aTColModes);
790   TColStd_ListIteratorOfListOfInteger itr( aTColModes );
791   QIntList aModesActivatedForIO;
792   for (; itr.More(); itr.Next() ) {
793     Standard_Integer aMode = itr.Value();
794     if (!theModes.contains(aMode)) {
795 #ifdef DEBUG_ACTIVATE
796       qDebug(QString("deactivate: %1").arg(aMode).toStdString().c_str());
797 #endif
798       aContext->Deactivate(theIO, aMode);
799     }
800     else {
801       aModesActivatedForIO.append(aMode);
802 #ifdef DEBUG_ACTIVATE
803       qDebug(QString("  active: %1").arg(aMode).toStdString().c_str());
804 #endif
805     }
806   }
807   // loading the interactive object allowing the decomposition
808   if (aTColModes.IsEmpty())
809     aContext->Load(theIO, -1, true);
810
811   Handle(AIS_Trihedron) aTrihedron = Handle(AIS_Trihedron)::DownCast(theIO);
812   //Deactivate trihedron which can be activated in local selector
813   if (aTrihedron.IsNull()) {
814     //aContext->Load(anAISIO, -1, true);
815     // In order to clear active modes list
816     if (theModes.size() == 0) {
817       //aContext->Load(anAISIO, 0, true);
818       aContext->Activate(theIO);
819 #ifdef DEBUG_ACTIVATE
820       qDebug("activate in all modes");
821 #endif
822     } else {
823       foreach(int aMode, theModes) {
824         //aContext->Load(anAISIO, aMode, true);
825         if (!aModesActivatedForIO.contains(aMode)) {
826           aContext->Activate(theIO, aMode);
827 #ifdef DEBUG_ACTIVATE
828           qDebug(QString("activate: %1").arg(aMode).toStdString().c_str());
829 #endif
830         }
831       }
832     }
833   }
834 }
835
836 bool XGUI_Displayer::customizeObject(ObjectPtr theObject)
837 {
838   AISObjectPtr anAISObj = getAISObject(theObject);
839   // correct the result's color it it has the attribute
840   ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
841
842   // Customization of presentation
843   GeomCustomPrsPtr aCustomPrs;
844   FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
845   if (aFeature.get() != NULL) {
846     GeomCustomPrsPtr aCustPrs = std::dynamic_pointer_cast<GeomAPI_ICustomPrs>(aFeature);
847     if (aCustPrs.get() != NULL)
848       aCustomPrs = aCustPrs;
849   }
850   if (aCustomPrs.get() == NULL) {
851     // we ignore presentable not customized objects
852     GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
853     if (aPrs.get() != NULL)
854       return false;
855     aCustomPrs = myCustomPrs;
856   }
857   return aCustomPrs->customisePresentation(aResult, anAISObj, myCustomPrs);
858 }
859
860
861 QColor XGUI_Displayer::setObjectColor(ObjectPtr theObject, const QColor& theColor, bool toUpdate)
862 {
863   if (!isVisible(theObject))
864     return Qt::black;
865
866   AISObjectPtr anAISObj = getAISObject(theObject);
867   int aR, aG, aB;
868   anAISObj->getColor(aR, aG, aB);
869   anAISObj->setColor(theColor.red(), theColor.green(), theColor.blue());
870   if (toUpdate)
871     updateViewer();
872   return QColor(aR, aG, aB);
873 }