Salome HOME
Merge branch 'master' of newgeom:newgeom.git into BR_PYTHON_PLUGIN
[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.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 = 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.erase(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.at(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    ResultToAISMap::iterator aIt;
276    for (aIt = myResult2AISObjectMap.begin(); aIt != myResult2AISObjectMap.end(); aIt++) {
277      // erase an object
278      AISObjectPtr aAISObj = (*aIt).second;
279      Handle(AIS_InteractiveObject) anIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
280      if (!anIO.IsNull())
281       ic->Remove(anIO, false);
282    }
283    myResult2AISObjectMap.clear();
284    if (isUpdateViewer)
285      updateViewer();
286  }
287
288 void XGUI_Displayer::eraseDeletedResults(const bool isUpdateViewer)
289 {
290   Handle(AIS_InteractiveContext) aContext = AISContext();
291   if (aContext.IsNull())
292     return;
293
294   ResultToAISMap::const_iterator aFIt = myResult2AISObjectMap.begin(), aFLast =
295       myResult2AISObjectMap.end();
296   std::list<ObjectPtr> aRemoved;
297   for (; aFIt != aFLast; aFIt++) {
298     ObjectPtr aFeature = (*aFIt).first;
299     if (!aFeature || !aFeature->data() || !aFeature->data()->isValid()) {
300       AISObjectPtr anObj = (*aFIt).second;
301       if (!anObj)
302         continue;
303       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
304       if (!anAIS.IsNull()) {
305         aContext->Remove(anAIS, false);
306         aRemoved.push_back(aFeature);
307       }
308     }
309   }
310   std::list<ObjectPtr>::const_iterator anIt = aRemoved.begin(), aLast = aRemoved.end();
311   for (; anIt != aLast; anIt++) {
312     myResult2AISObjectMap.erase(myResult2AISObjectMap.find(*anIt));
313   }
314
315   if (isUpdateViewer)
316     updateViewer();
317 }
318
319 void XGUI_Displayer::openLocalContext()
320 {
321   Handle(AIS_InteractiveContext) aContext = AISContext();
322   if (aContext.IsNull())
323     return;
324   // Open local context if there is no one
325   if (!aContext->HasOpenedContext()) {
326     aContext->ClearCurrents(false);
327     //aContext->OpenLocalContext(false/*use displayed objects*/, true/*allow shape decomposition*/);
328     aContext->OpenLocalContext();
329     aContext->NotUseDisplayedObjects();
330
331     myUseExternalObjects = false;
332     myActiveSelectionModes.clear();
333   }
334 }
335
336 void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer)
337 {
338   AISContext()->ClearSelected(false);
339   closeAllContexts(true);
340 }
341
342 AISObjectPtr XGUI_Displayer::getAISObject(ObjectPtr theObject) const
343 {
344   AISObjectPtr anIO;
345   if (myResult2AISObjectMap.find(theObject) != myResult2AISObjectMap.end())
346     anIO = (myResult2AISObjectMap.find(theObject))->second;
347   return anIO;
348 }
349
350 ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const
351 {
352   Handle(AIS_InteractiveObject) aRefAIS = theIO->impl<Handle(AIS_InteractiveObject)>();
353   return getObject(aRefAIS);
354 }
355
356 ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const
357 {
358   ObjectPtr aFeature;
359   ResultToAISMap::const_iterator aFIt = myResult2AISObjectMap.begin(), aFLast =
360       myResult2AISObjectMap.end();
361   for (; aFIt != aFLast && !aFeature; aFIt++) {
362     AISObjectPtr anObj = (*aFIt).second;
363     if (!anObj)
364       continue;
365     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
366     if (anAIS != theIO)
367       continue;
368     aFeature = (*aFIt).first;
369   }
370   return aFeature;
371 }
372
373 void XGUI_Displayer::closeAllContexts(const bool isUpdateViewer)
374 {
375   Handle(AIS_InteractiveContext) ic = AISContext();
376   if (!ic.IsNull()) {
377     ic->CloseAllContexts(false);
378     if (isUpdateViewer)
379       updateViewer();
380     myUseExternalObjects = false;
381     myActiveSelectionModes.clear();
382   }
383 }
384
385 void XGUI_Displayer::updateViewer()
386 {
387   Handle(AIS_InteractiveContext) ic = AISContext();
388   if (!ic.IsNull())
389     ic->UpdateCurrentViewer();
390 }
391
392 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
393 {
394   return myWorkshop->viewer()->AISContext();
395 }
396
397 void XGUI_Displayer::displayAIS(AISObjectPtr theAIS, bool isUpdate)
398 {
399   Handle(AIS_InteractiveContext) aContext = AISContext();
400   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
401   if (!anAISIO.IsNull()) {
402     aContext->Display(anAISIO, isUpdate);
403     if (aContext->HasOpenedContext()) {
404       if (myUseExternalObjects) {
405         if (myActiveSelectionModes.size() == 0)
406           aContext->Activate(anAISIO);
407         else {
408           foreach(int aMode, myActiveSelectionModes) {
409             aContext->Activate(anAISIO, aMode);
410           }
411         }
412       }
413     }
414   }
415 }
416
417 void XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool isUpdate)
418 {
419   Handle(AIS_InteractiveContext) aContext = AISContext();
420   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
421   if (!anAISIO.IsNull()) {
422     aContext->Remove(anAISIO, isUpdate);
423   }
424 }
425
426 void XGUI_Displayer::activateObjectsOutOfContext(const QIntList& theModes)
427 {
428   Handle(AIS_InteractiveContext) aContext = AISContext();
429   // Open local context if there is no one
430   if (!aContext->HasOpenedContext()) 
431     return;
432
433   aContext->UseDisplayedObjects();
434   myUseExternalObjects = true;
435   myActiveSelectionModes = theModes;
436
437   //Deactivate trihedron which can be activated in local selector
438   AIS_ListOfInteractive aPrsList;
439   aContext->DisplayedObjects(aPrsList, true);
440
441   Handle(AIS_Trihedron) aTrihedron;
442   AIS_ListIteratorOfListOfInteractive aLIt(aPrsList);
443   for(; aLIt.More(); aLIt.Next()){
444     aTrihedron = Handle(AIS_Trihedron)::DownCast(aLIt.Value());
445     if (!aTrihedron.IsNull()) {
446       aContext->Deactivate(aTrihedron);
447       break;
448     }
449   }
450
451   ResultToAISMap::iterator aIt;
452   Handle(AIS_InteractiveObject) anAISIO;
453   for (aIt = myResult2AISObjectMap.begin(); aIt != myResult2AISObjectMap.end(); aIt++) {
454   anAISIO = (*aIt).second->impl<Handle(AIS_InteractiveObject)>();
455     aContext->Load(anAISIO, -1, true);
456     if (theModes.size() == 0)
457       aContext->Activate(anAISIO);
458     else {
459       foreach(int aMode, theModes) {
460         aContext->Activate(anAISIO, aMode);
461       }
462     }
463   }
464 }
465
466
467 void XGUI_Displayer::deactivateObjectsOutOfContext()
468 {
469   Handle(AIS_InteractiveContext) aContext = AISContext();
470   // Open local context if there is no one
471   if (!aContext->HasOpenedContext()) 
472     return;
473
474   aContext->NotUseDisplayedObjects();
475 }
476
477
478 void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool toUpdate)
479 {
480   if (theMode == NoMode)
481     return;
482
483   Handle(AIS_InteractiveContext) aContext = AISContext();
484   if (aContext.IsNull())
485     return;
486
487   AISObjectPtr aAISObj = getAISObject(theObject);
488   if (!aAISObj)
489     return;
490
491   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
492   aContext->SetDisplayMode(aAISIO, theMode, toUpdate);
493 }
494
495 void XGUI_Displayer::setSelectionModes(const QIntList& theModes)
496 {
497   Handle(AIS_InteractiveContext) aContext = AISContext();
498   if (aContext.IsNull())
499     return;
500   if (!aContext->HasOpenedContext())
501     return;
502   // Clear previous mode
503   const TColStd_ListOfInteger& aModes = aContext->ActivatedStandardModes();
504   if (!aModes.IsEmpty()) {
505     TColStd_ListOfInteger aMModes;
506     aMModes.Assign(aModes);
507     TColStd_ListIteratorOfListOfInteger it(aMModes);
508     for(; it.More(); it.Next()) {
509       aContext->DeactivateStandardMode((TopAbs_ShapeEnum)it.Value());
510     }
511   }
512   foreach(int aMode, theModes) {
513     aContext->ActivateStandardMode((TopAbs_ShapeEnum)aMode);
514   }
515 }
516
517 XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const
518 {
519   Handle(AIS_InteractiveContext) aContext = AISContext();
520   if (aContext.IsNull())
521     return NoMode;
522
523   AISObjectPtr aAISObj = getAISObject(theObject);
524   if (!aAISObj)
525     return NoMode;
526
527   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
528   return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode();
529 }
530
531 void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
532 {
533   Handle(AIS_InteractiveContext) aContext = AISContext();
534   if (aContext.IsNull())
535     return;
536   const SelectMgr_ListOfFilter& aFilters = aContext->Filters();
537   SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
538   for (; aIt.More(); aIt.Next()) {
539     if (theFilter.Access() == aIt.Value().Access())
540       return;
541   }
542   aContext->AddFilter(theFilter);
543 }
544
545 void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
546 {
547   Handle(AIS_InteractiveContext) aContext = AISContext();
548   if (aContext.IsNull())
549     return;
550   aContext->RemoveFilter(theFilter);
551 }