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