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