Salome HOME
Redisplay objects after closing interactive context. Activate/Deactivate widget metho...
[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 theObject, const QIntList& theModes)
164 {
165   if (isVisible(theObject)) {
166     Handle(AIS_InteractiveContext) aContext = AISContext();
167     if (aContext.IsNull())
168       return;
169
170     AISObjectPtr anObj = myResult2AISObjectMap[theObject];
171     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
172     if (aContext->HasOpenedContext()) {
173       aContext->Load(anAIS, -1, true);
174     }
175     if (theModes.size() > 0) {
176       foreach(int aMode, theModes) {
177         aContext->Activate(anAIS, aMode);
178       }
179     } else 
180       aContext->Activate(anAIS);
181   }
182 }
183
184 bool XGUI_Displayer::isActive(ObjectPtr theObject) const
185 {
186   Handle(AIS_InteractiveContext) aContext = AISContext();
187   if (aContext.IsNull())
188     return false;
189   if (!isVisible(theObject))
190     return false;
191     
192   AISObjectPtr anObj = myResult2AISObjectMap[theObject];
193   Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
194
195   TColStd_ListOfInteger aModes;
196   aContext->ActivatedModes(anAIS, aModes);
197   return aModes.Extent() > 0;
198 }
199
200 void XGUI_Displayer::stopSelection(const QList<ObjectPtr>& theResults, const bool isStop,
201                                    const bool isUpdateViewer)
202 {
203   Handle(AIS_InteractiveContext) aContext = AISContext();
204   if (aContext.IsNull())
205     return;
206
207   Handle(AIS_Shape) anAIS;
208   QList<ObjectPtr>::const_iterator anIt = theResults.begin(), aLast = theResults.end();
209   ObjectPtr aFeature;
210   for (; anIt != aLast; anIt++) {
211     aFeature = *anIt;
212     if (isVisible(aFeature))
213       anAIS = Handle(AIS_Shape)::DownCast(
214           myResult2AISObjectMap[aFeature]->impl<Handle(AIS_InteractiveObject)>());
215     if (anAIS.IsNull())
216       continue;
217
218     if (isStop) {
219       QColor aColor(Qt::white);
220       anAIS->SetColor(
221           Quantity_Color(aColor.red() / 255., aColor.green() / 255., aColor.blue() / 255.,
222                          Quantity_TOC_RGB));
223       anAIS->Redisplay();
224     } else {
225       QColor aColor(Qt::red);
226       anAIS->SetColor(
227           Quantity_Color(aColor.red() / 255., aColor.green() / 255., aColor.blue() / 255.,
228                          Quantity_TOC_RGB));
229       anAIS->Redisplay();
230     }
231   }
232   if (isUpdateViewer)
233     updateViewer();
234 }
235
236 void XGUI_Displayer::setSelected(const QList<ObjectPtr>& theResults, const bool isUpdateViewer)
237 {
238   Handle(AIS_InteractiveContext) aContext = AISContext();
239   // we need to unhighligth objects manually in the current local context
240   // in couple with the selection clear (TODO)
241   Handle(AIS_LocalContext) aLocalContext = aContext->LocalContext();
242   if (!aLocalContext.IsNull())
243     aLocalContext->UnhilightLastDetected(myWorkshop->viewer()->activeView());
244
245   aContext->ClearSelected();
246   foreach(ObjectPtr aResult, theResults)
247   {
248     if (isVisible(aResult)) {
249       AISObjectPtr anObj = myResult2AISObjectMap[aResult];
250       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
251       if (!anAIS.IsNull())
252         aContext->SetSelected(anAIS, false);
253     }
254   }
255   if (isUpdateViewer)
256     updateViewer();
257 }
258
259
260 void XGUI_Displayer::clearSelected()
261 {
262   Handle(AIS_InteractiveContext) aContext = AISContext();
263   if (aContext) {
264     aContext->UnhilightCurrents(false);
265     aContext->ClearSelected();
266   }
267 }
268
269 void XGUI_Displayer::eraseAll(const bool isUpdateViewer)
270 {
271   Handle(AIS_InteractiveContext) ic = AISContext();
272   if (ic.IsNull())
273     return;
274
275    foreach (AISObjectPtr aAISObj, myResult2AISObjectMap) {
276      // erase an object
277      Handle(AIS_InteractiveObject) anIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
278      if (!anIO.IsNull())
279        ic->Remove(anIO, false);
280    }
281    myResult2AISObjectMap.clear();
282    if (isUpdateViewer)
283      updateViewer();
284  }
285
286 void XGUI_Displayer::eraseDeletedResults(const bool isUpdateViewer)
287 {
288   Handle(AIS_InteractiveContext) aContext = AISContext();
289   if (aContext.IsNull())
290     return;
291
292   QList<ObjectPtr> aRemoved;
293   foreach (ObjectPtr aFeature, myResult2AISObjectMap.keys()) {
294     if (!aFeature || !aFeature->data() || !aFeature->data()->isValid()) {
295       AISObjectPtr anObj = myResult2AISObjectMap[aFeature];
296       if (!anObj)
297         continue;
298       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
299       if (!anAIS.IsNull()) {
300         aContext->Remove(anAIS, false);
301         aRemoved.append(aFeature);
302       }
303     }
304   }
305   foreach(ObjectPtr aObj, aRemoved) {
306     myResult2AISObjectMap.remove(aObj);
307   }
308
309   if (isUpdateViewer)
310     updateViewer();
311 }
312
313 void XGUI_Displayer::openLocalContext()
314 {
315   Handle(AIS_InteractiveContext) aContext = AISContext();
316   if (aContext.IsNull())
317     return;
318   // Open local context if there is no one
319   if (!aContext->HasOpenedContext()) {
320     aContext->ClearCurrents(false);
321     //aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
322     aContext->OpenLocalContext();
323     aContext->NotUseDisplayedObjects();
324
325     myUseExternalObjects = false;
326     myActiveSelectionModes.clear();
327   }
328 }
329
330 void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer)
331 {
332   Handle(AIS_InteractiveContext) ic = AISContext();
333   if ( (!ic.IsNull()) && (ic->HasOpenedContext()) ) {
334     ic->ClearSelected(false);
335     ic->CloseAllContexts(false);
336
337     // Redisplay all object if they were displayed in localContext
338     Handle(AIS_InteractiveObject) aAISIO;
339     foreach (AISObjectPtr aAIS, myResult2AISObjectMap) {
340       aAISIO = aAIS->impl<Handle(AIS_InteractiveObject)>();
341       if (ic->DisplayStatus(aAISIO) != AIS_DS_Displayed) {
342         ic->Display(aAISIO, false);
343         ic->SetDisplayMode(aAISIO, Shading, false);
344       }
345     }
346     if (isUpdateViewer)
347       updateViewer();
348     myUseExternalObjects = false;
349     myActiveSelectionModes.clear();
350   }
351 }
352
353 AISObjectPtr XGUI_Displayer::getAISObject(ObjectPtr theObject) const
354 {
355   AISObjectPtr anIO;
356   if (myResult2AISObjectMap.contains(theObject))
357     anIO = myResult2AISObjectMap[theObject];
358   return anIO;
359 }
360
361 ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const
362 {
363   Handle(AIS_InteractiveObject) aRefAIS = theIO->impl<Handle(AIS_InteractiveObject)>();
364   return getObject(aRefAIS);
365 }
366
367 ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const
368 {
369   ObjectPtr aFeature;
370   foreach (ObjectPtr anObj, myResult2AISObjectMap.keys()) {
371     AISObjectPtr aAIS = myResult2AISObjectMap[anObj];
372     Handle(AIS_InteractiveObject) anAIS = aAIS->impl<Handle(AIS_InteractiveObject)>();
373     if (anAIS == theIO)
374       return anObj;
375   }
376   return aFeature;
377 }
378
379 void XGUI_Displayer::updateViewer()
380 {
381   Handle(AIS_InteractiveContext) ic = AISContext();
382   if (!ic.IsNull())
383     ic->UpdateCurrentViewer();
384 }
385
386 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
387 {
388   return myWorkshop->viewer()->AISContext();
389 }
390
391 void XGUI_Displayer::displayAIS(AISObjectPtr theAIS, bool isUpdate)
392 {
393   Handle(AIS_InteractiveContext) aContext = AISContext();
394   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
395   if (!anAISIO.IsNull()) {
396     aContext->Display(anAISIO, isUpdate);
397     if (aContext->HasOpenedContext()) {
398       if (myUseExternalObjects) {
399         if (myActiveSelectionModes.size() == 0)
400           aContext->Activate(anAISIO);
401         else {
402           foreach(int aMode, myActiveSelectionModes) {
403             aContext->Activate(anAISIO, aMode);
404           }
405         }
406       }
407     }
408   }
409 }
410
411 void XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool isUpdate)
412 {
413   Handle(AIS_InteractiveContext) aContext = AISContext();
414   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
415   if (!anAISIO.IsNull()) {
416     aContext->Remove(anAISIO, isUpdate);
417   }
418 }
419
420 void XGUI_Displayer::activateObjectsOutOfContext(const QIntList& theModes)
421 {
422   Handle(AIS_InteractiveContext) aContext = AISContext();
423   // Open local context if there is no one
424   if (!aContext->HasOpenedContext()) 
425     return;
426
427   aContext->UseDisplayedObjects();
428   myUseExternalObjects = true;
429   myActiveSelectionModes = theModes;
430
431   //Deactivate trihedron which can be activated in local selector
432   AIS_ListOfInteractive aPrsList;
433   aContext->DisplayedObjects(aPrsList, true);
434
435   Handle(AIS_Trihedron) aTrihedron;
436   AIS_ListIteratorOfListOfInteractive aLIt(aPrsList);
437   for(; aLIt.More(); aLIt.Next()){
438     aTrihedron = Handle(AIS_Trihedron)::DownCast(aLIt.Value());
439     if (!aTrihedron.IsNull()) {
440       aContext->Deactivate(aTrihedron);
441       break;
442     }
443   }
444
445   Handle(AIS_InteractiveObject) anAISIO;
446   foreach (AISObjectPtr aAIS, myResult2AISObjectMap) {
447   anAISIO = aAIS->impl<Handle(AIS_InteractiveObject)>();
448     aContext->Load(anAISIO, -1, true);
449     if (theModes.size() == 0)
450       aContext->Activate(anAISIO);
451     else {
452       foreach(int aMode, theModes) {
453         aContext->Activate(anAISIO, aMode);
454       }
455     }
456   }
457 }
458
459
460 void XGUI_Displayer::deactivateObjectsOutOfContext()
461 {
462   Handle(AIS_InteractiveContext) aContext = AISContext();
463   // Open local context if there is no one
464   if (!aContext->HasOpenedContext()) 
465     return;
466
467   aContext->NotUseDisplayedObjects();
468 }
469
470
471 void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool toUpdate)
472 {
473   if (theMode == NoMode)
474     return;
475
476   Handle(AIS_InteractiveContext) aContext = AISContext();
477   if (aContext.IsNull())
478     return;
479
480   AISObjectPtr aAISObj = getAISObject(theObject);
481   if (!aAISObj)
482     return;
483
484   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
485   aContext->SetDisplayMode(aAISIO, theMode, toUpdate);
486 }
487
488 void XGUI_Displayer::setSelectionModes(const QIntList& theModes)
489 {
490   Handle(AIS_InteractiveContext) aContext = AISContext();
491   if (aContext.IsNull())
492     return;
493   if (!aContext->HasOpenedContext())
494     return;
495   // Clear previous mode
496   const TColStd_ListOfInteger& aModes = aContext->ActivatedStandardModes();
497   if (!aModes.IsEmpty()) {
498     TColStd_ListOfInteger aMModes;
499     aMModes.Assign(aModes);
500     TColStd_ListIteratorOfListOfInteger it(aMModes);
501     for(; it.More(); it.Next()) {
502       aContext->DeactivateStandardMode((TopAbs_ShapeEnum)it.Value());
503     }
504   }
505   foreach(int aMode, theModes) {
506     aContext->ActivateStandardMode((TopAbs_ShapeEnum)aMode);
507   }
508 }
509
510 XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const
511 {
512   Handle(AIS_InteractiveContext) aContext = AISContext();
513   if (aContext.IsNull())
514     return NoMode;
515
516   AISObjectPtr aAISObj = getAISObject(theObject);
517   if (!aAISObj)
518     return NoMode;
519
520   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
521   return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode();
522 }
523
524 void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
525 {
526   Handle(AIS_InteractiveContext) aContext = AISContext();
527   if (aContext.IsNull())
528     return;
529   const SelectMgr_ListOfFilter& aFilters = aContext->Filters();
530   SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
531   for (; aIt.More(); aIt.Next()) {
532     if (theFilter.Access() == aIt.Value().Access())
533       return;
534   }
535   aContext->AddFilter(theFilter);
536 }
537
538 void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
539 {
540   Handle(AIS_InteractiveContext) aContext = AISContext();
541   if (aContext.IsNull())
542     return;
543   aContext->RemoveFilter(theFilter);
544 }