]> SALOME platform Git repositories - modules/shaper.git/blob - src/XGUI/XGUI_Displayer.cpp
Salome HOME
A sketcher operations manager is created
[modules/shaper.git] / src / XGUI / XGUI_Displayer.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        XGUI_Displayer.cpp
4 // Created:     20 Apr 2014
5 // Author:      Natalia ERMOLAEVA
6
7 #include "XGUI_Displayer.h"
8 #include "XGUI_Workshop.h"
9 #include "XGUI_ViewerProxy.h"
10
11 #include <AppElements_Viewer.h>
12
13 #include <ModelAPI_Document.h>
14 #include <ModelAPI_Data.h>
15 #include <ModelAPI_Object.h>
16 #include <ModelAPI_Tools.h>
17
18 #include <ModuleBase_ResultPrs.h>
19
20 #include <GeomAPI_Shape.h>
21 #include <GeomAPI_IPresentable.h>
22 #include <GeomAPI_ICustomPrs.h>
23
24 #include <AIS_InteractiveContext.hxx>
25 #include <AIS_LocalContext.hxx>
26 #include <AIS_ListOfInteractive.hxx>
27 #include <AIS_ListIteratorOfListOfInteractive.hxx>
28 #include <AIS_DimensionSelectionMode.hxx>
29 #include <AIS_Shape.hxx>
30 #include <AIS_Dimension.hxx>
31 #include <TColStd_ListIteratorOfListOfInteger.hxx>
32 #include <SelectMgr_ListOfFilter.hxx>
33 #include <SelectMgr_ListIteratorOfListOfFilter.hxx>
34
35 #include <set>
36
37 const int MOUSE_SENSITIVITY_IN_PIXEL = 10;  ///< defines the local context mouse selection sensitivity
38
39 XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop)
40   : myUseExternalObjects(false), myWorkshop(theWorkshop)
41 {
42 }
43
44 XGUI_Displayer::~XGUI_Displayer()
45 {
46 }
47
48 bool XGUI_Displayer::isVisible(ObjectPtr theObject) const
49 {
50   return myResult2AISObjectMap.contains(theObject);
51 }
52
53 void XGUI_Displayer::display(ObjectPtr theObject, bool isUpdateViewer)
54 {
55   if (isVisible(theObject)) {
56     redisplay(theObject, isUpdateViewer);
57   } else {
58     AISObjectPtr anAIS;
59
60     GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
61     bool isShading = false;
62     if (aPrs.get() != NULL) {
63       anAIS = aPrs->getAISObject(AISObjectPtr());
64     } else {
65       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
66       if (aResult.get() != NULL) {
67         std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
68         if (aShapePtr.get() != NULL) {
69           anAIS = AISObjectPtr(new GeomAPI_AISObject());
70           anAIS->setImpl(new Handle(AIS_InteractiveObject)(new ModuleBase_ResultPrs(aResult)));
71           //anAIS->createShape(aShapePtr);
72           isShading = true;
73         }
74       }
75     }
76     if (anAIS)
77       display(theObject, anAIS, isShading, isUpdateViewer);
78   }
79 }
80
81 void XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, 
82                              bool isShading, bool isUpdateViewer)
83 {
84   Handle(AIS_InteractiveContext) aContext = AISContext();
85   if (aContext.IsNull())
86     return;
87
88   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
89   if (!anAISIO.IsNull()) {
90     myResult2AISObjectMap[theObject] = theAIS;
91     aContext->Display(anAISIO, false);
92     aContext->SetDisplayMode(anAISIO, isShading? Shading : Wireframe, false);
93
94     FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
95     if (aFeature.get() != NULL) {
96       GeomCustomPrsPtr aCustPrs = std::dynamic_pointer_cast<GeomAPI_ICustomPrs>(aFeature);
97       if (aCustPrs.get() != NULL)
98         aCustPrs->customisePresentation(theAIS);
99     }
100     if (aContext->HasOpenedContext()) {
101       if (myUseExternalObjects) {
102         if (myActiveSelectionModes.size() == 0)
103           aContext->Activate(anAISIO);
104         else {
105           foreach(int aMode, myActiveSelectionModes) {
106             aContext->Activate(anAISIO, aMode);
107           }
108         }
109       }
110     }
111   }
112   if (isUpdateViewer)
113     updateViewer();
114 }
115
116 void XGUI_Displayer::erase(ObjectPtr theObject, const bool isUpdateViewer)
117 {
118   if (!isVisible(theObject))
119     return;
120
121   Handle(AIS_InteractiveContext) aContext = AISContext();
122   if (aContext.IsNull())
123     return;
124   AISObjectPtr anObject = myResult2AISObjectMap[theObject];
125   if (anObject) {
126     Handle(AIS_InteractiveObject) anAIS = anObject->impl<Handle(AIS_InteractiveObject)>();
127     if (!anAIS.IsNull()) {
128       aContext->Remove(anAIS, isUpdateViewer);
129     }
130   }
131   myResult2AISObjectMap.remove(theObject);
132 }
133
134 void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer)
135 {
136   if (!isVisible(theObject))
137     return;
138
139   AISObjectPtr aAISObj = getAISObject(theObject);
140   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
141
142   GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
143   if (aPrs) {
144     AISObjectPtr aAIS_Obj = aPrs->getAISObject(aAISObj);
145     if (!aAIS_Obj) {
146       erase(theObject, isUpdateViewer);
147       return;
148     }
149     if (aAIS_Obj != aAISObj) {
150       myResult2AISObjectMap[theObject] = aAIS_Obj;
151     }
152     aAISIO = aAIS_Obj->impl<Handle(AIS_InteractiveObject)>();
153   }
154
155   if (!aAISIO.IsNull()) {
156     Handle(AIS_InteractiveContext) aContext = AISContext();
157     if (aContext.IsNull())
158       return;
159     aContext->Redisplay(aAISIO, isUpdateViewer);
160   }
161 }
162
163 void XGUI_Displayer::deactivate(ObjectPtr theObject)
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     aContext->Deactivate(anAIS);
173   }
174 }
175
176 void XGUI_Displayer::activate(ObjectPtr theFeature)
177 {
178   QIntList aModes;
179   activate(theFeature, aModes);
180 }
181
182 void XGUI_Displayer::activate(ObjectPtr theObject, const QIntList& theModes)
183 {
184   if (isVisible(theObject)) {
185     Handle(AIS_InteractiveContext) aContext = AISContext();
186     if (aContext.IsNull())
187       return;
188
189     AISObjectPtr anObj = myResult2AISObjectMap[theObject];
190     Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
191     if (aContext->HasOpenedContext()) {
192       aContext->Load(anAIS, -1, true);
193     }
194     aContext->Deactivate(anAIS);
195     if (theModes.size() > 0) {
196       foreach(int aMode, theModes) {
197         aContext->Activate(anAIS, aMode);
198       }
199     } else 
200       aContext->Activate(anAIS);
201   }
202 }
203
204 bool XGUI_Displayer::isActive(ObjectPtr theObject) const
205 {
206   Handle(AIS_InteractiveContext) aContext = AISContext();
207   if (aContext.IsNull())
208     return false;
209   if (!isVisible(theObject))
210     return false;
211     
212   AISObjectPtr anObj = myResult2AISObjectMap[theObject];
213   Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
214
215   TColStd_ListOfInteger aModes;
216   aContext->ActivatedModes(anAIS, aModes);
217   return aModes.Extent() > 0;
218 }
219
220 void XGUI_Displayer::stopSelection(const QObjectPtrList& theResults, const bool isStop,
221                                    const bool isUpdateViewer)
222 {
223   Handle(AIS_InteractiveContext) aContext = AISContext();
224   if (aContext.IsNull())
225     return;
226
227   Handle(AIS_Shape) anAIS;
228   QObjectPtrList::const_iterator anIt = theResults.begin(), aLast = theResults.end();
229   ObjectPtr aFeature;
230   for (; anIt != aLast; anIt++) {
231     aFeature = *anIt;
232     if (isVisible(aFeature))
233       anAIS = Handle(AIS_Shape)::DownCast(
234           myResult2AISObjectMap[aFeature]->impl<Handle(AIS_InteractiveObject)>());
235     if (anAIS.IsNull())
236       continue;
237
238     if (isStop) {
239       QColor aColor(Qt::white);
240       anAIS->SetColor(
241           Quantity_Color(aColor.red() / 255., aColor.green() / 255., aColor.blue() / 255.,
242                          Quantity_TOC_RGB));
243       anAIS->Redisplay();
244     } else {
245       QColor aColor(Qt::red);
246       anAIS->SetColor(
247           Quantity_Color(aColor.red() / 255., aColor.green() / 255., aColor.blue() / 255.,
248                          Quantity_TOC_RGB));
249       anAIS->Redisplay();
250     }
251   }
252   if (isUpdateViewer)
253     updateViewer();
254 }
255
256 void XGUI_Displayer::setSelected(const QObjectPtrList& theResults, const bool isUpdateViewer)
257 {
258   Handle(AIS_InteractiveContext) aContext = AISContext();
259   if (aContext.IsNull())
260     return;
261   if (aContext->HasOpenedContext()) {
262     aContext->UnhilightSelected();
263     aContext->ClearSelected();
264     foreach(ObjectPtr aResult, theResults) {
265       if (isVisible(aResult)) {
266         AISObjectPtr anObj = myResult2AISObjectMap[aResult];
267         Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
268         if (!anAIS.IsNull())
269           aContext->SetSelected(anAIS, false);
270       }
271     }
272   } else {
273     aContext->UnhilightCurrents();
274     aContext->ClearCurrents();
275     foreach(ObjectPtr aResult, theResults) {
276       if (isVisible(aResult)) {
277         AISObjectPtr anObj = myResult2AISObjectMap[aResult];
278         Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
279         if (!anAIS.IsNull())
280           aContext->SetCurrentObject(anAIS, false);
281       }
282     }
283   }
284   if (isUpdateViewer)
285     updateViewer();
286 }
287
288
289 void XGUI_Displayer::clearSelected()
290 {
291   Handle(AIS_InteractiveContext) aContext = AISContext();
292   if (aContext) {
293     aContext->UnhilightCurrents(false);
294     aContext->ClearSelected();
295   }
296 }
297
298 void XGUI_Displayer::eraseAll(const bool isUpdateViewer)
299 {
300   Handle(AIS_InteractiveContext) aContext = AISContext();
301   if (aContext.IsNull())
302     return;
303
304    foreach (AISObjectPtr aAISObj, myResult2AISObjectMap) {
305      // erase an object
306      Handle(AIS_InteractiveObject) anIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
307      if (!anIO.IsNull())
308        aContext->Remove(anIO, false);
309    }
310    myResult2AISObjectMap.clear();
311    if (isUpdateViewer)
312      updateViewer();
313  }
314
315 void XGUI_Displayer::eraseDeletedResults(const bool isUpdateViewer)
316 {
317   Handle(AIS_InteractiveContext) aContext = AISContext();
318   if (aContext.IsNull())
319     return;
320
321   QObjectPtrList aRemoved;
322   foreach (ObjectPtr aFeature, myResult2AISObjectMap.keys()) {
323     if (!aFeature || !aFeature->data() || !aFeature->data()->isValid()) {
324       AISObjectPtr anObj = myResult2AISObjectMap[aFeature];
325       if (!anObj)
326         continue;
327       Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
328       if (!anAIS.IsNull()) {
329         aContext->Remove(anAIS, false);
330         aRemoved.append(aFeature);
331       }
332     }
333   }
334   foreach(ObjectPtr aObj, aRemoved) {
335     myResult2AISObjectMap.remove(aObj);
336   }
337
338   if (isUpdateViewer)
339     updateViewer();
340 }
341
342 void XGUI_Displayer::openLocalContext()
343 {
344   Handle(AIS_InteractiveContext) aContext = AISContext();
345   if (aContext.IsNull())
346     return;
347   // Open local context if there is no one
348   if (!aContext->HasOpenedContext()) {
349     // Preserve selected objects
350     //AIS_ListOfInteractive aAisList;
351     //for (aContext->InitCurrent(); aContext->MoreCurrent(); aContext->NextCurrent())
352     //  aAisList.Append(aContext->Current());
353
354     // get the filters from the global context and append them to the local context
355     // a list of filters in the global context is not cleared and should be cleared here
356     SelectMgr_ListOfFilter aFilters;
357     aFilters.Assign(aContext->Filters());
358     // it is important to remove the filters in the global context, because there is a code
359     // in the closeLocalContex, which restore the global context filters
360     aContext->RemoveFilters();
361
362     //aContext->ClearCurrents();
363     aContext->OpenLocalContext();
364
365     qDebug("### Open Local context");
366
367     aContext->NotUseDisplayedObjects();
368
369     myUseExternalObjects = false;
370     myActiveSelectionModes.clear();
371
372     SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
373     for (;aIt.More(); aIt.Next()) {
374       aContext->AddFilter(aIt.Value());
375     }
376     // Restore selection
377     //AIS_ListIteratorOfListOfInteractive aIt2(aAisList);
378     //for(; aIt2.More(); aIt2.Next()) {
379     //  aContext->SetSelected(aIt2.Value(), false);
380     //}
381   }
382 }
383
384 void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer)
385 {
386   Handle(AIS_InteractiveContext) aContext = AISContext();
387   if ( (!aContext.IsNull()) && (aContext->HasOpenedContext()) ) {
388     // Preserve selected objects
389     //AIS_ListOfInteractive aAisList;
390     //for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected())
391     //  aAisList.Append(aContext->SelectedInteractive());
392
393     // get the filters from the local context and append them to the global context
394     // a list of filters in the local context is cleared
395     SelectMgr_ListOfFilter aFilters;
396     aFilters.Assign(aContext->Filters());
397
398     //aContext->ClearSelected();
399     aContext->CloseAllContexts(false);
400
401     qDebug("### Close Local context");
402
403     // Redisplay all object if they were displayed in localContext
404     Handle(AIS_InteractiveObject) aAISIO;
405     foreach (AISObjectPtr aAIS, myResult2AISObjectMap) {
406       aAISIO = aAIS->impl<Handle(AIS_InteractiveObject)>();
407       if (aContext->DisplayStatus(aAISIO) != AIS_DS_Displayed) {
408         aContext->Display(aAISIO, false);
409         aContext->SetDisplayMode(aAISIO, Shading, false);
410       }
411     }
412
413     // Append the filters from the local selection in the global selection context
414     SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
415     for (;aIt.More(); aIt.Next()) {
416       Handle(SelectMgr_Filter) aFilter = aIt.Value();
417       aContext->AddFilter(aFilter);
418     }
419
420     if (isUpdateViewer)
421       updateViewer();
422     myUseExternalObjects = false;
423     myActiveSelectionModes.clear();
424
425     // Restore selection
426     //AIS_ListIteratorOfListOfInteractive aIt2(aAisList);
427     //for(; aIt2.More(); aIt2.Next()) {
428     //  if (aContext->IsDisplayed(aIt2.Value()))
429     //    aContext->SetCurrentObject(aIt2.Value(), false);
430     //}
431   }
432 }
433
434 AISObjectPtr XGUI_Displayer::getAISObject(ObjectPtr theObject) const
435 {
436   AISObjectPtr anIO;
437   if (myResult2AISObjectMap.contains(theObject))
438     anIO = myResult2AISObjectMap[theObject];
439   return anIO;
440 }
441
442 ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const
443 {
444   Handle(AIS_InteractiveObject) aRefAIS = theIO->impl<Handle(AIS_InteractiveObject)>();
445   return getObject(aRefAIS);
446 }
447
448 ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const
449 {
450   ObjectPtr aFeature;
451   foreach (ObjectPtr anObj, myResult2AISObjectMap.keys()) {
452     AISObjectPtr aAIS = myResult2AISObjectMap[anObj];
453     Handle(AIS_InteractiveObject) anAIS = aAIS->impl<Handle(AIS_InteractiveObject)>();
454     if (anAIS == theIO)
455       return anObj;
456   }
457   return aFeature;
458 }
459
460 void XGUI_Displayer::updateViewer()
461 {
462   Handle(AIS_InteractiveContext) aContext = AISContext();
463   if (!aContext.IsNull())
464     aContext->UpdateCurrentViewer();
465 }
466
467 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
468 {
469   return myWorkshop->viewer()->AISContext();
470 }
471
472 Handle(SelectMgr_AndFilter) XGUI_Displayer::GetFilter()
473 {
474   Handle(AIS_InteractiveContext) aContext = AISContext();
475   if (myAndFilter.IsNull() && !aContext.IsNull()) {
476     myAndFilter = new SelectMgr_AndFilter();
477     aContext->AddFilter(myAndFilter);
478   }
479   return myAndFilter;
480 }
481
482 void XGUI_Displayer::displayAIS(AISObjectPtr theAIS, bool isUpdate)
483 {
484   Handle(AIS_InteractiveContext) aContext = AISContext();
485   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
486   if (!anAISIO.IsNull()) {
487     aContext->Display(anAISIO, isUpdate);
488     if (aContext->HasOpenedContext()) {
489       if (myUseExternalObjects) {
490         aContext->Deactivate(anAISIO);
491         if (myActiveSelectionModes.size() == 0)
492           aContext->Activate(anAISIO);
493         else {
494           foreach(int aMode, myActiveSelectionModes) {
495             aContext->Activate(anAISIO, aMode);
496           }
497         }
498       }
499     }
500   }
501 }
502
503 void XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool isUpdate)
504 {
505   Handle(AIS_InteractiveContext) aContext = AISContext();
506   Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
507   if (!anAISIO.IsNull()) {
508     aContext->Remove(anAISIO, isUpdate);
509   }
510 }
511
512 void XGUI_Displayer::activateObjects(const QIntList& theModes)
513 {
514   Handle(AIS_InteractiveContext) aContext = AISContext();
515   // Open local context if there is no one
516   if (!aContext->HasOpenedContext()) 
517     return;
518
519   aContext->UseDisplayedObjects();
520   myUseExternalObjects = true;
521   myActiveSelectionModes = theModes;
522
523   //Deactivate trihedron which can be activated in local selector
524   AIS_ListOfInteractive aPrsList;
525   aContext->DisplayedObjects(aPrsList, true);
526
527   AIS_ListIteratorOfListOfInteractive aLIt(aPrsList);
528   Handle(AIS_InteractiveObject) anAISIO;
529   Handle(AIS_Trihedron) aTrihedron;
530   for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){
531     anAISIO = aLIt.Value();
532     aTrihedron = Handle(AIS_Trihedron)::DownCast(anAISIO);
533     aContext->Deactivate(anAISIO);
534     if (aTrihedron.IsNull())  {
535       aContext->Load(anAISIO, -1, true);
536       if (theModes.size() == 0)
537         aContext->Activate(anAISIO);
538       else {
539         foreach(int aMode, theModes) {
540           aContext->Activate(anAISIO, aMode);
541         }
542       }
543     }
544   }
545 }
546
547
548 void XGUI_Displayer::deactivateObjects()
549 {
550   Handle(AIS_InteractiveContext) aContext = AISContext();
551   // Open local context if there is no one
552   if (!aContext->HasOpenedContext()) 
553     return;
554
555   aContext->NotUseDisplayedObjects();
556 }
557
558
559 void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool toUpdate)
560 {
561   if (theMode == NoMode)
562     return;
563
564   Handle(AIS_InteractiveContext) aContext = AISContext();
565   if (aContext.IsNull())
566     return;
567
568   AISObjectPtr aAISObj = getAISObject(theObject);
569   if (!aAISObj)
570     return;
571
572   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
573   aContext->SetDisplayMode(aAISIO, theMode, toUpdate);
574 }
575
576 XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const
577 {
578   Handle(AIS_InteractiveContext) aContext = AISContext();
579   if (aContext.IsNull())
580     return NoMode;
581
582   AISObjectPtr aAISObj = getAISObject(theObject);
583   if (!aAISObj)
584     return NoMode;
585
586   Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
587   return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode();
588 }
589
590 void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
591 {
592   Handle(AIS_InteractiveContext) aContext = AISContext();
593   if (aContext.IsNull())
594     return;
595   const SelectMgr_ListOfFilter& aFilters = aContext->Filters();
596   SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
597   for (; aIt.More(); aIt.Next()) {
598     if (theFilter.Access() == aIt.Value().Access())
599       return;
600   }
601   GetFilter()->Add(theFilter);
602 }
603
604 void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
605 {
606   Handle(AIS_InteractiveContext) aContext = AISContext();
607   if (aContext.IsNull())
608     return;
609   GetFilter()->Remove(theFilter);
610 }
611
612 void XGUI_Displayer::removeFilters()
613 {
614   Handle(AIS_InteractiveContext) aContext = AISContext();
615   if (aContext.IsNull())
616     return;
617   GetFilter()->Clear();
618 }
619
620 void XGUI_Displayer::showOnly(const QObjectPtrList& theList)
621 {
622   QObjectPtrList aDispList = myResult2AISObjectMap.keys();
623   foreach(ObjectPtr aObj, aDispList) {
624     if (!theList.contains(aObj))
625       erase(aObj, false);
626   }
627   foreach(ObjectPtr aObj, theList) {
628     if (!isVisible(aObj))
629       display(aObj, false);
630   }
631   updateViewer();
632 }