Salome HOME
adfe3aad8847e1b705a12511894c9c826124a8f9
[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     // get the filters from the global context and append them to the local context
332     // a list of filters in the global context is not cleared and should be cleared here
333     SelectMgr_ListOfFilter aFilters;
334     aFilters.Assign(aContext->Filters());
335     // it is important to remove the filters in the global context, because there is a code
336     // in the closeLocalContex, which restore the global context filters
337     aContext->RemoveFilters();
338
339     //aContext->ClearCurrents();
340     aContext->OpenLocalContext();
341     aContext->NotUseDisplayedObjects();
342
343     myUseExternalObjects = false;
344     myActiveSelectionModes.clear();
345
346     SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
347     for (;aIt.More(); aIt.Next()) {
348       aContext->AddFilter(aIt.Value());
349       //GetFilter()->Add(aIt.Value());
350     }
351     // Restore selection
352     //AIS_ListIteratorOfListOfInteractive aIt(aAisList);
353     //for(; aIt.More(); aIt.Next()) {
354     //  if (aContext->IsDisplayed(aIt.Value()))
355     //    aContext->SetSelected(aIt.Value(), false);
356     //}
357   }
358 }
359
360 void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer)
361 {
362   Handle(AIS_InteractiveContext) ic = AISContext();
363   if ( (!ic.IsNull()) && (ic->HasOpenedContext()) ) {
364     // Preserve selected objects
365     //AIS_ListOfInteractive aAisList;
366     //for (ic->InitSelected(); ic->MoreSelected(); ic->NextSelected())
367     //  aAisList.Append(ic->SelectedInteractive());
368
369     // get the filters from the local context and append them to the global context
370     // a list of filters in the local context is cleared
371     SelectMgr_ListOfFilter aFilters;
372     aFilters.Assign(ic->Filters());
373
374     //ic->ClearSelected();
375     ic->CloseAllContexts(false);
376
377     // Redisplay all object if they were displayed in localContext
378     Handle(AIS_InteractiveObject) aAISIO;
379     foreach (AISObjectPtr aAIS, myResult2AISObjectMap) {
380       aAISIO = aAIS->impl<Handle(AIS_InteractiveObject)>();
381       if (ic->DisplayStatus(aAISIO) != AIS_DS_Displayed) {
382         ic->Display(aAISIO, false);
383         ic->SetDisplayMode(aAISIO, Shading, false);
384       }
385     }
386
387     // Append the filters from the local selection in the global selection context
388     SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
389     for (;aIt.More(); aIt.Next()) {
390       Handle(SelectMgr_Filter) aFilter = aIt.Value();
391       ic->AddFilter(aFilter);
392       //GetFilter()->Add(aIt.Value());
393     }
394
395     if (isUpdateViewer)
396       updateViewer();
397     myUseExternalObjects = false;
398     myActiveSelectionModes.clear();
399
400     // Restore selection
401     //AIS_ListIteratorOfListOfInteractive aIt(aAisList);
402     //for(; aIt.More(); aIt.Next()) {
403     //  if (ic->IsDisplayed(aIt.Value()))
404     //    ic->SetCurrentObject(aIt.Value(), false);
405     //}
406   }
407 }
408
409 AISObjectPtr XGUI_Displayer::getAISObject(ObjectPtr theObject) const
410 {
411   AISObjectPtr anIO;
412   if (myResult2AISObjectMap.contains(theObject))
413     anIO = myResult2AISObjectMap[theObject];
414   return anIO;
415 }
416
417 ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const
418 {
419   Handle(AIS_InteractiveObject) aRefAIS = theIO->impl<Handle(AIS_InteractiveObject)>();
420   return getObject(aRefAIS);
421 }
422
423 ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const
424 {
425   ObjectPtr aFeature;
426   foreach (ObjectPtr anObj, myResult2AISObjectMap.keys()) {
427     AISObjectPtr aAIS = myResult2AISObjectMap[anObj];
428     Handle(AIS_InteractiveObject) anAIS = aAIS->impl<Handle(AIS_InteractiveObject)>();
429     if (anAIS == theIO)
430       return anObj;
431   }
432   return aFeature;
433 }
434
435 void XGUI_Displayer::updateViewer()
436 {
437   Handle(AIS_InteractiveContext) ic = AISContext();
438   if (!ic.IsNull())
439     ic->UpdateCurrentViewer();
440 }
441
442 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
443 {
444   return myWorkshop->viewer()->AISContext();
445 }
446
447 Handle(SelectMgr_AndFilter) XGUI_Displayer::GetFilter()
448 {
449   Handle(AIS_InteractiveContext) aContext = AISContext();
450   if (myAndFilter.IsNull() && !aContext.IsNull()) {
451     myAndFilter = new SelectMgr_AndFilter();
452     aContext->AddFilter(myAndFilter);
453   }
454   return myAndFilter;
455 }
456
457 void XGUI_Displayer::displayAIS(AISObjectPtr theAIS, bool isUpdate)
458 {
459   Handle(AIS_InteractiveContext) aContext = AISContext();
460   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
461   if (!anAISIO.IsNull()) {
462     aContext->Display(anAISIO, isUpdate);
463     if (aContext->HasOpenedContext()) {
464       if (myUseExternalObjects) {
465         if (myActiveSelectionModes.size() == 0)
466           aContext->Activate(anAISIO);
467         else {
468           foreach(int aMode, myActiveSelectionModes) {
469             aContext->Activate(anAISIO, aMode);
470           }
471         }
472       }
473     }
474   }
475 }
476
477 void XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool isUpdate)
478 {
479   Handle(AIS_InteractiveContext) aContext = AISContext();
480   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
481   if (!anAISIO.IsNull()) {
482     aContext->Remove(anAISIO, isUpdate);
483   }
484 }
485
486 void XGUI_Displayer::activateObjects(const QIntList& theModes)
487 {
488   Handle(AIS_InteractiveContext) aContext = AISContext();
489   // Open local context if there is no one
490   if (!aContext->HasOpenedContext()) 
491     return;
492
493   aContext->UseDisplayedObjects();
494   myUseExternalObjects = true;
495   myActiveSelectionModes = theModes;
496
497   //Deactivate trihedron which can be activated in local selector
498   AIS_ListOfInteractive aPrsList;
499   aContext->DisplayedObjects(aPrsList, true);
500
501   Handle(AIS_Trihedron) aTrihedron;
502   AIS_ListIteratorOfListOfInteractive aLIt(aPrsList);
503   for(; aLIt.More(); aLIt.Next()){
504     aTrihedron = Handle(AIS_Trihedron)::DownCast(aLIt.Value());
505     if (!aTrihedron.IsNull()) {
506       aContext->Deactivate(aTrihedron);
507       break;
508     }
509   }
510
511   //Activate all displayed objects with the module modes
512   //AIS_ListOfInteractive aPrsList;
513   //aContext->DisplayedObjects(aPrsList, true);
514
515   //AIS_ListIteratorOfListOfInteractive aLIt(aPrsList);
516   Handle(AIS_InteractiveObject) anAISIO;
517   for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){
518     anAISIO = aLIt.Value();
519     aTrihedron = Handle(AIS_Trihedron)::DownCast(anAISIO);
520     if (!aTrihedron.IsNull())
521       continue;
522
523     aContext->Load(anAISIO, -1, true);
524     if (theModes.size() == 0)
525       aContext->Activate(anAISIO);
526     else {
527       foreach(int aMode, theModes) {
528         aContext->Activate(anAISIO, aMode);
529       }
530     }
531   }
532 }
533
534
535 void XGUI_Displayer::deactivateObjects()
536 {
537   Handle(AIS_InteractiveContext) aContext = AISContext();
538   // Open local context if there is no one
539   if (!aContext->HasOpenedContext()) 
540     return;
541
542   aContext->NotUseDisplayedObjects();
543 }
544
545
546 void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool toUpdate)
547 {
548   if (theMode == NoMode)
549     return;
550
551   Handle(AIS_InteractiveContext) aContext = AISContext();
552   if (aContext.IsNull())
553     return;
554
555   AISObjectPtr aAISObj = getAISObject(theObject);
556   if (!aAISObj)
557     return;
558
559   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
560   aContext->SetDisplayMode(aAISIO, theMode, toUpdate);
561 }
562
563 XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const
564 {
565   Handle(AIS_InteractiveContext) aContext = AISContext();
566   if (aContext.IsNull())
567     return NoMode;
568
569   AISObjectPtr aAISObj = getAISObject(theObject);
570   if (!aAISObj)
571     return NoMode;
572
573   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
574   return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode();
575 }
576
577 void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
578 {
579   Handle(AIS_InteractiveContext) aContext = AISContext();
580   if (aContext.IsNull())
581     return;
582   const SelectMgr_ListOfFilter& aFilters = aContext->Filters();
583   SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
584   for (; aIt.More(); aIt.Next()) {
585     if (theFilter.Access() == aIt.Value().Access())
586       return;
587   }
588   //aContext->AddFilter(theFilter);
589   GetFilter()->Add(theFilter);
590 }
591
592 void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
593 {
594   Handle(AIS_InteractiveContext) aContext = AISContext();
595   if (aContext.IsNull())
596     return;
597   //aContext->RemoveFilter(theFilter);
598   GetFilter()->Remove(theFilter);
599 }
600
601 void XGUI_Displayer::removeFilters()
602 {
603   Handle(AIS_InteractiveContext) aContext = AISContext();
604   if (aContext.IsNull())
605     return;
606   //aContext->RemoveFilters();
607   GetFilter()->Clear();
608 }