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