Salome HOME
Prevent usage of uninitialized variable
[modules/shaper.git] / src / XGUI / XGUI_FacesPanel.cpp
1 // Copyright (C) 2014-2021  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "XGUI_FacesPanel.h"
21 #include "XGUI_ObjectsBrowser.h"
22 #include "XGUI_SelectionMgr.h"
23 #include "XGUI_Selection.h"
24 #include "XGUI_Tools.h"
25 #include "XGUI_Workshop.h"
26 #include "XGUI_Displayer.h"
27 #include "XGUI_ViewerProxy.h"
28
29 #include <ModuleBase_IModule.h>
30 #include <ModuleBase_ISelection.h>
31 #include <ModuleBase_IWorkshop.h>
32 #include <ModuleBase_IViewer.h>
33 #include <ModuleBase_ListView.h>
34 #include <ModuleBase_ResultPrs.h>
35 #include <ModuleBase_Tools.h>
36 #include <ModuleBase_ViewerPrs.h>
37 #include <ModuleBase_SelectionFilterType.h>
38
39 #include <Config_PropManager.h>
40 #include <Events_Loop.h>
41 #include <GeomAlgoAPI_CompoundBuilder.h>
42 #include <GeomAPI_Shape.h>
43
44 #include <ModelAPI_Events.h>
45 #include <ModelAPI_AttributeSelectionList.h>
46
47 #include <ModuleBase_Operation.h>
48 #include <ModuleBase_OperationFeature.h>
49 #include <XGUI_OperationMgr.h>
50
51 #include <QAction>
52 #include <QCheckBox>
53 #include <QFocusEvent>
54 #include <QGridLayout>
55 #include <QListWidget>
56 #include <QMainWindow>
57 #include <QTimer>
58
59 static const int LayoutMargin = 3;
60
61 //********************************************************************
62 bool getGroup(ModuleBase_ViewerPrsPtr thePrs, ResultGroupPtr& theResGroup,
63   FeaturePtr& theGroupFeature)
64 {
65   ObjectPtr anObject = thePrs->object();
66   if (!anObject.get())
67     return false;
68
69   theResGroup = std::dynamic_pointer_cast<ModelAPI_ResultGroup>(anObject);
70   if (theResGroup.get()) {
71     theGroupFeature = ModelAPI_Feature::feature(theResGroup);
72   }
73   else {
74     theGroupFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
75     if (theGroupFeature.get())
76       theResGroup = std::dynamic_pointer_cast<ModelAPI_ResultGroup>(theGroupFeature->firstResult());
77   }
78   return theGroupFeature.get() && theResGroup.get();
79 }
80
81 //********************************************************************
82 void updateHiddenShapes(Handle(ModuleBase_ResultPrs) thePrs, const TopoDS_ListOfShape& theShapes)
83 {
84   TopoDS_ListOfShape aAlreadyHidden = thePrs->hiddenSubShapes();
85   TopoDS_ListOfShape::Iterator aShPIt(theShapes);
86   for (; aShPIt.More(); aShPIt.Next()) {
87     if (aAlreadyHidden.Contains(aShPIt.Value()))
88       aAlreadyHidden.Remove(aShPIt.Value());
89   }
90   thePrs->setSubShapeHidden(aAlreadyHidden);
91 }
92
93 //********************************************************************
94 XGUI_FacesPanel::XGUI_FacesPanel(QWidget* theParent, XGUI_Workshop* theWorkshop)
95   : QDockWidget(theParent), myWorkshop(theWorkshop), myIsActive(false), myLastItemIndex(0)
96 {
97   setWindowTitle(tr("Hide Faces"));
98   setObjectName("Hide Faces");
99
100   MAYBE_UNUSED QAction* aViewAct = toggleViewAction();
101   setStyleSheet("::title { position: relative; padding-left: 5px; text-align: left center }");
102
103   QWidget* aContent = new QWidget(this);
104   QGridLayout* aMainLayout = new QGridLayout(aContent);
105   aMainLayout->setContentsMargins(LayoutMargin, LayoutMargin, LayoutMargin, LayoutMargin);
106   setWidget(aContent);
107
108   myHiddenOrTransparent = new QCheckBox(tr("Transparent"), aContent);
109   connect(myHiddenOrTransparent, SIGNAL(toggled(bool)), SLOT(onTransparencyChanged()));
110
111   myListView = new ModuleBase_ListView(aContent, "", "Hidden/transparent faces in 3D view");
112   connect(myListView, SIGNAL(deleteActionClicked()), SLOT(onDeleteItem()));
113
114   aMainLayout->addWidget(myHiddenOrTransparent, 0, 0);
115   aMainLayout->addWidget(myListView->getControl(), 1, 0);
116
117   myListView->getControl()->setFocusPolicy(Qt::StrongFocus);
118   myListView->getControl()->viewport()->installEventFilter(this);
119
120   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
121   connect(aDisplayer, SIGNAL(objectDisplayed(ObjectPtr, AISObjectPtr)),
122     SLOT(onObjectDisplay(ObjectPtr, AISObjectPtr)));
123 }
124
125 //********************************************************************
126 void XGUI_FacesPanel::reset(const bool isToFlushRedisplay)
127 {
128   if (myLastItemIndex == 0) // do nothing because there was no activity in the pane after reset
129     return;
130
131   std::map<ObjectPtr, TopoDS_ListOfShape> anObjectToShapes;
132   std::map<ObjectPtr, Handle(ModuleBase_ResultPrs) > anObjectToPrs;
133   QMap<int, ModuleBase_ViewerPrsPtr >::const_iterator aIt;
134   for (aIt = myItems.cbegin(); aIt != myItems.cend(); aIt++) {
135     getObjectsMapFromPrs(aIt.value(), anObjectToShapes, anObjectToPrs);
136   }
137
138   std::set<ObjectPtr> aObjects;
139   TopoDS_ListOfShape anEmpty;
140   std::map<ObjectPtr, Handle(ModuleBase_ResultPrs)>::const_iterator aPrsIt;
141   for (aPrsIt = anObjectToPrs.cbegin(); aPrsIt != anObjectToPrs.cend(); aPrsIt++) {
142     aObjects.insert(aPrsIt->first);
143     aPrsIt->second->setSubShapeHidden(anEmpty);
144   }
145   std::set<ObjectPtr >::const_iterator aGrpIt;
146   for (aGrpIt = myHiddenGroups.cbegin(); aGrpIt != myHiddenGroups.cend(); aGrpIt++)
147     (*aGrpIt)->setDisplayed(true);
148   myHiddenGroups.clear();
149
150   if (redisplayObjects(aObjects))
151     flushRedisplay();
152
153   // clear internal containers
154   myListView->getControl()->clear();
155   myItems.clear();
156   updateProcessedObjects(myItems, myItemObjects);
157   myLastItemIndex = 0; // it should be after redisplay as flag used in customize
158   myHiddenObjects.clear();
159 }
160
161 //********************************************************************
162 bool XGUI_FacesPanel::isEmpty() const
163 {
164   return myItems.size() == 0;
165 }
166
167 //********************************************************************
168 void XGUI_FacesPanel::selectionModes(QIntList& theModes)
169 {
170   theModes.append(TopAbs_FACE);
171 }
172
173 //********************************************************************
174 void XGUI_FacesPanel::selectionFilters(SelectMgr_ListOfFilter& theSelectionFilters)
175 {
176   ModuleBase_IModule* aModule = myWorkshop->module();
177   QIntList aModuleSelectionFilters = myWorkshop->module()->selectionFilters();
178
179   // The global filter makes problem for groups selection when any operation is launched
180   // theSelectionFilters.Append(aModule->selectionFilter(SF_GlobalFilter));
181   theSelectionFilters.Append(aModule->selectionFilter(SF_FilterInfinite));
182   theSelectionFilters.Append(aModule->selectionFilter(SF_ResultGroupNameFilter));
183 }
184
185 //********************************************************************
186 bool XGUI_FacesPanel::eventFilter(QObject* theObject, QEvent *theEvent)
187 {
188   QWidget* aWidget = qobject_cast<QWidget*>(theObject);
189   if (theEvent->type() == QEvent::MouseButtonRelease)
190   {
191     if (myListView->getControl()->viewport() == aWidget)
192       setActivePanel(true);
193   }
194   // pass the event on to the parent class
195   return QObject::eventFilter(theObject, theEvent);
196 }
197
198 //********************************************************************
199 void XGUI_FacesPanel::setActivePanel(const bool theIsActive)
200 {
201   if (myIsActive == theIsActive)
202     return;
203
204   ModuleBase_Tools::setShadowEffect(myListView->getControl(), theIsActive);
205   myIsActive = theIsActive;
206
207   if (myIsActive) {
208     emit activated();
209     // selection should be cleared after emit of signal to do not process selection change
210     // event by the previous selector
211     // the selection is cleared by activating selection control
212     myWorkshop->selector()->clearSelection();
213   }
214   else{
215     emit deactivated();
216     myUndoList.clear();
217   }
218 }
219
220 //********************************************************************
221 bool XGUI_FacesPanel::useTransparency() const
222 {
223   return myHiddenOrTransparent->isChecked();
224 }
225
226 //********************************************************************
227 double XGUI_FacesPanel::transparency() const
228 {
229   return useTransparency() ?
230     Config_PropManager::real("Visualization", "hidden_face_transparency") : 1;
231 }
232
233
234 //********************************************************************
235 void XGUI_FacesPanel::restoreObjects(const std::set<ObjectPtr>& theHiddenObjects)
236 {
237   std::set<int> anIndicesToBeRemoved;
238   for (QMap<int, ModuleBase_ViewerPrsPtr>::const_iterator anItemsIt = myItems.begin();
239     anItemsIt != myItems.end(); anItemsIt++)
240   {
241     ModuleBase_ViewerPrsPtr aPrs = anItemsIt.value();
242     ObjectPtr anObject = aPrs->object();
243     if (theHiddenObjects.find(anObject) == theHiddenObjects.end()) // not found
244       continue;
245     anIndicesToBeRemoved.insert(anItemsIt.key());
246   }
247
248   // remove from myItes container
249   removeItems(anIndicesToBeRemoved);
250   if (!anIndicesToBeRemoved.empty()) // means that myItems has been changed
251     updateProcessedObjects(myItems, myItemObjects);
252
253   // remove from container of hidden objects
254   for (std::set<ObjectPtr>::const_iterator aHiddenIt = theHiddenObjects.begin();
255     aHiddenIt != theHiddenObjects.end(); aHiddenIt++)
256   {
257     if (myHiddenObjects.find(*aHiddenIt) != myHiddenObjects.end()) /// found objects
258       myHiddenObjects.erase(*aHiddenIt);
259   }
260 }
261
262 //********************************************************************
263 bool XGUI_FacesPanel::processAction(ModuleBase_ActionType theActionType)
264 {
265   switch (theActionType) {
266     //case ActionEnter:
267     //  return processEnter();
268     case ActionEscape:
269       setActivePanel(false);
270       return true;
271     case ActionDelete:
272       return processDelete();
273     //case ActionUndo:
274     //case ActionRedo:
275     default:
276       return false;
277   }
278 }
279
280 //********************************************************************
281 void XGUI_FacesPanel::getObjectsMapFromResult(ResultGroupPtr theResGroup,
282   FeaturePtr theGroupFeature,
283   std::map<ObjectPtr, TopoDS_ListOfShape>& theObjectToShapes,
284   std::map<ObjectPtr, Handle(ModuleBase_ResultPrs) >& theObjectToPrs)
285 {
286   XGUI_Displayer* aDisplayer = myWorkshop->displayer();
287   // Process a grouip result
288   AttributeSelectionListPtr aSelectionList = theGroupFeature->selectionList("group_list");
289   AISObjectPtr aPrs;
290   for (int i = 0; i < aSelectionList->size(); i++) {
291     AttributeSelectionPtr aSelection = aSelectionList->value(i);
292     ResultPtr aRes = aSelection->context();
293     aPrs = aDisplayer->getAISObject(aRes);
294     if (aPrs.get()) {
295       Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast(
296         aPrs->impl<Handle(AIS_InteractiveObject)>());
297       if (!aResultPrs.IsNull()) {
298         GeomShapePtr aShape = aSelection->value();
299         if (theObjectToShapes.find(aRes) != theObjectToShapes.end())
300           theObjectToShapes.at(aRes).Append(aShape->impl<TopoDS_Shape>());
301         else {
302           TopoDS_ListOfShape aListOfShapes;
303           aListOfShapes.Append(aShape->impl<TopoDS_Shape>());
304           theObjectToShapes[aRes] = aListOfShapes;
305           theObjectToPrs[aRes] = aResultPrs;
306         }
307       }
308     }
309   }
310 }
311
312 //********************************************************************
313 void objectsMapFromPrs(ModuleBase_ViewerPrsPtr thePrs,
314   std::map<ObjectPtr, TopoDS_ListOfShape>& theObjectToShapes,
315   std::map<ObjectPtr, Handle(ModuleBase_ResultPrs) >& theObjectToPrs)
316 {
317   ObjectPtr anObject = thePrs->object();
318   if (!anObject.get())
319     return;
320
321   // Process bodies
322   Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast(
323     thePrs->interactive());
324   if (aResultPrs.IsNull())
325     return;
326
327   if (theObjectToShapes.find(anObject) != theObjectToShapes.end())
328     theObjectToShapes.at(anObject).Append(ModuleBase_Tools::getSelectedShape(thePrs));
329   else {
330     TopoDS_ListOfShape aListOfShapes;
331     aListOfShapes.Append(ModuleBase_Tools::getSelectedShape(thePrs));
332     theObjectToShapes[anObject] = aListOfShapes;
333     theObjectToPrs[anObject] = aResultPrs;
334   }
335 }
336
337 //********************************************************************
338 void XGUI_FacesPanel::getObjectsMapFromPrs(ModuleBase_ViewerPrsPtr thePrs,
339   std::map<ObjectPtr, TopoDS_ListOfShape>& theObjectToShapes,
340   std::map<ObjectPtr, Handle(ModuleBase_ResultPrs) >& theObjectToPrs)
341 {
342   ResultGroupPtr aResGroup;
343   FeaturePtr aGroupFeature;
344   if (getGroup(thePrs, aResGroup, aGroupFeature))
345     getObjectsMapFromResult(aResGroup, aGroupFeature, theObjectToShapes, theObjectToPrs);
346   else
347     objectsMapFromPrs(thePrs, theObjectToShapes, theObjectToPrs);
348 }
349
350 //********************************************************************
351 void XGUI_FacesPanel::processSelection()
352 {
353   QList<ModuleBase_ViewerPrsPtr> aSelected =
354     myWorkshop->selector()->selection()->getSelected(ModuleBase_ISelection::Viewer);
355
356   if (aSelected.size() == 0)
357     return;
358
359   bool isModified = false;
360   static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
361
362   std::map<ObjectPtr, TopoDS_ListOfShape> anObjectToShapes;
363   std::map<ObjectPtr, Handle(ModuleBase_ResultPrs) > anObjectToPrs;
364   std::set<int> aToRemove;
365
366   for (int i = 0; i < aSelected.size(); i++) {
367     ModuleBase_ViewerPrsPtr aPrs = aSelected[i];
368     ObjectPtr anObject = aPrs->object();
369     if (!anObject.get())
370       continue;
371
372     ResultGroupPtr aResGroup;
373     FeaturePtr aGroupFeature;
374     if (getGroup(aPrs, aResGroup, aGroupFeature)) {
375       AttributeSelectionListPtr aSelectionListAttr =
376         aGroupFeature->data()->selectionList("group_list");
377       std::string aType = aSelectionListAttr->selectionType();
378       if (aType != "Faces")
379         continue;
380     }
381     else {
382       GeomShapePtr aShapePtr = aPrs->shape();
383       if (!aShapePtr.get() || !aShapePtr->isFace())
384         continue;
385     }
386
387     QString aItemName = aResGroup.get()?
388       QString::fromStdWString(aResGroup->data()->name()) : XGUI_Tools::generateName(aPrs);
389     if (myListView->hasItem(aItemName))
390       continue;
391
392     if (aResGroup.get()) {
393       if (aResGroup->isDisplayed()) {
394         aResGroup->setDisplayed(false);
395         myHiddenGroups.insert(aResGroup);
396       }
397       getObjectsMapFromResult(aResGroup, aGroupFeature, anObjectToShapes, anObjectToPrs);
398     }
399     else
400       objectsMapFromPrs(aPrs, anObjectToShapes, anObjectToPrs);
401
402     // The code is dedicated to remove already selected items if they are selected twice
403     // It can happen in case of groups selection
404     QMap<int, ModuleBase_ViewerPrsPtr>::const_iterator aIt;
405     for (aIt = myItems.cbegin(); aIt != myItems.cend(); aIt++) {
406       ModuleBase_ViewerPrsPtr aCurPrs = aIt.value();
407       ObjectPtr aObject = aCurPrs->object();
408       ResultGroupPtr aCurResGroup = std::dynamic_pointer_cast<ModelAPI_ResultGroup>(aObject);
409       if (aCurResGroup.get())
410         continue;
411       if (anObjectToShapes.find(aObject) != anObjectToShapes.end()) {
412         TopoDS_ListOfShape aShapes = anObjectToShapes[aObject];
413         GeomShapePtr aShapePtr = aCurPrs->shape();
414         if (aShapes.Contains(aShapePtr->impl<TopoDS_Shape>())) {
415           aToRemove.insert(aIt.key());
416         }
417       }
418     }
419
420     myItems.insert(myLastItemIndex, aPrs);
421     myListView->addItem(aItemName, myLastItemIndex);
422     // add in undo list
423     myUndoList.push_back(myLastItemIndex);
424     myLastItemIndex++;
425     isModified = true;
426   }
427
428   // Hide fully hidden shapes
429   std::map<ObjectPtr, TopoDS_ListOfShape>::const_iterator anIt;
430   for (anIt = anObjectToShapes.begin(); anIt != anObjectToShapes.end(); anIt++) {
431     ObjectPtr anObject = anIt->first;
432     if (!anObject.get() || anObjectToPrs.find(anObject) == anObjectToPrs.end())
433       continue;
434     Handle(ModuleBase_ResultPrs) aResultPrs = anObjectToPrs.at(anObject);
435
436     if (!aResultPrs->hasSubShapeVisible(anIt->second)) { // redisplay
437       // erase object because it is entirely hidden
438       anObject->setDisplayed(false);
439       myHiddenObjects.insert(anObject);
440     }
441     ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent);
442   }
443
444   // Process selected presentations
445   double aTransp = transparency();
446   std::map<ObjectPtr, Handle(ModuleBase_ResultPrs)>::iterator aPrsIt;
447   for (aPrsIt = anObjectToPrs.begin(); aPrsIt != anObjectToPrs.end(); aPrsIt++) {
448     ObjectPtr anObject = aPrsIt->first;
449     Handle(ModuleBase_ResultPrs) aPrs = aPrsIt->second;
450     TopoDS_ListOfShape aAlreadyHidden = aPrs->hiddenSubShapes();
451     TopoDS_ListOfShape aListOfShapes = anObjectToShapes[anObject];
452     TopoDS_ListOfShape::Iterator aShapesIt(aListOfShapes);
453     for (; aShapesIt.More(); aShapesIt.Next()) {
454       if (!aAlreadyHidden.Contains(aShapesIt.Value()))
455         aAlreadyHidden.Append(aShapesIt.Value());
456     }
457     aPrs->setSubShapeHidden(aAlreadyHidden);
458     aPrs->setHiddenSubShapeTransparency(aTransp);
459   }
460
461   // Remove duplicate items
462   removeItems(aToRemove);
463   if (isModified) {
464     updateProcessedObjects(myItems, myItemObjects);
465     flushRedisplay();
466   }
467 }
468
469 //********************************************************************
470 bool XGUI_FacesPanel::processDelete()
471 {
472   //appendFirstSelectionInHistory();
473   //QModelIndexList anIndices = myListView->getControl()->selectionModel()->selectedIndexes();
474
475   std::set<int> aSelectedIds;
476   myListView->getSelectedIndices(aSelectedIds);
477   if (aSelectedIds.empty())
478     return false;
479
480   std::set<ModuleBase_ViewerPrsPtr> aRestored;
481   std::set<int>::const_iterator anIt;
482   for (anIt = aSelectedIds.begin(); anIt != aSelectedIds.end(); anIt++) {
483     ModuleBase_ViewerPrsPtr aPrs = myItems[*anIt];
484     if (aRestored.find(aPrs) == aRestored.end()) {
485       aRestored.insert(aPrs);
486       myItems.remove(*anIt);
487     }
488   }
489   std::map<ObjectPtr, TopoDS_ListOfShape> anObjectToShapes;
490   std::map<ObjectPtr, Handle(ModuleBase_ResultPrs) > anObjectToPrs;
491
492   std::set<ModuleBase_ViewerPrsPtr>::const_iterator aIt;
493   for (aIt = aRestored.cbegin(); aIt != aRestored.cend(); aIt++) {
494     getObjectsMapFromPrs((*aIt), anObjectToShapes, anObjectToPrs);
495     ResultGroupPtr aResGroup;
496     FeaturePtr aGroupFeature;
497     if (getGroup((*aIt), aResGroup, aGroupFeature)) {
498       std::set<ObjectPtr >::iterator aGrpIt = myHiddenGroups.find(aResGroup);
499       if (aGrpIt != myHiddenGroups.end()) {
500         aResGroup->setDisplayed(true);
501         myHiddenGroups.erase(aGrpIt);
502       }
503     }
504   }
505
506   std::set<ObjectPtr> aRestoredObjects;
507   std::map<ObjectPtr, TopoDS_ListOfShape>::const_iterator aShapesIt;
508   for (aShapesIt = anObjectToShapes.begin(); aShapesIt != anObjectToShapes.end(); aShapesIt++) {
509     TopoDS_ListOfShape aShapes = aShapesIt->second;
510     aRestoredObjects.insert(aShapesIt->first);
511     Handle(ModuleBase_ResultPrs) aPrs = anObjectToPrs[aShapesIt->first];
512     TopoDS_ListOfShape aHiddenShapes = aPrs->hiddenSubShapes();
513     TopoDS_ListOfShape::Iterator aSubShapesIt(aShapes);
514     for (; aSubShapesIt.More(); aSubShapesIt.Next()) {
515       if (aHiddenShapes.Contains(aSubShapesIt.Value()))
516         aHiddenShapes.Remove(aSubShapesIt.Value());
517     }
518     aPrs->setSubShapeHidden(aHiddenShapes);
519   }
520   if (redisplayObjects(aRestoredObjects))
521     flushRedisplay();
522
523   myListView->removeSelectedItems();
524   return true;
525 }
526
527 //********************************************************************
528 bool XGUI_FacesPanel::redisplayObjects(
529   const std::set<ObjectPtr >& theObjects)
530 {
531   if (theObjects.empty())
532     return false;
533
534   bool isModified = false;
535   static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
536   for (std::set<ObjectPtr>::const_iterator anIt = theObjects.begin(); anIt != theObjects.end();
537        anIt++)
538   {
539     ObjectPtr anObject = *anIt;
540     if (!anObject->isDisplayed())
541       continue;
542     ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent);
543     isModified = true;
544   }
545   return isModified;
546 }
547
548 //********************************************************************
549 void XGUI_FacesPanel::updateProcessedObjects(QMap<int, ModuleBase_ViewerPrsPtr> theItems,
550                                              std::set<ObjectPtr>& theObjects)
551 {
552   theObjects.clear();
553   for (QMap<int, ModuleBase_ViewerPrsPtr>::const_iterator anIt = theItems.begin();
554        anIt != theItems.end(); anIt++) {
555     ModuleBase_ViewerPrsPtr aPrs = anIt.value();
556     ResultGroupPtr aResGroup;
557     FeaturePtr aGroupFeature;
558     if (getGroup(aPrs, aResGroup, aGroupFeature)) {
559       AttributeSelectionListPtr aSelectionList = aGroupFeature->selectionList("group_list");
560       for (int i = 0; i < aSelectionList->size(); i++) {
561         AttributeSelectionPtr aSelection = aSelectionList->value(i);
562         ResultPtr aRes = aSelection->context();
563         if (theObjects.find(aRes) == theObjects.end())
564           theObjects.insert(aRes);
565       }
566     }
567     else {
568       if (theObjects.find(aPrs->object()) == theObjects.end())
569         theObjects.insert(aPrs->object());
570     }
571   }
572 }
573
574 //********************************************************************
575 void XGUI_FacesPanel::closeEvent(QCloseEvent* theEvent)
576 {
577   QDockWidget::closeEvent(theEvent);
578   emit closed();
579 }
580
581 //********************************************************************
582 void XGUI_FacesPanel::onDeleteItem()
583 {
584   processDelete();
585 }
586
587 //********************************************************************
588 void XGUI_FacesPanel::onTransparencyChanged()
589 {
590   std::map<ObjectPtr, TopoDS_ListOfShape> anObjectToShapes;
591   std::map<ObjectPtr, Handle(ModuleBase_ResultPrs) > anObjectToPrs;
592   QMap<int, ModuleBase_ViewerPrsPtr >::const_iterator aIt;
593   for (aIt = myItems.cbegin(); aIt != myItems.cend(); aIt++) {
594     getObjectsMapFromPrs(aIt.value(), anObjectToShapes, anObjectToPrs);
595   }
596
597   double aTransp = Config_PropManager::real("Visualization", "hidden_face_transparency");
598   std::set<ObjectPtr> aObjects;
599   std::map<ObjectPtr, Handle(ModuleBase_ResultPrs)>::const_iterator aPrsIt;
600   for (aPrsIt = anObjectToPrs.cbegin(); aPrsIt != anObjectToPrs.cend(); aPrsIt++) {
601     aObjects.insert(aPrsIt->first);
602     aPrsIt->second->setHiddenSubShapeTransparency(useTransparency()? aTransp : 1);
603   }
604   if (redisplayObjects(aObjects))
605     flushRedisplay();
606 }
607
608 //********************************************************************
609 void XGUI_FacesPanel::onClosed()
610 {
611   setActivePanel(false);
612   reset(true);
613 }
614
615 //********************************************************************
616
617 void XGUI_FacesPanel::processUndo()
618 {
619  if(!myUndoList.size())
620    return;
621
622  myListView->selectIndices({myUndoList.back()});
623  processDelete();
624  myUndoList.pop_back();
625 }
626
627 //********************************************************************
628 void XGUI_FacesPanel::flushRedisplay() const
629 {
630   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
631   // Necessary for update visibility icons in ObjectBrowser
632   XGUI_ObjectsBrowser* anObjectBrowser = myWorkshop->objectBrowser();
633   if (anObjectBrowser)
634     anObjectBrowser->updateAllIndexes();
635   myWorkshop->viewer()->update();
636 }
637
638
639 //********************************************************************
640 void XGUI_FacesPanel::onObjectDisplay(ObjectPtr theObject, AISObjectPtr theAIS)
641 {
642   bool aContains = false;
643   QMap<int, ModuleBase_ViewerPrsPtr>::iterator aIt;
644   for (aIt = myItems.begin(); aIt != myItems.end(); aIt++) {
645     ModuleBase_ViewerPrsPtr aPrs = aIt.value();
646     if (aPrs->object() == theObject) {
647       aContains = true;
648       break;
649     }
650   }
651   if (aContains) {
652     ResultGroupPtr aResGroup;
653     FeaturePtr aGroupFeature;
654     std::map<ObjectPtr, TopoDS_ListOfShape> aObjectToShapes;
655     std::map<ObjectPtr, Handle(ModuleBase_ResultPrs)> aObjectToPrs;
656     std::set<ObjectPtr> aObjects;
657     std::set<int> aIdsToRem;
658
659     TopoDS_ListOfShape aHideShapes;
660     std::map<ObjectPtr, TopoDS_ListOfShape>::const_iterator aSIt;
661     for (aIt = myItems.begin(); aIt != myItems.end(); aIt++) {
662       ModuleBase_ViewerPrsPtr aPrs = aIt.value();
663       if (getGroup(aPrs, aResGroup, aGroupFeature)) {
664         getObjectsMapFromResult(aResGroup, aGroupFeature, aObjectToShapes, aObjectToPrs);
665         if (aResGroup == theObject) {
666           // If group is displayed it means that it has to be deleted from the Faces list and all
667           // corresponded faces have been restored
668           for (aSIt = aObjectToShapes.begin(); aSIt != aObjectToShapes.end(); aSIt++) {
669             TopoDS_ListOfShape aShapes = aSIt->second;
670             Handle(ModuleBase_ResultPrs) aResPrs = aObjectToPrs[aSIt->first];
671             TopoDS_ListOfShape aAlreadyHidden = aResPrs->hiddenSubShapes();
672             TopoDS_ListOfShape::Iterator aShPIt(aShapes);
673             for (; aShPIt.More(); aShPIt.Next()) {
674               if (aAlreadyHidden.Contains(aShPIt.Value()))
675                 aAlreadyHidden.Remove(aShPIt.Value());
676             }
677             aResPrs->setSubShapeHidden(aAlreadyHidden);
678             aObjects.insert(aSIt->first);
679           }
680           aIdsToRem.insert(aIt.key());
681         }
682         else {
683           std::map<ObjectPtr, Handle(ModuleBase_ResultPrs)>::iterator aPIt =
684             aObjectToPrs.find(theObject);
685           if (aPIt != aObjectToPrs.end()) {
686             ObjectPtr aObj = aPIt->first;
687             if (aObj == theObject) {
688               TopoDS_ListOfShape aShapes = aObjectToShapes[aObj];
689               aHideShapes.Append(aShapes);
690               aObjects.insert(aObj);
691             }
692           }
693         }
694       }
695       else {
696         if (aPrs->object() == theObject) {
697           TopoDS_Shape aShape = aPrs->shape()->impl<TopoDS_Shape>();
698           if (!aShape.IsNull())
699             aHideShapes.Append(aShape);
700           aPrs->setInteractive(theAIS->impl<Handle(AIS_InteractiveObject)>());
701         }
702       }
703     }
704     double aTransp = transparency();
705     if (aHideShapes.Size() > 0) {
706       Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast(
707         theAIS->impl<Handle(AIS_InteractiveObject)>());
708       if (!aResultPrs.IsNull()) {
709         aResultPrs->setSubShapeHidden(aHideShapes);
710         aResultPrs->setHiddenSubShapeTransparency(aTransp);
711         aObjects.insert(theObject);
712       }
713     }
714     removeItems(aIdsToRem);
715     myWorkshop->selector()->clearSelection();
716     if (redisplayObjects(aObjects))
717       QTimer::singleShot(50, this, SLOT(flushRedisplay()));
718   }
719 }
720
721 void XGUI_FacesPanel::removeItems(std::set<int> theIds)
722 {
723   if (theIds.empty())
724     return;
725   myListView->removeItems(theIds);
726   std::set<int>::const_iterator aRIt;
727   for (aRIt = theIds.begin(); aRIt != theIds.end(); aRIt++)
728     myItems.remove(*aRIt);
729 }