Salome HOME
Merge branch 'Dev_0.6.1' of newgeom:newgeom into Dev_0.6.1
[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
11 #include <AppElements_Viewer.h>
12
13 #include <ModelAPI_Document.h>
14 #include <ModelAPI_Data.h>
15 #include <ModelAPI_Object.h>
16 #include <ModelAPI_Tools.h>
17
18 #include <ModuleBase_ResultPrs.h>
19
20 #include <GeomAPI_Shape.h>
21 #include <GeomAPI_IPresentable.h>
22
23 #include <AIS_InteractiveContext.hxx>
24 #include <AIS_LocalContext.hxx>
25 #include <AIS_ListOfInteractive.hxx>
26 #include <AIS_ListIteratorOfListOfInteractive.hxx>
27 #include <AIS_DimensionSelectionMode.hxx>
28 #include <AIS_Shape.hxx>
29 #include <AIS_Dimension.hxx>
30 #include <TColStd_ListIteratorOfListOfInteger.hxx>
31 #include <SelectMgr_ListOfFilter.hxx>
32 #include <SelectMgr_ListIteratorOfListOfFilter.hxx>
33
34 #include <set>
35
36 const int MOUSE_SENSITIVITY_IN_PIXEL = 10;  ///< defines the local context mouse selection sensitivity
37
38 XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop)
39   : myUseExternalObjects(false), myWorkshop(theWorkshop)
40 {
41 }
42
43 XGUI_Displayer::~XGUI_Displayer()
44 {
45 }
46
47 bool XGUI_Displayer::isVisible(ObjectPtr theObject) const
48 {
49   return myResult2AISObjectMap.contains(theObject);
50 }
51
52 void XGUI_Displayer::display(ObjectPtr theObject, bool isUpdateViewer)
53 {
54   if (isVisible(theObject)) {
55     redisplay(theObject, isUpdateViewer);
56   } else {
57     AISObjectPtr anAIS;
58
59     GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
60     bool isShading = false;
61     if (aPrs) {
62       anAIS = aPrs->getAISObject(AISObjectPtr());
63     } else {
64       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
65       if (aResult) {
66         std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
67         if (aShapePtr) {
68           anAIS = AISObjectPtr(new GeomAPI_AISObject());
69           anAIS->setImpl(new Handle(AIS_InteractiveObject)(new ModuleBase_ResultPrs(aResult)));
70           //anAIS->createShape(aShapePtr);
71           isShading = true;
72         }
73       }
74     }
75     if (anAIS)
76       display(theObject, anAIS, isShading, isUpdateViewer);
77   }
78 }
79
80 void XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, 
81                              bool isShading, bool isUpdateViewer)
82 {
83   Handle(AIS_InteractiveContext) aContext = AISContext();
84   if (aContext.IsNull())
85     return;
86
87   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
88   if (!anAISIO.IsNull()) {
89     myResult2AISObjectMap[theObject] = theAIS;
90     aContext->Display(anAISIO, false);
91     aContext->SetDisplayMode(anAISIO, isShading? Shading : Wireframe, isUpdateViewer);
92     if (aContext->HasOpenedContext()) {
93       if (myUseExternalObjects) {
94         if (myActiveSelectionModes.size() == 0)
95           aContext->Activate(anAISIO);
96         else {
97           foreach(int aMode, myActiveSelectionModes) {
98             aContext->Activate(anAISIO, aMode);
99           }
100         }
101       }
102     }
103   }
104 }
105
106 void XGUI_Displayer::erase(ObjectPtr theObject, const bool isUpdateViewer)
107 {
108   if (!isVisible(theObject))
109     return;
110
111   Handle(AIS_InteractiveContext) aContext = AISContext();
112   if (aContext.IsNull())
113     return;
114   AISObjectPtr anObject = myResult2AISObjectMap[theObject];
115   if (anObject) {
116     Handle(AIS_InteractiveObject) anAIS = anObject->impl<Handle(AIS_InteractiveObject)>();
117     if (!anAIS.IsNull()) {
118       aContext->Remove(anAIS, isUpdateViewer);
119     }
120   }
121   myResult2AISObjectMap.remove(theObject);
122 }
123
124 void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer)
125 {
126   if (!isVisible(theObject))
127     return;
128
129   AISObjectPtr aAISObj = getAISObject(theObject);
130   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
131
132   GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
133   if (aPrs) {
134     AISObjectPtr aAIS_Obj = aPrs->getAISObject(aAISObj);
135     if (!aAIS_Obj) {
136       erase(theObject, isUpdateViewer);
137       return;
138     }
139     if (aAIS_Obj != aAISObj) {
140       myResult2AISObjectMap[theObject] = aAIS_Obj;
141     }
142     aAISIO = aAIS_Obj->impl<Handle(AIS_InteractiveObject)>();
143   }
144
145   if (!aAISIO.IsNull()) {
146     Handle(AIS_InteractiveContext) aContext = AISContext();
147     if (aContext.IsNull())
148       return;
149     aContext->Redisplay(aAISIO, isUpdateViewer);
150   }
151 }
152
153 void XGUI_Displayer::deactivate(ObjectPtr theObject)
154 {
155   if (isVisible(theObject)) {
156     Handle(AIS_InteractiveContext) aContext = AISContext();
157     if (aContext.IsNull())
158       return;
159
160     AISObjectPtr anObj = myResult2AISObjectMap[theObject];
161     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
162     aContext->Deactivate(anAIS);
163   }
164 }
165
166 void XGUI_Displayer::activate(ObjectPtr theFeature)
167 {
168   QIntList aModes;
169   activate(theFeature, aModes);
170 }
171
172 void XGUI_Displayer::activate(ObjectPtr theObject, const QIntList& theModes)
173 {
174   if (isVisible(theObject)) {
175     Handle(AIS_InteractiveContext) aContext = AISContext();
176     if (aContext.IsNull())
177       return;
178
179     AISObjectPtr anObj = myResult2AISObjectMap[theObject];
180     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
181     if (aContext->HasOpenedContext()) {
182       aContext->Load(anAIS, -1, true);
183     }
184     if (theModes.size() > 0) {
185       foreach(int aMode, theModes) {
186         aContext->Activate(anAIS, aMode);
187       }
188     } else 
189       aContext->Activate(anAIS);
190   }
191 }
192
193 bool XGUI_Displayer::isActive(ObjectPtr theObject) const
194 {
195   Handle(AIS_InteractiveContext) aContext = AISContext();
196   if (aContext.IsNull())
197     return false;
198   if (!isVisible(theObject))
199     return false;
200     
201   AISObjectPtr anObj = myResult2AISObjectMap[theObject];
202   Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
203
204   TColStd_ListOfInteger aModes;
205   aContext->ActivatedModes(anAIS, aModes);
206   return aModes.Extent() > 0;
207 }
208
209 void XGUI_Displayer::stopSelection(const QObjectPtrList& theResults, const bool isStop,
210                                    const bool isUpdateViewer)
211 {
212   Handle(AIS_InteractiveContext) aContext = AISContext();
213   if (aContext.IsNull())
214     return;
215
216   Handle(AIS_Shape) anAIS;
217   QObjectPtrList::const_iterator anIt = theResults.begin(), aLast = theResults.end();
218   ObjectPtr aFeature;
219   for (; anIt != aLast; anIt++) {
220     aFeature = *anIt;
221     if (isVisible(aFeature))
222       anAIS = Handle(AIS_Shape)::DownCast(
223           myResult2AISObjectMap[aFeature]->impl<Handle(AIS_InteractiveObject)>());
224     if (anAIS.IsNull())
225       continue;
226
227     if (isStop) {
228       QColor aColor(Qt::white);
229       anAIS->SetColor(
230           Quantity_Color(aColor.red() / 255., aColor.green() / 255., aColor.blue() / 255.,
231                          Quantity_TOC_RGB));
232       anAIS->Redisplay();
233     } else {
234       QColor aColor(Qt::red);
235       anAIS->SetColor(
236           Quantity_Color(aColor.red() / 255., aColor.green() / 255., aColor.blue() / 255.,
237                          Quantity_TOC_RGB));
238       anAIS->Redisplay();
239     }
240   }
241   if (isUpdateViewer)
242     updateViewer();
243 }
244
245 void XGUI_Displayer::setSelected(const QObjectPtrList& theResults, const bool isUpdateViewer)
246 {
247   Handle(AIS_InteractiveContext) aContext = AISContext();
248   if (aContext.IsNull())
249     return;
250   if (aContext->HasOpenedContext()) {
251     aContext->UnhilightSelected();
252     aContext->ClearSelected();
253     foreach(ObjectPtr aResult, theResults) {
254       if (isVisible(aResult)) {
255         AISObjectPtr anObj = myResult2AISObjectMap[aResult];
256         Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
257         if (!anAIS.IsNull())
258           aContext->SetSelected(anAIS, false);
259       }
260     }
261   } else {
262     aContext->UnhilightCurrents();
263     aContext->ClearCurrents();
264     foreach(ObjectPtr aResult, theResults) {
265       if (isVisible(aResult)) {
266         AISObjectPtr anObj = myResult2AISObjectMap[aResult];
267         Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
268         if (!anAIS.IsNull())
269           aContext->SetCurrentObject(anAIS, false);
270       }
271     }
272   }
273   if (isUpdateViewer)
274     updateViewer();
275 }
276
277
278 void XGUI_Displayer::clearSelected()
279 {
280   Handle(AIS_InteractiveContext) aContext = AISContext();
281   if (aContext) {
282     aContext->UnhilightCurrents(false);
283     aContext->ClearSelected();
284   }
285 }
286
287 void XGUI_Displayer::eraseAll(const bool isUpdateViewer)
288 {
289   Handle(AIS_InteractiveContext) aContext = AISContext();
290   if (aContext.IsNull())
291     return;
292
293    foreach (AISObjectPtr aAISObj, myResult2AISObjectMap) {
294      // erase an object
295      Handle(AIS_InteractiveObject) anIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
296      if (!anIO.IsNull())
297        aContext->Remove(anIO, false);
298    }
299    myResult2AISObjectMap.clear();
300    if (isUpdateViewer)
301      updateViewer();
302  }
303
304 void XGUI_Displayer::eraseDeletedResults(const bool isUpdateViewer)
305 {
306   Handle(AIS_InteractiveContext) aContext = AISContext();
307   if (aContext.IsNull())
308     return;
309
310   QObjectPtrList aRemoved;
311   foreach (ObjectPtr aFeature, myResult2AISObjectMap.keys()) {
312     if (!aFeature || !aFeature->data() || !aFeature->data()->isValid()) {
313       AISObjectPtr anObj = myResult2AISObjectMap[aFeature];
314       if (!anObj)
315         continue;
316       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
317       if (!anAIS.IsNull()) {
318         aContext->Remove(anAIS, false);
319         aRemoved.append(aFeature);
320       }
321     }
322   }
323   foreach(ObjectPtr aObj, aRemoved) {
324     myResult2AISObjectMap.remove(aObj);
325   }
326
327   if (isUpdateViewer)
328     updateViewer();
329 }
330
331 void XGUI_Displayer::openLocalContext()
332 {
333   Handle(AIS_InteractiveContext) aContext = AISContext();
334   if (aContext.IsNull())
335     return;
336   // Open local context if there is no one
337   if (!aContext->HasOpenedContext()) {
338     // Preserve selected objects
339     //AIS_ListOfInteractive aAisList;
340     //for (aContext->InitCurrent(); aContext->MoreCurrent(); aContext->NextCurrent())
341     //  aAisList.Append(aContext->Current());
342
343     // get the filters from the global context and append them to the local context
344     // a list of filters in the global context is not cleared and should be cleared here
345     SelectMgr_ListOfFilter aFilters;
346     aFilters.Assign(aContext->Filters());
347     // it is important to remove the filters in the global context, because there is a code
348     // in the closeLocalContex, which restore the global context filters
349     aContext->RemoveFilters();
350
351     aContext->ClearCurrents();
352     aContext->OpenLocalContext();
353     aContext->NotUseDisplayedObjects();
354
355     myUseExternalObjects = false;
356     myActiveSelectionModes.clear();
357
358     SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
359     for (;aIt.More(); aIt.Next()) {
360       aContext->AddFilter(aIt.Value());
361     }
362     // Restore selection
363     //AIS_ListIteratorOfListOfInteractive aIt2(aAisList);
364     //for(; aIt2.More(); aIt2.Next()) {
365     //  aContext->SetSelected(aIt2.Value(), false);
366     //}
367   }
368 }
369
370 void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer)
371 {
372   Handle(AIS_InteractiveContext) aContext = AISContext();
373   if ( (!aContext.IsNull()) && (aContext->HasOpenedContext()) ) {
374     // Preserve selected objects
375     //AIS_ListOfInteractive aAisList;
376     //for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected())
377     //  aAisList.Append(aContext->SelectedInteractive());
378
379     // get the filters from the local context and append them to the global context
380     // a list of filters in the local context is cleared
381     SelectMgr_ListOfFilter aFilters;
382     aFilters.Assign(aContext->Filters());
383
384     aContext->ClearSelected();
385     aContext->CloseAllContexts(false);
386
387     // Redisplay all object if they were displayed in localContext
388     Handle(AIS_InteractiveObject) aAISIO;
389     foreach (AISObjectPtr aAIS, myResult2AISObjectMap) {
390       aAISIO = aAIS->impl<Handle(AIS_InteractiveObject)>();
391       if (aContext->DisplayStatus(aAISIO) != AIS_DS_Displayed) {
392         aContext->Display(aAISIO, false);
393         aContext->SetDisplayMode(aAISIO, Shading, false);
394       }
395     }
396
397     // Append the filters from the local selection in the global selection context
398     SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
399     for (;aIt.More(); aIt.Next()) {
400       Handle(SelectMgr_Filter) aFilter = aIt.Value();
401       aContext->AddFilter(aFilter);
402     }
403
404     if (isUpdateViewer)
405       updateViewer();
406     myUseExternalObjects = false;
407     myActiveSelectionModes.clear();
408
409     // Restore selection
410     //AIS_ListIteratorOfListOfInteractive aIt2(aAisList);
411     //for(; aIt2.More(); aIt2.Next()) {
412     //  if (aContext->IsDisplayed(aIt2.Value()))
413     //    aContext->SetCurrentObject(aIt2.Value(), false);
414     //}
415   }
416 }
417
418 AISObjectPtr XGUI_Displayer::getAISObject(ObjectPtr theObject) const
419 {
420   AISObjectPtr anIO;
421   if (myResult2AISObjectMap.contains(theObject))
422     anIO = myResult2AISObjectMap[theObject];
423   return anIO;
424 }
425
426 ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const
427 {
428   Handle(AIS_InteractiveObject) aRefAIS = theIO->impl<Handle(AIS_InteractiveObject)>();
429   return getObject(aRefAIS);
430 }
431
432 ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const
433 {
434   ObjectPtr aFeature;
435   foreach (ObjectPtr anObj, myResult2AISObjectMap.keys()) {
436     AISObjectPtr aAIS = myResult2AISObjectMap[anObj];
437     Handle(AIS_InteractiveObject) anAIS = aAIS->impl<Handle(AIS_InteractiveObject)>();
438     if (anAIS == theIO)
439       return anObj;
440   }
441   return aFeature;
442 }
443
444 void XGUI_Displayer::updateViewer()
445 {
446   Handle(AIS_InteractiveContext) aContext = AISContext();
447   if (!aContext.IsNull())
448     aContext->UpdateCurrentViewer();
449 }
450
451 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
452 {
453   return myWorkshop->viewer()->AISContext();
454 }
455
456 Handle(SelectMgr_AndFilter) XGUI_Displayer::GetFilter()
457 {
458   Handle(AIS_InteractiveContext) aContext = AISContext();
459   if (myAndFilter.IsNull() && !aContext.IsNull()) {
460     myAndFilter = new SelectMgr_AndFilter();
461     aContext->AddFilter(myAndFilter);
462   }
463   return myAndFilter;
464 }
465
466 void XGUI_Displayer::displayAIS(AISObjectPtr theAIS, bool isUpdate)
467 {
468   Handle(AIS_InteractiveContext) aContext = AISContext();
469   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
470   if (!anAISIO.IsNull()) {
471     aContext->Display(anAISIO, isUpdate);
472     if (aContext->HasOpenedContext()) {
473       if (myUseExternalObjects) {
474         if (myActiveSelectionModes.size() == 0)
475           aContext->Activate(anAISIO);
476         else {
477           foreach(int aMode, myActiveSelectionModes) {
478             aContext->Activate(anAISIO, aMode);
479           }
480         }
481       }
482     }
483   }
484 }
485
486 void XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool isUpdate)
487 {
488   Handle(AIS_InteractiveContext) aContext = AISContext();
489   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
490   if (!anAISIO.IsNull()) {
491     aContext->Remove(anAISIO, isUpdate);
492   }
493 }
494
495 void XGUI_Displayer::activateObjects(const QIntList& theModes)
496 {
497   Handle(AIS_InteractiveContext) aContext = AISContext();
498   // Open local context if there is no one
499   if (!aContext->HasOpenedContext()) 
500     return;
501
502   aContext->UseDisplayedObjects();
503   myUseExternalObjects = true;
504   myActiveSelectionModes = theModes;
505
506   //Deactivate trihedron which can be activated in local selector
507   AIS_ListOfInteractive aPrsList;
508   aContext->DisplayedObjects(aPrsList, true);
509
510   Handle(AIS_Trihedron) aTrihedron;
511   AIS_ListIteratorOfListOfInteractive aLIt(aPrsList);
512   for(; aLIt.More(); aLIt.Next()){
513     aTrihedron = Handle(AIS_Trihedron)::DownCast(aLIt.Value());
514     if (!aTrihedron.IsNull()) {
515       aContext->Deactivate(aTrihedron);
516       break;
517     }
518   }
519
520   //Activate all displayed objects with the module modes
521   //AIS_ListOfInteractive aPrsList;
522   //aContext->DisplayedObjects(aPrsList, true);
523
524   //AIS_ListIteratorOfListOfInteractive aLIt(aPrsList);
525   Handle(AIS_InteractiveObject) anAISIO;
526   for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){
527     anAISIO = aLIt.Value();
528     aTrihedron = Handle(AIS_Trihedron)::DownCast(anAISIO);
529     if (!aTrihedron.IsNull())
530       continue;
531
532     aContext->Load(anAISIO, -1, true);
533     if (theModes.size() == 0)
534       aContext->Activate(anAISIO);
535     else {
536       foreach(int aMode, theModes) {
537         aContext->Activate(anAISIO, aMode);
538       }
539     }
540   }
541 }
542
543
544 void XGUI_Displayer::deactivateObjects()
545 {
546   Handle(AIS_InteractiveContext) aContext = AISContext();
547   // Open local context if there is no one
548   if (!aContext->HasOpenedContext()) 
549     return;
550
551   aContext->NotUseDisplayedObjects();
552 }
553
554
555 void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool toUpdate)
556 {
557   if (theMode == NoMode)
558     return;
559
560   Handle(AIS_InteractiveContext) aContext = AISContext();
561   if (aContext.IsNull())
562     return;
563
564   AISObjectPtr aAISObj = getAISObject(theObject);
565   if (!aAISObj)
566     return;
567
568   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
569   aContext->SetDisplayMode(aAISIO, theMode, toUpdate);
570 }
571
572 XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const
573 {
574   Handle(AIS_InteractiveContext) aContext = AISContext();
575   if (aContext.IsNull())
576     return NoMode;
577
578   AISObjectPtr aAISObj = getAISObject(theObject);
579   if (!aAISObj)
580     return NoMode;
581
582   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
583   return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode();
584 }
585
586 void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
587 {
588   Handle(AIS_InteractiveContext) aContext = AISContext();
589   if (aContext.IsNull())
590     return;
591   const SelectMgr_ListOfFilter& aFilters = aContext->Filters();
592   SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
593   for (; aIt.More(); aIt.Next()) {
594     if (theFilter.Access() == aIt.Value().Access())
595       return;
596   }
597   GetFilter()->Add(theFilter);
598 }
599
600 void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
601 {
602   Handle(AIS_InteractiveContext) aContext = AISContext();
603   if (aContext.IsNull())
604     return;
605   GetFilter()->Remove(theFilter);
606 }
607
608 void XGUI_Displayer::removeFilters()
609 {
610   Handle(AIS_InteractiveContext) aContext = AISContext();
611   if (aContext.IsNull())
612     return;
613   GetFilter()->Clear();
614 }
615
616 void XGUI_Displayer::showOnly(const QObjectPtrList& theList)
617 {
618   QObjectPtrList aDispList = myResult2AISObjectMap.keys();
619   foreach(ObjectPtr aObj, aDispList) {
620     if (!theList.contains(aObj))
621       erase(aObj, false);
622   }
623   foreach(ObjectPtr aObj, theList) {
624     if (!isVisible(aObj))
625       display(aObj, false);
626   }
627   updateViewer();
628 }