1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: XGUI_Displayer.cpp
4 // Created: 20 Apr 2014
5 // Author: Natalia ERMOLAEVA
7 #include "XGUI_Displayer.h"
8 #include "XGUI_Workshop.h"
9 #include "XGUI_ViewerProxy.h"
10 #include "XGUI_SelectionMgr.h"
11 #include "XGUI_Selection.h"
13 #include <AppElements_Viewer.h>
15 #include <ModelAPI_Document.h>
16 #include <ModelAPI_Data.h>
17 #include <ModelAPI_Object.h>
18 #include <ModelAPI_Tools.h>
20 #include <ModuleBase_ResultPrs.h>
22 #include <GeomAPI_Shape.h>
23 #include <GeomAPI_IPresentable.h>
24 #include <GeomAPI_ICustomPrs.h>
26 #include <AIS_InteractiveContext.hxx>
27 #include <AIS_LocalContext.hxx>
28 #include <AIS_ListOfInteractive.hxx>
29 #include <AIS_ListIteratorOfListOfInteractive.hxx>
30 #include <AIS_DimensionSelectionMode.hxx>
31 #include <AIS_Shape.hxx>
32 #include <AIS_Dimension.hxx>
33 #include <TColStd_ListIteratorOfListOfInteger.hxx>
34 #include <SelectMgr_ListOfFilter.hxx>
35 #include <SelectMgr_ListIteratorOfListOfFilter.hxx>
37 #include <TColStd_MapOfTransient.hxx>
38 #include <TColStd_MapIteratorOfMapOfTransient.hxx>
42 const int MOUSE_SENSITIVITY_IN_PIXEL = 10; ///< defines the local context mouse selection sensitivity
45 // Workaround for bug #25637
46 void displayedObjects(const Handle(AIS_InteractiveContext)& theAIS, AIS_ListOfInteractive& theList)
48 // Get from null point
49 theAIS->DisplayedObjects(theList, true);
50 if (theAIS->HasOpenedContext()) {
51 // get from local context
52 const Handle(AIS_LocalContext)& aLC = theAIS->LocalContext();
53 TColStd_MapOfTransient aMap;
54 int NbDisp = aLC->DisplayedObjects(aMap);
55 TColStd_MapIteratorOfMapOfTransient aIt(aMap);
57 Handle(AIS_InteractiveObject) curIO;
58 Handle(Standard_Transient) Tr;
59 for(; aIt.More(); aIt.Next()){
61 curIO = *((Handle(AIS_InteractiveObject)*) &Tr);
62 theList.Append(curIO);
68 XGUI_Displayer::XGUI_Displayer(XGUI_Workshop* theWorkshop)
69 : myWorkshop(theWorkshop)
73 XGUI_Displayer::~XGUI_Displayer()
77 bool XGUI_Displayer::isVisible(ObjectPtr theObject) const
79 return myResult2AISObjectMap.contains(theObject);
82 void XGUI_Displayer::display(ObjectPtr theObject, bool isUpdateViewer)
84 if (isVisible(theObject)) {
85 redisplay(theObject, isUpdateViewer);
89 GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
90 bool isShading = false;
91 if (aPrs.get() != NULL) {
92 anAIS = aPrs->getAISObject(AISObjectPtr());
94 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
95 if (aResult.get() != NULL) {
96 std::shared_ptr<GeomAPI_Shape> aShapePtr = ModelAPI_Tools::shape(aResult);
97 if (aShapePtr.get() != NULL) {
98 anAIS = AISObjectPtr(new GeomAPI_AISObject());
99 anAIS->setImpl(new Handle(AIS_InteractiveObject)(new ModuleBase_ResultPrs(aResult)));
100 //anAIS->createShape(aShapePtr);
106 display(theObject, anAIS, isShading, isUpdateViewer);
110 bool canBeShaded(Handle(AIS_InteractiveObject) theAIS)
112 Handle(AIS_Shape) aShapePrs = Handle(AIS_Shape)::DownCast(theAIS);
113 if (!aShapePrs.IsNull()) {
114 TopoDS_Shape aShape = aShapePrs->Shape();
115 TopAbs_ShapeEnum aType = aShape.ShapeType();
116 if ((aType == TopAbs_VERTEX) || (aType == TopAbs_EDGE) || (aType == TopAbs_WIRE))
124 void XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS,
125 bool isShading, bool isUpdateViewer)
127 Handle(AIS_InteractiveContext) aContext = AISContext();
128 if (aContext.IsNull())
131 Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
132 if (!anAISIO.IsNull()) {
133 myResult2AISObjectMap[theObject] = theAIS;
134 bool aCanBeShaded = ::canBeShaded(anAISIO);
135 // In order to avoid extra closing/opening context
136 SelectMgr_IndexedMapOfOwner aSelectedOwners;
138 myWorkshop->selector()->selection()->selectedOwners(aSelectedOwners);
139 closeLocalContexts(false);
141 aContext->Display(anAISIO, false);
142 qDebug("### Display %i", (long)anAISIO.Access());
144 aContext->SetDisplayMode(anAISIO, isShading? Shading : Wireframe, false);
145 // Customization of presentation
146 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
147 if (aFeature.get() != NULL) {
148 GeomCustomPrsPtr aCustPrs = std::dynamic_pointer_cast<GeomAPI_ICustomPrs>(aFeature);
149 if (aCustPrs.get() != NULL)
150 aCustPrs->customisePresentation(theAIS);
154 activateObjects(myActiveSelectionModes);
155 myWorkshop->selector()->setSelectedOwners(aSelectedOwners);
162 void XGUI_Displayer::erase(ObjectPtr theObject, const bool isUpdateViewer)
164 if (!isVisible(theObject))
167 Handle(AIS_InteractiveContext) aContext = AISContext();
168 if (aContext.IsNull())
170 AISObjectPtr anObject = myResult2AISObjectMap[theObject];
172 Handle(AIS_InteractiveObject) anAIS = anObject->impl<Handle(AIS_InteractiveObject)>();
173 if (!anAIS.IsNull()) {
174 aContext->Remove(anAIS, isUpdateViewer);
177 myResult2AISObjectMap.remove(theObject);
180 void XGUI_Displayer::redisplay(ObjectPtr theObject, bool isUpdateViewer)
182 if (!isVisible(theObject))
185 AISObjectPtr aAISObj = getAISObject(theObject);
186 Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
188 GeomPresentablePtr aPrs = std::dynamic_pointer_cast<GeomAPI_IPresentable>(theObject);
190 AISObjectPtr aAIS_Obj = aPrs->getAISObject(aAISObj);
192 erase(theObject, isUpdateViewer);
195 if (aAIS_Obj != aAISObj) {
196 myResult2AISObjectMap[theObject] = aAIS_Obj;
198 aAISIO = aAIS_Obj->impl<Handle(AIS_InteractiveObject)>();
201 if (!aAISIO.IsNull()) {
202 Handle(AIS_InteractiveContext) aContext = AISContext();
203 if (aContext.IsNull())
205 bool aToSelect = aContext->IsSelected(aAISIO);
206 aContext->Redisplay(aAISIO, false);
207 // Restore selection state after redisplay
209 aContext->SetSelected(aAISIO);
215 void XGUI_Displayer::deactivate(ObjectPtr theObject)
217 if (isVisible(theObject)) {
218 Handle(AIS_InteractiveContext) aContext = AISContext();
219 if (aContext.IsNull())
222 AISObjectPtr anObj = myResult2AISObjectMap[theObject];
223 Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
224 aContext->Deactivate(anAIS);
225 qDebug("### Deactivate obj %i", (long)anAIS.Access());
229 void XGUI_Displayer::activate(ObjectPtr theFeature)
231 activate(theFeature, myActiveSelectionModes);
234 void XGUI_Displayer::activate(ObjectPtr theObject, const QIntList& theModes)
236 if (isVisible(theObject)) {
237 Handle(AIS_InteractiveContext) aContext = AISContext();
238 if (aContext.IsNull())
241 AISObjectPtr anObj = myResult2AISObjectMap[theObject];
242 Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
243 aContext->Deactivate(anAIS);
244 aContext->Load(anAIS, -1, true);
245 // In order to clear active modes list
246 if (theModes.size() > 0) {
247 foreach(int aMode, theModes) {
248 //aContext->Load(anAIS, aMode, true);
249 aContext->Activate(anAIS, aMode);
250 qDebug("### 1. Activate obj %i, %i", (long)anAIS.Access(), aMode);
253 //aContext->Load(anAIS, 0, true);
254 aContext->Activate(anAIS);
255 qDebug("### 2. Activate obj %i", (long)anAIS.Access());
260 void XGUI_Displayer::getModesOfActivation(ObjectPtr theObject, QIntList& theModes)
262 if (!isVisible(theObject))
265 Handle(AIS_InteractiveContext) aContext = AISContext();
266 if (aContext.IsNull())
269 AISObjectPtr aAISObj = getAISObject(theObject);
271 if (aAISObj.get() != NULL) {
272 Handle(AIS_InteractiveObject) anAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
273 TColStd_ListOfInteger aTColModes;
274 aContext->ActivatedModes(anAISIO, aTColModes);
275 TColStd_ListIteratorOfListOfInteger itr( aTColModes );
276 for (; itr.More(); itr.Next() ) {
277 theModes.append(itr.Value());
282 void XGUI_Displayer::activateObjects(const QIntList& theModes)
284 // In order to avoid doblications of selection modes
286 foreach (int aMode, theModes) {
287 if (!aNewModes.contains(aMode))
288 aNewModes.append(aMode);
290 myActiveSelectionModes = aNewModes;
291 Handle(AIS_InteractiveContext) aContext = AISContext();
292 // Open local context if there is no one
293 if (!aContext->HasOpenedContext())
296 //aContext->UseDisplayedObjects();
297 //myUseExternalObjects = true;
299 AIS_ListOfInteractive aPrsList;
300 displayedObjects(aContext, aPrsList);
302 Handle(AIS_Trihedron) aTrihedron;
303 AIS_ListIteratorOfListOfInteractive aLIt(aPrsList);
304 Handle(AIS_InteractiveObject) anAISIO;
305 for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){
306 anAISIO = aLIt.Value();
307 aContext->Load(anAISIO, -1, true);
308 aContext->Deactivate(anAISIO);
309 aTrihedron = Handle(AIS_Trihedron)::DownCast(anAISIO);
310 //Deactivate trihedron which can be activated in local selector
311 if (aTrihedron.IsNull()) {
312 //aContext->Load(anAISIO, -1, true);
313 // In order to clear active modes list
314 if (myActiveSelectionModes.size() == 0) {
315 //aContext->Load(anAISIO, 0, true);
316 aContext->Activate(anAISIO);
317 qDebug("### 2. Activate all %i", (long)anAISIO.Access());
319 foreach(int aMode, myActiveSelectionModes) {
320 //aContext->Load(anAISIO, aMode, true);
321 aContext->Activate(anAISIO, aMode);
322 qDebug("### 1. Activate all %i, %i", (long)anAISIO.Access(), aMode);
330 void XGUI_Displayer::deactivateObjects()
332 myActiveSelectionModes.clear();
333 Handle(AIS_InteractiveContext) aContext = AISContext();
334 // Open local context if there is no one
335 if (!aContext->HasOpenedContext())
338 //aContext->NotUseDisplayedObjects();
339 AIS_ListOfInteractive aPrsList;
340 displayedObjects(aContext, aPrsList);
342 AIS_ListIteratorOfListOfInteractive aLIt;
343 //Handle(AIS_Trihedron) aTrihedron;
344 Handle(AIS_InteractiveObject) anAISIO;
345 for(aLIt.Initialize(aPrsList); aLIt.More(); aLIt.Next()){
346 anAISIO = aLIt.Value();
347 aContext->Deactivate(anAISIO);
348 //aTrihedron = Handle(AIS_Trihedron)::DownCast(anAISIO);
349 //if (aTrihedron.IsNull()) {
350 // qDebug("### Deactivate all %i", (long)anAISIO.Access());
351 // //aContext->Activate(anAISIO);
356 bool XGUI_Displayer::isActive(ObjectPtr theObject) const
358 Handle(AIS_InteractiveContext) aContext = AISContext();
359 if (aContext.IsNull())
361 if (!isVisible(theObject))
364 AISObjectPtr anObj = myResult2AISObjectMap[theObject];
365 Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
367 TColStd_ListOfInteger aModes;
368 aContext->ActivatedModes(anAIS, aModes);
369 return aModes.Extent() > 0;
372 void XGUI_Displayer::setSelected(const QObjectPtrList& theResults, const bool isUpdateViewer)
374 Handle(AIS_InteractiveContext) aContext = AISContext();
375 if (aContext.IsNull())
377 if (aContext->HasOpenedContext()) {
378 aContext->UnhilightSelected();
379 aContext->ClearSelected();
380 foreach(ObjectPtr aResult, theResults) {
381 if (isVisible(aResult)) {
382 AISObjectPtr anObj = myResult2AISObjectMap[aResult];
383 Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
385 aContext->SetSelected(anAIS, false);
389 aContext->UnhilightCurrents();
390 aContext->ClearCurrents();
391 foreach(ObjectPtr aResult, theResults) {
392 if (isVisible(aResult)) {
393 AISObjectPtr anObj = myResult2AISObjectMap[aResult];
394 Handle(AIS_InteractiveObject) anAIS = anObj->impl<Handle(AIS_InteractiveObject)>();
396 aContext->SetCurrentObject(anAIS, false);
405 void XGUI_Displayer::clearSelected()
407 Handle(AIS_InteractiveContext) aContext = AISContext();
409 aContext->UnhilightCurrents(false);
410 aContext->ClearSelected();
414 void XGUI_Displayer::eraseAll(const bool isUpdateViewer)
416 Handle(AIS_InteractiveContext) aContext = AISContext();
417 if (aContext.IsNull())
420 foreach (AISObjectPtr aAISObj, myResult2AISObjectMap) {
422 Handle(AIS_InteractiveObject) anIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
424 aContext->Remove(anIO, false);
426 myResult2AISObjectMap.clear();
431 void XGUI_Displayer::openLocalContext()
433 Handle(AIS_InteractiveContext) aContext = AISContext();
434 if (aContext.IsNull())
436 // Open local context if there is no one
437 if (!aContext->HasOpenedContext()) {
438 // Preserve selected objects
439 //AIS_ListOfInteractive aAisList;
440 //for (aContext->InitCurrent(); aContext->MoreCurrent(); aContext->NextCurrent())
441 // aAisList.Append(aContext->Current());
443 // get the filters from the global context and append them to the local context
444 // a list of filters in the global context is not cleared and should be cleared here
445 SelectMgr_ListOfFilter aFilters;
446 aFilters.Assign(aContext->Filters());
447 // it is important to remove the filters in the global context, because there is a code
448 // in the closeLocalContex, which restore the global context filters
449 aContext->RemoveFilters();
451 //aContext->ClearCurrents();
452 aContext->OpenLocalContext();
453 qDebug("### Open context");
454 //aContext->NotUseDisplayedObjects();
456 //myUseExternalObjects = false;
458 SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
459 for (;aIt.More(); aIt.Next()) {
460 aContext->AddFilter(aIt.Value());
463 //AIS_ListIteratorOfListOfInteractive aIt2(aAisList);
464 //for(; aIt2.More(); aIt2.Next()) {
465 // aContext->SetSelected(aIt2.Value(), false);
470 void XGUI_Displayer::closeLocalContexts(const bool isUpdateViewer)
472 Handle(AIS_InteractiveContext) aContext = AISContext();
473 if ( (!aContext.IsNull()) && (aContext->HasOpenedContext()) ) {
474 // Preserve selected objects
475 //AIS_ListOfInteractive aAisList;
476 //for (aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected())
477 // aAisList.Append(aContext->SelectedInteractive());
479 // get the filters from the local context and append them to the global context
480 // a list of filters in the local context is cleared
481 SelectMgr_ListOfFilter aFilters;
482 aFilters.Assign(aContext->Filters());
484 //aContext->ClearSelected();
485 aContext->CloseAllContexts(false);
486 qDebug("### Close context");
488 // Redisplay all object if they were displayed in localContext
489 Handle(AIS_InteractiveObject) aAISIO;
490 foreach (AISObjectPtr aAIS, myResult2AISObjectMap) {
491 aAISIO = aAIS->impl<Handle(AIS_InteractiveObject)>();
492 if (aContext->DisplayStatus(aAISIO) != AIS_DS_Displayed) {
493 aContext->Display(aAISIO, false);
494 aContext->SetDisplayMode(aAISIO, Shading, false);
498 // Append the filters from the local selection in the global selection context
499 SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
500 for (;aIt.More(); aIt.Next()) {
501 Handle(SelectMgr_Filter) aFilter = aIt.Value();
502 aContext->AddFilter(aFilter);
507 //myUseExternalObjects = false;
510 //AIS_ListIteratorOfListOfInteractive aIt2(aAisList);
511 //for(; aIt2.More(); aIt2.Next()) {
512 // if (aContext->IsDisplayed(aIt2.Value()))
513 // aContext->SetCurrentObject(aIt2.Value(), false);
518 AISObjectPtr XGUI_Displayer::getAISObject(ObjectPtr theObject) const
521 if (myResult2AISObjectMap.contains(theObject))
522 anIO = myResult2AISObjectMap[theObject];
526 ObjectPtr XGUI_Displayer::getObject(const AISObjectPtr& theIO) const
528 Handle(AIS_InteractiveObject) aRefAIS = theIO->impl<Handle(AIS_InteractiveObject)>();
529 return getObject(aRefAIS);
532 ObjectPtr XGUI_Displayer::getObject(const Handle(AIS_InteractiveObject)& theIO) const
535 foreach (ObjectPtr anObj, myResult2AISObjectMap.keys()) {
536 AISObjectPtr aAIS = myResult2AISObjectMap[anObj];
537 Handle(AIS_InteractiveObject) anAIS = aAIS->impl<Handle(AIS_InteractiveObject)>();
544 void XGUI_Displayer::updateViewer()
546 Handle(AIS_InteractiveContext) aContext = AISContext();
547 if (!aContext.IsNull())
548 aContext->UpdateCurrentViewer();
551 Handle(AIS_InteractiveContext) XGUI_Displayer::AISContext() const
553 Handle(AIS_InteractiveContext) aContext = myWorkshop->viewer()->AISContext();
554 if ((!aContext.IsNull()) && (!aContext->HasOpenedContext())) {
555 aContext->OpenLocalContext();
556 qDebug("### Open context");
561 Handle(SelectMgr_AndFilter) XGUI_Displayer::GetFilter()
563 Handle(AIS_InteractiveContext) aContext = AISContext();
564 if (myAndFilter.IsNull() && !aContext.IsNull()) {
565 myAndFilter = new SelectMgr_AndFilter();
566 aContext->AddFilter(myAndFilter);
571 void XGUI_Displayer::displayAIS(AISObjectPtr theAIS, bool isUpdate)
573 Handle(AIS_InteractiveContext) aContext = AISContext();
574 Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
575 if (!anAISIO.IsNull()) {
576 aContext->Display(anAISIO, isUpdate);
577 if (aContext->HasOpenedContext()) {
578 //if (myUseExternalObjects) {
579 if (myActiveSelectionModes.size() == 0)
580 aContext->Activate(anAISIO);
582 foreach(int aMode, myActiveSelectionModes) {
583 aContext->Activate(anAISIO, aMode);
591 void XGUI_Displayer::eraseAIS(AISObjectPtr theAIS, const bool isUpdate)
593 Handle(AIS_InteractiveContext) aContext = AISContext();
594 Handle(AIS_InteractiveObject) anAISIO = theAIS->impl<Handle(AIS_InteractiveObject)>();
595 if (!anAISIO.IsNull()) {
596 aContext->Remove(anAISIO, isUpdate);
601 void XGUI_Displayer::setDisplayMode(ObjectPtr theObject, DisplayMode theMode, bool toUpdate)
603 if (theMode == NoMode)
606 Handle(AIS_InteractiveContext) aContext = AISContext();
607 if (aContext.IsNull())
610 AISObjectPtr aAISObj = getAISObject(theObject);
614 Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
615 bool aCanBeShaded = ::canBeShaded(aAISIO);
616 // In order to avoid extra closing/opening context
618 closeLocalContexts(false);
619 aContext->SetDisplayMode(aAISIO, theMode, toUpdate);
622 activateObjects(myActiveSelectionModes);
626 XGUI_Displayer::DisplayMode XGUI_Displayer::displayMode(ObjectPtr theObject) const
628 Handle(AIS_InteractiveContext) aContext = AISContext();
629 if (aContext.IsNull())
632 AISObjectPtr aAISObj = getAISObject(theObject);
636 Handle(AIS_InteractiveObject) aAISIO = aAISObj->impl<Handle(AIS_InteractiveObject)>();
637 return (XGUI_Displayer::DisplayMode) aAISIO->DisplayMode();
640 void XGUI_Displayer::addSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
642 Handle(AIS_InteractiveContext) aContext = AISContext();
643 if (aContext.IsNull())
645 const SelectMgr_ListOfFilter& aFilters = aContext->Filters();
646 SelectMgr_ListIteratorOfListOfFilter aIt(aFilters);
647 for (; aIt.More(); aIt.Next()) {
648 if (theFilter.Access() == aIt.Value().Access())
651 GetFilter()->Add(theFilter);
654 void XGUI_Displayer::removeSelectionFilter(const Handle(SelectMgr_Filter)& theFilter)
656 Handle(AIS_InteractiveContext) aContext = AISContext();
657 if (aContext.IsNull())
659 GetFilter()->Remove(theFilter);
662 void XGUI_Displayer::removeFilters()
664 Handle(AIS_InteractiveContext) aContext = AISContext();
665 if (aContext.IsNull())
667 GetFilter()->Clear();
670 void XGUI_Displayer::showOnly(const QObjectPtrList& theList)
672 QObjectPtrList aDispList = myResult2AISObjectMap.keys();
673 foreach(ObjectPtr aObj, aDispList) {
674 if (!theList.contains(aObj))
677 foreach(ObjectPtr aObj, theList) {
678 if (!isVisible(aObj))
679 display(aObj, false);
684 bool XGUI_Displayer::canBeShaded(ObjectPtr theObject) const
686 if (!isVisible(theObject))
689 AISObjectPtr aAISObj = getAISObject(theObject);
690 if (aAISObj.get() == NULL)
693 Handle(AIS_InteractiveObject) anAIS = aAISObj->impl<Handle(AIS_InteractiveObject)>();
694 return ::canBeShaded(anAIS);