Salome HOME
Make the application compiliable and executable on Linux with SALOME environment:
[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 <GeomAPI_Shape.h>
16 #include <GeomAPI_IPresentable.h>
17
18 #include <AIS_InteractiveContext.hxx>
19 #include <AIS_LocalContext.hxx>
20 #include <AIS_ListOfInteractive.hxx>
21 #include <AIS_ListIteratorOfListOfInteractive.hxx>
22 #include <AIS_DimensionSelectionMode.hxx>
23 #include <AIS_Shape.hxx>
24
25 #include <set>
26
27 const int MOUSE_SENSITIVITY_IN_PIXEL = 10;  ///< defines the local context mouse selection sensitivity
28
29 XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop)
30 {
31   myWorkshop = theWorkshop;
32 }
33
34 XGUI_Displayer::~XGUI_Displayer()
35 {
36 }
37
38 bool XGUI_Displayer::isVisible(ObjectPtr theObject)
39 {
40   return myResult2AISObjectMap.find(theObject) != myResult2AISObjectMap.end();
41 }
42
43 void XGUI_Displayer::display(ObjectPtr theObject, bool isUpdateViewer)
44 {
45   if (isVisible(theObject)) {
46     redisplay(theObject, isUpdateViewer);
47   } else {
48     boost::shared_ptr<GeomAPI_AISObject> anAIS;
49
50     GeomPresentablePtr aPrs = boost::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
51     if (aPrs) {
52       anAIS = aPrs->getAISObject(boost::shared_ptr<GeomAPI_AISObject>());
53     } else {
54       ResultPtr aResult = boost::dynamic_pointer_cast<ModelAPI_Result>(theObject);
55       if (aResult) {
56         boost::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
57         if (aShapePtr) {
58           anAIS = boost::shared_ptr<GeomAPI_AISObject>(new GeomAPI_AISObject());
59           anAIS->createShape(aShapePtr);
60         }
61       }
62     }
63     if (anAIS)
64       display(theObject, anAIS, isUpdateViewer);
65   }
66 }
67
68 void XGUI_Displayer::display(ObjectPtr theObject, boost::shared_ptr<GeomAPI_AISObject> theAIS,
69                              bool isUpdateViewer)
70 {
71   Handle(AIS_InteractiveContext) aContext = AISContext();
72
73   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
74   if (!anAISIO.IsNull()) {
75     myResult2AISObjectMap[theObject] = theAIS;
76     aContext->Display(anAISIO, isUpdateViewer);
77   }
78 }
79
80 void XGUI_Displayer::erase(ObjectPtr theObject, const bool isUpdateViewer)
81 {
82   if (!isVisible(theObject))
83     return;
84
85   Handle(AIS_InteractiveContext) aContext = AISContext();
86   boost::shared_ptr<GeomAPI_AISObject> anObject = myResult2AISObjectMap[theObject];
87   if (anObject) {
88     Handle(AIS_InteractiveObject) anAIS = anObject->impl<Handle(AIS_InteractiveObject)>();
89     if (!anAIS.IsNull()) {
90       aContext->Remove(anAIS, isUpdateViewer);
91     }
92   }
93   myResult2AISObjectMap.erase(theObject);
94 }
95
96 /*bool XGUI_Displayer::redisplay(ObjectPtr theObject,
97  boost::shared_ptr<GeomAPI_AISObject> theAIS,
98  const bool isUpdateViewer)
99  {
100  bool isCreated = false;
101  Handle(AIS_InteractiveObject) anAIS = 
102  theAIS ? theAIS->impl<Handle(AIS_InteractiveObject)>() : Handle(AIS_InteractiveObject)();
103  Handle(AIS_InteractiveContext) aContext = AISContext();
104  // Open local context if there is no one
105  if (!aContext->HasOpenedContext()) {
106  aContext->ClearCurrents(false);
107  aContext->OpenLocalContext(false /use displayed objects/, true /allow shape decomposition/);
108  // set mouse sensitivity
109  //aContext->SetSensitivityMode(StdSelect_SM_WINDOW);
110  //aContext->SetPixelTolerance(MOUSE_SENSITIVITY_IN_PIXEL);
111  }
112  // display or redisplay presentation
113  boost::shared_ptr<GeomAPI_AISObject> anObj = myResult2AISObjectMap[theObject];
114  if (isVisible(theObject) && anObj && !anObj->empty()) {
115  aContext->Redisplay(anAIS, isUpdateViewer);
116  //aContext->RecomputeSelectionOnly(anAIS);
117  }
118  else {
119  myResult2AISObjectMap[theObject] = theAIS;
120  aContext->Display(anAIS, isUpdateViewer);
121  isCreated = true;
122  }
123  return isCreated;
124  }*/
125
126 void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer)
127 {
128   if (!isVisible(theObject))
129     return;
130
131   Handle(AIS_InteractiveObject) aAISIO;
132   boost::shared_ptr<GeomAPI_AISObject> aAISObj = getAISObject(theObject);
133   GeomPresentablePtr aPrs = boost::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
134   if (aPrs) {
135     boost::shared_ptr<GeomAPI_AISObject> aAIS_Obj = aPrs->getAISObject(aAISObj);
136     if (aAISObj && !aAIS_Obj) {
137       erase(theObject, isUpdateViewer);
138       return;
139     }
140     aAISIO = aAIS_Obj->impl<Handle(AIS_InteractiveObject)>();
141   } else {
142     ResultPtr aResult = boost::dynamic_pointer_cast<ModelAPI_Result>(theObject);
143     if (aResult) {
144       boost::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
145       if (aShapePtr) {
146         Handle(AIS_Shape) aAISShape = Handle(AIS_Shape)::DownCast(
147             aAISObj->impl<Handle(AIS_InteractiveObject)>());
148         if (!aAISShape.IsNull()) {
149           aAISShape->Set(aShapePtr->impl<TopoDS_Shape>());
150           aAISIO = aAISShape;
151         }
152       }
153     }
154   }
155   if (!aAISIO.IsNull()) {
156     Handle(AIS_InteractiveContext) aContext = AISContext();
157     aContext->Redisplay(aAISIO, isUpdateViewer);
158     //if (aContext->HasOpenedContext()) {
159     //  aContext->Load(aAISIO, -1, true/*allow decomposition*/);
160     //}
161   }
162 }
163
164 void XGUI_Displayer::activateInLocalContext(ObjectPtr theResult, const std::list<int>& theModes,
165                                             const bool isUpdateViewer)
166 {
167   Handle(AIS_InteractiveContext) aContext = AISContext();
168   // Open local context if there is no one
169   if (!aContext->HasOpenedContext()) {
170     aContext->ClearCurrents(false);
171     //aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
172     aContext->OpenLocalContext();
173     aContext->NotUseDisplayedObjects();
174   }
175   // display or redisplay presentation
176   Handle(AIS_InteractiveObject) anAIS;
177   if (isVisible(theResult)) {
178     boost::shared_ptr<GeomAPI_AISObject> anObj = myResult2AISObjectMap[theResult];
179     if (anObj)
180       anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
181   }
182
183   // Activate selection of objects from prs
184   if (!anAIS.IsNull()) {
185     aContext->ClearSelected(false);  // ToCheck
186     //aContext->upClearSelected(false); // ToCheck
187     aContext->Load(anAIS, -1, true/*allow decomposition*/);
188     aContext->Deactivate(anAIS);
189
190     std::list<int>::const_iterator anIt = theModes.begin(), aLast = theModes.end();
191     for (; anIt != aLast; anIt++) {
192       aContext->Activate(anAIS, (*anIt));
193     }
194   }
195
196   if (isUpdateViewer)
197     updateViewer();
198 }
199
200 void XGUI_Displayer::deactivate(ObjectPtr theObject)
201 {
202   if (isVisible(theObject)) {
203     Handle(AIS_InteractiveContext) aContext = AISContext();
204
205     boost::shared_ptr<GeomAPI_AISObject> anObj = myResult2AISObjectMap[theObject];
206     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
207     aContext->Deactivate(anAIS);
208   }
209 }
210
211 void XGUI_Displayer::activate(ObjectPtr theObject)
212 {
213   if (isVisible(theObject)) {
214     Handle(AIS_InteractiveContext) aContext = AISContext();
215
216     boost::shared_ptr<GeomAPI_AISObject> anObj = myResult2AISObjectMap[theObject];
217     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
218     aContext->Activate(anAIS);
219   }
220 }
221
222 void XGUI_Displayer::stopSelection(const QList<ObjectPtr>& theResults, const bool isStop,
223                                    const bool isUpdateViewer)
224 {
225   Handle(AIS_InteractiveContext) aContext = AISContext();
226
227   Handle(AIS_Shape) anAIS;
228   QList<ObjectPtr>::const_iterator anIt = theResults.begin(), aLast = theResults.end();
229   ObjectPtr aFeature;
230   for (; anIt != aLast; anIt++) {
231     aFeature = *anIt;
232     if (isVisible(aFeature))
233       anAIS = Handle(AIS_Shape)::DownCast(
234           myResult2AISObjectMap[aFeature]->impl<Handle(AIS_InteractiveObject)>());
235     if (anAIS.IsNull())
236       continue;
237
238     if (isStop) {
239       QColor aColor(Qt::white);
240       anAIS->SetColor(
241           Quantity_Color(aColor.red() / 255., aColor.green() / 255., aColor.blue() / 255.,
242                          Quantity_TOC_RGB));
243       anAIS->Redisplay();
244     } else {
245       QColor aColor(Qt::red);
246       anAIS->SetColor(
247           Quantity_Color(aColor.red() / 255., aColor.green() / 255., aColor.blue() / 255.,
248                          Quantity_TOC_RGB));
249       anAIS->Redisplay();
250     }
251   }
252   if (isUpdateViewer)
253     updateViewer();
254 }
255
256 void XGUI_Displayer::setSelected(const QList<ObjectPtr>& theResults, const bool isUpdateViewer)
257 {
258   Handle(AIS_InteractiveContext) aContext = AISContext();
259   // we need to unhighligth objects manually in the current local context
260   // in couple with the selection clear (TODO)
261   Handle(AIS_LocalContext) aLocalContext = aContext->LocalContext();
262   if (!aLocalContext.IsNull())
263     aLocalContext->UnhilightLastDetected(myWorkshop->viewer()->activeView());
264
265   aContext->ClearSelected();
266   foreach(ObjectPtr aResult, theResults)
267   {
268     if (myResult2AISObjectMap.find(aResult) == myResult2AISObjectMap.end())
269       continue;
270
271     boost::shared_ptr<GeomAPI_AISObject> anObj = myResult2AISObjectMap[aResult];
272     if (anObj) {
273       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
274       if (!anAIS.IsNull())
275         aContext->AddOrRemoveSelected(anAIS, false);
276     }
277   }
278   if (isUpdateViewer)
279     updateViewer();
280 }
281
282 /*void XGUI_Displayer::EraseAll(const bool isUpdateViewer)
283  {
284  Handle(AIS_InteractiveContext) ic = AISContext();
285
286  AIS_ListOfInteractive aList;
287  ic->DisplayedObjects(aList);
288  AIS_ListIteratorOfListOfInteractive anIter(aList);
289  for (; anIter.More(); anIter.Next()) {
290  if ((anIter.Value()->DynamicType() == STANDARD_TYPE(AIS_Trihedron)))
291  continue;
292
293  // erase an object
294  Handle(AIS_InteractiveObject) anIO = anIter.Value();
295  ic->Erase(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
306   ResultToAISMap::const_iterator aFIt = myResult2AISObjectMap.begin(), aFLast =
307       myResult2AISObjectMap.end();
308   std::list<ObjectPtr> aRemoved;
309   for (; aFIt != aFLast; aFIt++) {
310     ObjectPtr aFeature = (*aFIt).first;
311     if (!aFeature || !aFeature->data() || !aFeature->data()->isValid()) {
312       boost::shared_ptr<GeomAPI_AISObject> anObj = (*aFIt).second;
313       if (!anObj)
314         continue;
315       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
316       if (!anAIS.IsNull()) {
317         aContext->Remove(anAIS, false);
318         aRemoved.push_back(aFeature);
319       }
320     }
321   }
322   std::list<ObjectPtr>::const_iterator anIt = aRemoved.begin(), aLast = aRemoved.end();
323   for (; anIt != aLast; anIt++) {
324     myResult2AISObjectMap.erase(myResult2AISObjectMap.find(*anIt));
325   }
326
327   if (isUpdateViewer)
328     updateViewer();
329 }
330
331 void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer)
332 {
333   AISContext()->ClearSelected(false);
334   closeAllContexts(true);
335 }
336
337 boost::shared_ptr<GeomAPI_AISObject> XGUI_Displayer::getAISObject(ObjectPtr theObject) const
338 {
339   boost::shared_ptr<GeomAPI_AISObject> anIO;
340   if (myResult2AISObjectMap.find(theObject) != myResult2AISObjectMap.end())
341     anIO = (myResult2AISObjectMap.find(theObject))->second;
342   return anIO;
343 }
344
345 ObjectPtr XGUI_Displayer::getObject(Handle(AIS_InteractiveObject) theIO) const
346 {
347   ObjectPtr aFeature;
348   ResultToAISMap::const_iterator aFIt = myResult2AISObjectMap.begin(), aFLast =
349       myResult2AISObjectMap.end();
350   for (; aFIt != aFLast && !aFeature; aFIt++) {
351     boost::shared_ptr<GeomAPI_AISObject> anObj = (*aFIt).second;
352     if (!anObj)
353       continue;
354     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
355     if (anAIS != theIO)
356       continue;
357     aFeature = (*aFIt).first;
358   }
359   return aFeature;
360 }
361
362 void XGUI_Displayer::closeAllContexts(const bool isUpdateViewer)
363 {
364   Handle(AIS_InteractiveContext) ic = AISContext();
365   if (!ic.IsNull()) {
366     ic->CloseAllContexts(false);
367     if (isUpdateViewer)
368       updateViewer();
369   }
370 }
371
372 void XGUI_Displayer::updateViewer()
373 {
374   Handle(AIS_InteractiveContext) ic = AISContext();
375   if (!ic.IsNull())
376     ic->UpdateCurrentViewer();
377 }
378
379 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
380 {
381   return myWorkshop->viewer()->AISContext();
382 }
383
384 void XGUI_Displayer::display(boost::shared_ptr<GeomAPI_AISObject> theAIS, bool isUpdate)
385 {
386   Handle(AIS_InteractiveContext) aContext = AISContext();
387   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
388   if (!anAISIO.IsNull())
389     aContext->Display(anAISIO, isUpdate);
390 }
391
392 void XGUI_Displayer::erase(boost::shared_ptr<GeomAPI_AISObject> theAIS, const bool isUpdate)
393 {
394   Handle(AIS_InteractiveContext) aContext = AISContext();
395   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
396   if (!anAISIO.IsNull()) {
397     aContext->Remove(anAISIO, isUpdate);
398   }
399 }
400
401 void XGUI_Displayer::activateObjectsOutOfContext(const std::list<int>& theModes, 
402                                                  Handle(SelectMgr_Filter) theFilter)
403 {
404   Handle(AIS_InteractiveContext) aContext = AISContext();
405   // Open local context if there is no one
406   if (!aContext->HasOpenedContext()) 
407     return;
408
409   aContext->UseDisplayedObjects();
410   std::list<int>::const_iterator anIt = theModes.begin(), aLast = theModes.end();
411   for (; anIt != aLast; anIt++) {
412     aContext->ActivateStandardMode((TopAbs_ShapeEnum)(*anIt));
413   }
414
415   if (!theFilter.IsNull())
416     aContext->AddFilter(theFilter);
417 }
418
419
420 void XGUI_Displayer::deactivateObjectsOutOfContext()
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->RemoveFilters();
428   aContext->NotUseDisplayedObjects();
429 }