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