]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_Displayer.cpp
Salome HOME
Merge branch 'master' of newgeom:newgeom
[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 {
37   myWorkshop = theWorkshop;
38 }
39
40 XGUI_Displayer::~XGUI_Displayer()
41 {
42 }
43
44 bool XGUI_Displayer::isVisible(ObjectPtr theObject) const
45 {
46   return myResult2AISObjectMap.find(theObject) != myResult2AISObjectMap.end();
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 = boost::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
57     bool isShading = false;
58     if (aPrs) {
59       anAIS = aPrs->getAISObject(AISObjectPtr());
60     } else {
61       ResultPtr aResult = boost::dynamic_pointer_cast<ModelAPI_Result>(theObject);
62       if (aResult) {
63         boost::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   }
90 }
91
92 void XGUI_Displayer::erase(ObjectPtr theObject, const bool isUpdateViewer)
93 {
94   if (!isVisible(theObject))
95     return;
96
97   Handle(AIS_InteractiveContext) aContext = AISContext();
98   if (aContext.IsNull())
99     return;
100   AISObjectPtr anObject = myResult2AISObjectMap[theObject];
101   if (anObject) {
102     Handle(AIS_InteractiveObject) anAIS = anObject->impl<Handle(AIS_InteractiveObject)>();
103     if (!anAIS.IsNull()) {
104       aContext->Remove(anAIS, isUpdateViewer);
105     }
106   }
107   myResult2AISObjectMap.erase(theObject);
108 }
109
110 void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer)
111 {
112   if (!isVisible(theObject))
113     return;
114
115   AISObjectPtr aAISObj = getAISObject(theObject);
116   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
117
118   GeomPresentablePtr aPrs = boost::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
119   if (aPrs) {
120     AISObjectPtr aAIS_Obj = aPrs->getAISObject(aAISObj);
121     if (!aAIS_Obj) {
122       erase(theObject, isUpdateViewer);
123       return;
124     }
125     if (aAIS_Obj != aAISObj) {
126       myResult2AISObjectMap[theObject] = aAIS_Obj;
127     }
128     aAISIO = aAIS_Obj->impl<Handle(AIS_InteractiveObject)>();
129   }
130
131   if (!aAISIO.IsNull()) {
132     Handle(AIS_InteractiveContext) aContext = AISContext();
133     if (aContext.IsNull())
134       return;
135     aContext->Redisplay(aAISIO, isUpdateViewer);
136   }
137 }
138
139 void XGUI_Displayer::deactivate(ObjectPtr theObject)
140 {
141   if (isVisible(theObject)) {
142     Handle(AIS_InteractiveContext) aContext = AISContext();
143     if (aContext.IsNull())
144       return;
145
146     AISObjectPtr anObj = myResult2AISObjectMap[theObject];
147     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
148     aContext->Deactivate(anAIS);
149   }
150 }
151
152 void XGUI_Displayer::activate(ObjectPtr theObject, const QIntList& theModes)
153 {
154   if (isVisible(theObject)) {
155     Handle(AIS_InteractiveContext) aContext = AISContext();
156     if (aContext.IsNull())
157       return;
158
159     AISObjectPtr anObj = myResult2AISObjectMap[theObject];
160     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
161     if (aContext->HasOpenedContext()) {
162       aContext->Load(anAIS, -1, true);
163     }
164     if (theModes.size() > 0) {
165       foreach(int aMode, theModes) {
166         aContext->Activate(anAIS, aMode);
167       }
168     } else 
169       aContext->Activate(anAIS);
170   }
171 }
172
173 bool XGUI_Displayer::isActive(ObjectPtr theObject) const
174 {
175   Handle(AIS_InteractiveContext) aContext = AISContext();
176   if (aContext.IsNull())
177     return false;
178   if (!isVisible(theObject))
179     return false;
180     
181   AISObjectPtr anObj = myResult2AISObjectMap.at(theObject);
182   Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
183
184   TColStd_ListOfInteger aModes;
185   aContext->ActivatedModes(anAIS, aModes);
186   return aModes.Extent() > 0;
187 }
188
189 void XGUI_Displayer::stopSelection(const QList<ObjectPtr>& theResults, const bool isStop,
190                                    const bool isUpdateViewer)
191 {
192   Handle(AIS_InteractiveContext) aContext = AISContext();
193   if (aContext.IsNull())
194     return;
195
196   Handle(AIS_Shape) anAIS;
197   QList<ObjectPtr>::const_iterator anIt = theResults.begin(), aLast = theResults.end();
198   ObjectPtr aFeature;
199   for (; anIt != aLast; anIt++) {
200     aFeature = *anIt;
201     if (isVisible(aFeature))
202       anAIS = Handle(AIS_Shape)::DownCast(
203           myResult2AISObjectMap[aFeature]->impl<Handle(AIS_InteractiveObject)>());
204     if (anAIS.IsNull())
205       continue;
206
207     if (isStop) {
208       QColor aColor(Qt::white);
209       anAIS->SetColor(
210           Quantity_Color(aColor.red() / 255., aColor.green() / 255., aColor.blue() / 255.,
211                          Quantity_TOC_RGB));
212       anAIS->Redisplay();
213     } else {
214       QColor aColor(Qt::red);
215       anAIS->SetColor(
216           Quantity_Color(aColor.red() / 255., aColor.green() / 255., aColor.blue() / 255.,
217                          Quantity_TOC_RGB));
218       anAIS->Redisplay();
219     }
220   }
221   if (isUpdateViewer)
222     updateViewer();
223 }
224
225 void XGUI_Displayer::setSelected(const QList<ObjectPtr>& theResults, const bool isUpdateViewer)
226 {
227   Handle(AIS_InteractiveContext) aContext = AISContext();
228   // we need to unhighligth objects manually in the current local context
229   // in couple with the selection clear (TODO)
230   Handle(AIS_LocalContext) aLocalContext = aContext->LocalContext();
231   if (!aLocalContext.IsNull())
232     aLocalContext->UnhilightLastDetected(myWorkshop->viewer()->activeView());
233
234   aContext->ClearSelected();
235   foreach(ObjectPtr aResult, theResults)
236   {
237     if (isVisible(aResult)) {
238       AISObjectPtr anObj = myResult2AISObjectMap[aResult];
239       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
240       if (!anAIS.IsNull())
241         aContext->SetSelected(anAIS, false);
242     }
243   }
244   if (isUpdateViewer)
245     updateViewer();
246 }
247
248
249 void XGUI_Displayer::clearSelected()
250 {
251   Handle(AIS_InteractiveContext) aContext = AISContext();
252   if (aContext) {
253     aContext->UnhilightCurrents(false);
254     aContext->ClearSelected();
255   }
256 }
257
258 void XGUI_Displayer::eraseAll(const bool isUpdateViewer)
259 {
260   Handle(AIS_InteractiveContext) ic = AISContext();
261   if (ic.IsNull())
262     return;
263
264    ResultToAISMap::iterator aIt;
265    for (aIt = myResult2AISObjectMap.begin(); aIt != myResult2AISObjectMap.end(); aIt++) {
266      // erase an object
267      AISObjectPtr aAISObj = (*aIt).second;
268      Handle(AIS_InteractiveObject) anIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
269      if (!anIO.IsNull())
270       ic->Remove(anIO, false);
271    }
272    myResult2AISObjectMap.clear();
273    if (isUpdateViewer)
274      updateViewer();
275  }
276
277 void XGUI_Displayer::eraseDeletedResults(const bool isUpdateViewer)
278 {
279   Handle(AIS_InteractiveContext) aContext = AISContext();
280   if (aContext.IsNull())
281     return;
282
283   ResultToAISMap::const_iterator aFIt = myResult2AISObjectMap.begin(), aFLast =
284       myResult2AISObjectMap.end();
285   std::list<ObjectPtr> aRemoved;
286   for (; aFIt != aFLast; aFIt++) {
287     ObjectPtr aFeature = (*aFIt).first;
288     if (!aFeature || !aFeature->data() || !aFeature->data()->isValid()) {
289       AISObjectPtr anObj = (*aFIt).second;
290       if (!anObj)
291         continue;
292       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
293       if (!anAIS.IsNull()) {
294         aContext->Remove(anAIS, false);
295         aRemoved.push_back(aFeature);
296       }
297     }
298   }
299   std::list<ObjectPtr>::const_iterator anIt = aRemoved.begin(), aLast = aRemoved.end();
300   for (; anIt != aLast; anIt++) {
301     myResult2AISObjectMap.erase(myResult2AISObjectMap.find(*anIt));
302   }
303
304   if (isUpdateViewer)
305     updateViewer();
306 }
307
308 void XGUI_Displayer::openLocalContext()
309 {
310   Handle(AIS_InteractiveContext) aContext = AISContext();
311   if (aContext.IsNull())
312     return;
313   // Open local context if there is no one
314   if (!aContext->HasOpenedContext()) {
315     aContext->ClearCurrents(false);
316     //aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
317     aContext->OpenLocalContext();
318     aContext->NotUseDisplayedObjects();
319   }
320 }
321
322 void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer)
323 {
324   AISContext()->ClearSelected(false);
325   closeAllContexts(true);
326 }
327
328 AISObjectPtr XGUI_Displayer::getAISObject(ObjectPtr theObject) const
329 {
330   AISObjectPtr anIO;
331   if (myResult2AISObjectMap.find(theObject) != myResult2AISObjectMap.end())
332     anIO = (myResult2AISObjectMap.find(theObject))->second;
333   return anIO;
334 }
335
336 ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const
337 {
338   Handle(AIS_InteractiveObject) aRefAIS = theIO->impl<Handle(AIS_InteractiveObject)>();
339   return getObject(aRefAIS);
340 }
341
342 ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const
343 {
344   ObjectPtr aFeature;
345   ResultToAISMap::const_iterator aFIt = myResult2AISObjectMap.begin(), aFLast =
346       myResult2AISObjectMap.end();
347   for (; aFIt != aFLast && !aFeature; aFIt++) {
348     AISObjectPtr anObj = (*aFIt).second;
349     if (!anObj)
350       continue;
351     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
352     if (anAIS != theIO)
353       continue;
354     aFeature = (*aFIt).first;
355   }
356   return aFeature;
357 }
358
359 void XGUI_Displayer::closeAllContexts(const bool isUpdateViewer)
360 {
361   Handle(AIS_InteractiveContext) ic = AISContext();
362   if (!ic.IsNull()) {
363     ic->CloseAllContexts(false);
364     if (isUpdateViewer)
365       updateViewer();
366   }
367 }
368
369 void XGUI_Displayer::updateViewer()
370 {
371   Handle(AIS_InteractiveContext) ic = AISContext();
372   if (!ic.IsNull())
373     ic->UpdateCurrentViewer();
374 }
375
376 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
377 {
378   return myWorkshop->viewer()->AISContext();
379 }
380
381 void XGUI_Displayer::display(AISObjectPtr theAIS, bool isUpdate)
382 {
383   Handle(AIS_InteractiveContext) aContext = AISContext();
384   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
385   if (!anAISIO.IsNull())
386     aContext->Display(anAISIO, isUpdate);
387 }
388
389 void XGUI_Displayer::erase(AISObjectPtr theAIS, const bool isUpdate)
390 {
391   Handle(AIS_InteractiveContext) aContext = AISContext();
392   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
393   if (!anAISIO.IsNull()) {
394     aContext->Remove(anAISIO, isUpdate);
395   }
396 }
397
398 void XGUI_Displayer::activateObjectsOutOfContext(const QIntList& theModes)
399 {
400   Handle(AIS_InteractiveContext) aContext = AISContext();
401   // Open local context if there is no one
402   if (!aContext->HasOpenedContext()) 
403     return;
404
405   aContext->UseDisplayedObjects();
406
407   //Deactivate trihedron which can be activated in local selector
408   AIS_ListOfInteractive aPrsList;
409   aContext->DisplayedObjects(aPrsList, true);
410
411   Handle(AIS_Trihedron) aTrihedron;
412   AIS_ListIteratorOfListOfInteractive aLIt(aPrsList);
413   for(; aLIt.More(); aLIt.Next()){
414     aTrihedron = Handle(AIS_Trihedron)::DownCast(aLIt.Value());
415     if (!aTrihedron.IsNull()) {
416       aContext->Deactivate(aTrihedron);
417       break;
418     }
419   }
420
421   ResultToAISMap::iterator aIt;
422   Handle(AIS_InteractiveObject) anAISIO;
423   for (aIt = myResult2AISObjectMap.begin(); aIt != myResult2AISObjectMap.end(); aIt++) {
424   anAISIO = (*aIt).second->impl<Handle(AIS_InteractiveObject)>();
425     aContext->Load(anAISIO, -1, true);
426     if (theModes.size() == 0)
427       aContext->Activate(anAISIO);
428     else {
429       foreach(int aMode, theModes) {
430         aContext->Activate(anAISIO, aMode);
431       }
432     }
433   }
434 }
435
436
437 void XGUI_Displayer::deactivateObjectsOutOfContext()
438 {
439   Handle(AIS_InteractiveContext) aContext = AISContext();
440   // Open local context if there is no one
441   if (!aContext->HasOpenedContext()) 
442     return;
443
444   aContext->NotUseDisplayedObjects();
445 }
446
447
448 void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool toUpdate)
449 {
450   if (theMode == NoMode)
451     return;
452
453   Handle(AIS_InteractiveContext) aContext = AISContext();
454   if (aContext.IsNull())
455     return;
456
457   AISObjectPtr aAISObj = getAISObject(theObject);
458   if (!aAISObj)
459     return;
460
461   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
462   aContext->SetDisplayMode(aAISIO, theMode, toUpdate);
463 }
464
465 void XGUI_Displayer::setSelectionModes(const QIntList& theModes)
466 {
467   Handle(AIS_InteractiveContext) aContext = AISContext();
468   if (aContext.IsNull())
469     return;
470   if (!aContext->HasOpenedContext())
471     return;
472   // Clear previous mode
473   const TColStd_ListOfInteger& aModes = aContext->ActivatedStandardModes();
474   if (!aModes.IsEmpty()) {
475     TColStd_ListOfInteger aMModes;
476     aMModes.Assign(aModes);
477     TColStd_ListIteratorOfListOfInteger it(aMModes);
478     for(; it.More(); it.Next()) {
479       aContext->DeactivateStandardMode((TopAbs_ShapeEnum)it.Value());
480     }
481   }
482   foreach(int aMode, theModes) {
483     aContext->ActivateStandardMode((TopAbs_ShapeEnum)aMode);
484   }
485 }
486
487 XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const
488 {
489   Handle(AIS_InteractiveContext) aContext = AISContext();
490   if (aContext.IsNull())
491     return NoMode;
492
493   AISObjectPtr aAISObj = getAISObject(theObject);
494   if (!aAISObj)
495     return NoMode;
496
497   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
498   return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode();
499 }
500
501 void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
502 {
503   Handle(AIS_InteractiveContext) aContext = AISContext();
504   if (aContext.IsNull())
505     return;
506   const SelectMgr_ListOfFilter& aFilters = aContext->Filters();
507   SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
508   for (; aIt.More(); aIt.Next()) {
509     if (theFilter.Access() == aIt.Value().Access())
510       return;
511   }
512   aContext->AddFilter(theFilter);
513 }
514
515 void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
516 {
517   Handle(AIS_InteractiveContext) aContext = AISContext();
518   if (aContext.IsNull())
519     return;
520   aContext->RemoveFilter(theFilter);
521 }