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