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