From a4c5ad394d277931acdbf98e8cae94d0752032af Mon Sep 17 00:00:00 2001 From: nds Date: Wed, 6 Dec 2017 18:47:01 +0300 Subject: [PATCH] Issue #2309 Possibility to hide faces : redisplay objects by transparency check box click --- src/ModuleBase/ModuleBase_ResultPrs.cpp | 2 +- src/XGUI/XGUI_Displayer.cpp | 9 +- src/XGUI/XGUI_Displayer.h | 3 +- src/XGUI/XGUI_FacesPanel.cpp | 185 ++++++++++++++---------- src/XGUI/XGUI_FacesPanel.h | 31 +++- src/XGUI/XGUI_Workshop.cpp | 6 +- 6 files changed, 142 insertions(+), 94 deletions(-) diff --git a/src/ModuleBase/ModuleBase_ResultPrs.cpp b/src/ModuleBase/ModuleBase_ResultPrs.cpp index b988f7fec..63a571ca7 100755 --- a/src/ModuleBase/ModuleBase_ResultPrs.cpp +++ b/src/ModuleBase/ModuleBase_ResultPrs.cpp @@ -161,7 +161,7 @@ bool ModuleBase_ResultPrs::hasSubShapeVisible(const TopoDS_Shape& theShape) //******************************************************************** bool ModuleBase_ResultPrs::setHiddenSubShapeTransparency(double theTransparency) { - if (theTransparency > 1 || theTransparency < 0) + if (myTransparency == theTransparency || theTransparency > 1 || theTransparency < 0) return false; myTransparency = theTransparency; diff --git a/src/XGUI/XGUI_Displayer.cpp b/src/XGUI/XGUI_Displayer.cpp index 4b7e02f5a..2652ae0ed 100644 --- a/src/XGUI/XGUI_Displayer.cpp +++ b/src/XGUI/XGUI_Displayer.cpp @@ -268,7 +268,7 @@ bool XGUI_Displayer::display(ObjectPtr theObject, AISObjectPtr theAIS, if (!anAISIO.IsNull()) { appendResultObject(theObject, theAIS); - bool isCustomized = customizeObject(theObject, true); + bool isCustomized = customizeObject(theObject); int aDispMode = isShading? Shading : Wireframe; if (isShading) @@ -371,7 +371,7 @@ bool XGUI_Displayer::redisplay(ObjectPtr theObject, bool theUpdateViewer) } } // Customization of presentation - bool isCustomized = customizeObject(theObject, false); + bool isCustomized = customizeObject(theObject); #ifdef DEBUG_FEATURE_REDISPLAY qDebug(QString("Redisplay: %1, isEqualShapes=%2, isCustomized=%3"). arg(!isEqualShapes || isCustomized).arg(isEqualShapes) @@ -1367,7 +1367,7 @@ bool XGUI_Displayer::activate(const Handle(AIS_InteractiveObject)& theIO, return isActivationChanged; } -bool XGUI_Displayer::customizeObject(ObjectPtr theObject, const bool isDisplayed) +bool XGUI_Displayer::customizeObject(ObjectPtr theObject) { AISObjectPtr anAISObj = getAISObject(theObject); // correct the result's color it it has the attribute @@ -1394,8 +1394,7 @@ bool XGUI_Displayer::customizeObject(ObjectPtr theObject, const bool isDisplayed // update presentation state if faces panel is active if (anAISObj.get() && myWorkshop->facesPanel()) - isCustomized = myWorkshop->facesPanel()->customizeObject(theObject, isDisplayed) || - isCustomized; + isCustomized = myWorkshop->facesPanel()->customizeObject(theObject, anAISObj) || isCustomized; return isCustomized; } diff --git a/src/XGUI/XGUI_Displayer.h b/src/XGUI/XGUI_Displayer.h index 4414598d0..9b606dab3 100644 --- a/src/XGUI/XGUI_Displayer.h +++ b/src/XGUI/XGUI_Displayer.h @@ -337,9 +337,8 @@ private: /// If the object is result with the color attribute value set, it is used, /// otherwise the customize is applyed to the object's feature if it is a custom prs /// \param theObject an object instance - /// \param isDisplayed boolean state whether the object is displayed/redisplayed /// \return the true state if there is changes and the presentation is customized - bool customizeObject(ObjectPtr theObject, const bool isDisplayed); + bool customizeObject(ObjectPtr theObject); /// Append the objects in the internal map. Checks whether the map already contains the object /// \param theObject an object to display diff --git a/src/XGUI/XGUI_FacesPanel.cpp b/src/XGUI/XGUI_FacesPanel.cpp index 5f9c9d583..55b0c1786 100644 --- a/src/XGUI/XGUI_FacesPanel.cpp +++ b/src/XGUI/XGUI_FacesPanel.cpp @@ -33,7 +33,6 @@ #include "ModuleBase_Tools.h" #include "ModuleBase_ViewerPrs.h" -#include "XGUI_Displayer.h" #include "XGUI_Tools.h" #include "XGUI_Workshop.h" @@ -60,6 +59,8 @@ XGUI_FacesPanel::XGUI_FacesPanel(QWidget* theParent, ModuleBase_IWorkshop* theWo setWidget(aContent); myHiddenOrTransparent = new QCheckBox(tr("Transparent"), aContent); + connect(myHiddenOrTransparent, SIGNAL(toggled(bool)), SLOT(onTransparencyChanged())); + myListView = new ModuleBase_ListView(aContent, "", "Hidden/transparent faces in 3D view"); connect(myListView, SIGNAL(deleteActionClicked()), SLOT(onDeleteItem())); @@ -73,23 +74,19 @@ XGUI_FacesPanel::XGUI_FacesPanel(QWidget* theParent, ModuleBase_IWorkshop* theWo //******************************************************************** void XGUI_FacesPanel::reset(const bool isToFlushRedisplay) { - // restore presentation state - bool isModified = false; - std::set aRestoredObjects; - for (QMap::const_iterator anIt = myItems.begin(); - anIt != myItems.end(); anIt++) { - if (aRestoredObjects.find(anIt.value()->object()) == aRestoredObjects.end()) - aRestoredObjects.insert(anIt.value()->object()); - } // clear internal containers myListView->getControl()->clear(); - myLastItemIndex = 0; myItems.clear(); - isModified = redisplayObjects(aRestoredObjects, isToFlushRedisplay); + // restore previous view of presentations + bool isModified = redisplayObjects(myItemObjects, false); + isModified = displayHiddenObjects(myHiddenObjects, false) || isModified; + if (isModified && isToFlushRedisplay) + Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)); - if (isToFlushRedisplay && isModified) - XGUI_Tools::workshop(myWorkshop)->displayer()->updateViewer(); + updateProcessedObjects(myItems, myItemObjects); + myHiddenObjects.clear(); + myLastItemIndex = 0; // it should be after redisplay as flag used in customize } //******************************************************************** @@ -151,15 +148,18 @@ void XGUI_FacesPanel::restoreObjects(const std::set& theHiddenObjects // remove from myItes container for (std::set::const_iterator aToBeRemovedIt = anIndicesToBeRemoved.begin(); aToBeRemovedIt != anIndicesToBeRemoved.end(); aToBeRemovedIt++) + { myItems.remove(*aToBeRemovedIt); - + } + if (!anIndicesToBeRemoved.empty()) // means that myItems has been changed + updateProcessedObjects(myItems, myItemObjects); myListView->removeItems(anIndicesToBeRemoved); // remove from container of hidden objects for (std::set::const_iterator aHiddenIt = theHiddenObjects.begin(); aHiddenIt != theHiddenObjects.end(); aHiddenIt++) { - if (myHiddenObjects.find(*aHiddenIt) != myHiddenObjects.end()) ///< found objects + if (myHiddenObjects.find(*aHiddenIt) != myHiddenObjects.end()) /// found objects myHiddenObjects.erase(*aHiddenIt); } } @@ -188,24 +188,38 @@ void XGUI_FacesPanel::processSelection() QList aSelected = myWorkshop->selection()->getSelected( ModuleBase_ISelection::Viewer); bool isModified = false; + static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); for (int i = 0; i < aSelected.size(); i++) { ModuleBase_ViewerPrsPtr aPrs = aSelected[i]; ObjectPtr anObject = aPrs->object(); if (!anObject.get()) continue; - if (ModuleBase_Tools::getSelectedShape(aPrs).ShapeType() != TopAbs_FACE) continue; + Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast( + aPrs->interactive()); + if (aResultPrs.IsNull()) + continue; + myItems.insert(myLastItemIndex, aPrs); myListView->addItem(generateName(aPrs), myLastItemIndex); - isModified = hideFace(myLastItemIndex) || isModified; - myLastItemIndex++; - } + isModified = true; + if (aResultPrs->hasSubShapeVisible(ModuleBase_Tools::getSelectedShape(aPrs))) // redisplay + ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent); + else { // erase object because it is entirely hidden + anObject->setDisplayed(false); + myHiddenObjects.insert(anObject); + ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent); + } + } if (isModified) - XGUI_Tools::workshop(myWorkshop)->displayer()->updateViewer(); + { + updateProcessedObjects(myItems, myItemObjects); + Events_Loop::loop()->flush(aDispEvent); + } } //******************************************************************** @@ -221,20 +235,24 @@ bool XGUI_FacesPanel::processDelete() bool isModified = false; std::set aRestoredObjects; - XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(myWorkshop)->displayer(); for (std::set::const_iterator anIt = aSelectedIds.begin(); anIt != aSelectedIds.end(); anIt++) { ModuleBase_ViewerPrsPtr aPrs = myItems[*anIt]; if (aRestoredObjects.find(aPrs->object()) == aRestoredObjects.end()) aRestoredObjects.insert(aPrs->object()); myItems.remove(*anIt); + isModified = true; + } + if (isModified) { + bool isRedisplayed = redisplayObjects(aRestoredObjects, false); + isRedisplayed = displayHiddenObjects(aRestoredObjects, false) || isRedisplayed; + if (isRedisplayed) + Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)); + // should be after flush of redisplay to have items object to be updated + updateProcessedObjects(myItems, myItemObjects); } - myListView->removeSelectedItems(); - - isModified = redisplayObjects(aRestoredObjects, true) || isModified; - if (isModified) - XGUI_Tools::workshop(myWorkshop)->displayer()->updateViewer(); + myListView->removeSelectedItems(); // Restore selection myListView->restoreSelection(anIndices); //appendSelectionInHistory(); @@ -246,67 +264,70 @@ bool XGUI_FacesPanel::redisplayObjects( const std::set >& theObjects, const bool isToFlushRedisplay) { + if (theObjects.empty()) + return false; + bool isModified = false; - XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(myWorkshop)->displayer(); static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); - for (std::set::const_iterator anIt = theObjects.begin(); anIt != theObjects.end(); anIt++) { ObjectPtr anObject = *anIt; - if (!anObject->isDisplayed()) { - // if the object was hidden by this panel - if (myHiddenObjects.find(anObject) != myHiddenObjects.end()) - myHiddenObjects.erase(anObject); - anObject->setDisplayed(true); // it means that the object is hidden by hide all faces - ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent); - isModified = true; - //isModified = aDisplayer->display(anObject, false) || isModified; - } - else { - ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent); - isModified = true; - } + if (!anObject->isDisplayed()) + continue; + ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent); + isModified = true; } - if (isToFlushRedisplay) + if (isModified && isToFlushRedisplay) Events_Loop::loop()->flush(aDispEvent); return isModified; } //******************************************************************** -bool XGUI_FacesPanel::hideFace(const int theIndex) +bool XGUI_FacesPanel::displayHiddenObjects( + const std::set >& theObjects, + const bool isToFlushRedisplay) { - XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(myWorkshop)->displayer(); - - if (!myItems.contains(theIndex)) + if (theObjects.empty()) return false; - ModuleBase_ViewerPrsPtr aPrs = myItems[theIndex]; - - AISObjectPtr aAISObj = aDisplayer->getAISObject(aPrs->object()); - if (aAISObj.get() == NULL) - return false; - Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast( - aAISObj->impl()); - if (aResultPrs.IsNull()) - return false; - // set shape hidden to check whether the presentation should be erased from the viewer bool isModified = false; - if (aResultPrs->hasSubShapeVisible(ModuleBase_Tools::getSelectedShape(aPrs))) - isModified = aDisplayer->redisplay(aPrs->object(), false) || isModified; - else + static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); + + for (std::set::const_iterator anIt = theObjects.begin(); anIt != theObjects.end(); + anIt++) { - ObjectPtr anObject = aPrs->object(); - myHiddenObjects.insert(anObject); - static Events_ID aDispEvent = Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY); - anObject->setDisplayed(false); - isModified = aDisplayer->erase(anObject, false) || isModified; + ObjectPtr anObject = *anIt; + // if the object was hidden by this panel + if (anObject->isDisplayed() || myHiddenObjects.find(anObject) == myHiddenObjects.end()) + continue; + myHiddenObjects.erase(anObject); + anObject->setDisplayed(true); // it means that the object is hidden by hide all faces ModelAPI_EventCreator::get()->sendUpdated(anObject, aDispEvent); - Events_Loop::loop()->flush(aDispEvent); + isModified = true; } + + if (isModified && isToFlushRedisplay) + Events_Loop::loop()->flush(aDispEvent); return isModified; } + +//******************************************************************** +void XGUI_FacesPanel::updateProcessedObjects(QMap theItems, + std::set& theObjects) +{ + theObjects.clear(); + for (QMap::const_iterator anIt = theItems.begin(); + anIt != theItems.end(); anIt++) { + ModuleBase_ViewerPrsPtr aPrs = anIt.value(); + ObjectPtr anObject = aPrs.get() ? aPrs->object() : ObjectPtr(); + if (anObject.get() && theObjects.find(anObject) != theObjects.end()) + continue; + theObjects.insert(anObject); + } +} + //******************************************************************** void XGUI_FacesPanel::closeEvent(QCloseEvent* theEvent) { @@ -357,19 +378,16 @@ QString XGUI_FacesPanel::generateName(const ModuleBase_ViewerPrsPtr& thePrs) } //******************************************************************** -bool XGUI_FacesPanel::customizeObject(const ObjectPtr& theObject, const bool isDisplayed) +bool XGUI_FacesPanel::customizeObject(const ObjectPtr& theObject, + const AISObjectPtr& thePresentation) { - if (isDisplayed && myItems.isEmpty()) + if (myLastItemIndex == 0) // do nothing because there was no activity in the pane after reset return false; - XGUI_Displayer* aDisplayer = XGUI_Tools::workshop(myWorkshop)->displayer(); - - AISObjectPtr aAISObj = aDisplayer->getAISObject(theObject); - if (aAISObj.get() == NULL) + if (thePresentation.get() == NULL) return false; - Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast( - aAISObj->impl()); - if (aResultPrs.IsNull()) + + if (myItemObjects.find(theObject) == myItemObjects.end()) // not found return false; // if the object is displayed, the hidden faces are collected and set to the presentation @@ -384,10 +402,17 @@ bool XGUI_FacesPanel::customizeObject(const ObjectPtr& theObject, const bool isD if (!aHiddenSubShapes.Contains(aShape)) aHiddenSubShapes.Append(aShape); } + + Handle(ModuleBase_ResultPrs) aResultPrs = Handle(ModuleBase_ResultPrs)::DownCast( + thePresentation->impl()); + if (aResultPrs.IsNull()) + return false; + isModified = aResultPrs->setSubShapeHidden(aHiddenSubShapes); + double aTransparency = !useTransparency() ? 1 : Config_PropManager::real("Visualization", "hidden_face_transparency"); - aResultPrs->setHiddenSubShapeTransparency(aTransparency); + isModified = aResultPrs->setHiddenSubShapeTransparency(aTransparency) || isModified; return isModified; } @@ -398,8 +423,18 @@ void XGUI_FacesPanel::onDeleteItem() processDelete(); } +//******************************************************************** +void XGUI_FacesPanel::onTransparencyChanged() +{ + bool isModified = redisplayObjects(myItemObjects, false); + if (isModified) + Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)); + +} + //******************************************************************** void XGUI_FacesPanel::onClosed() { + setActivePanel(false); reset(true); } diff --git a/src/XGUI/XGUI_FacesPanel.h b/src/XGUI/XGUI_FacesPanel.h index 4c147ab7d..1679bdc3e 100644 --- a/src/XGUI/XGUI_FacesPanel.h +++ b/src/XGUI/XGUI_FacesPanel.h @@ -36,6 +36,8 @@ class AIS_InteractiveObject; +class GeomAPI_AISObject; + class ModuleBase_IWorkshop; class ModuleBase_ListView; @@ -114,9 +116,10 @@ public: /// If the object is displayed, all panel faces selected on it will be moved into presentation /// or, if redisplayed, fuction return if the object should be redisplayed or not /// \param theObject a customized object - /// \param isDisplayed state if the object is displayed or redisplayed + /// \param thePresentation visualized presentation of the object /// \return true if the presentation is customized - bool customizeObject(const std::shared_ptr& theObject, const bool isDisplayed); + bool customizeObject(const std::shared_ptr& theObject, + const std::shared_ptr& thePresentation); protected: /// Add panel selection filters to the current viewer @@ -141,17 +144,25 @@ private: /// Activate or deactivate selection and selection filters void activateSelection(bool toActivate); - /// Redisplay or display objects. The viewer is not updated after redisplay. + /// Redisplay objects. /// \param theObjects container of objects /// \param isToFlushRedisplay flag if redisplay should be flushed immediatelly - /// \return true if some of objects was redisplayed to update viewer + /// \return true if some of objects was redisplayed bool redisplayObjects(const std::set >& theObjects, const bool isToFlushRedisplay); - /// Change the presentation to have the selected presentation hidden - /// \param theIndex an index of selected item that should be hidden - /// \return true if presentation is changed - bool hideFace(const int theIndex); + /// Display objects if the objects are in a container of hidden by this pane. + /// \param theObjects container of objects + /// \param isToFlushRedisplay flag if redisplay should be flushed immediatelly + /// \return true if some of objects was redisplayed + bool displayHiddenObjects(const std::set >& theObjects, + const bool isToFlushRedisplay); + + /// Container of objects participating in the panel, it is filled by internal container + /// \param theItems container of selected values + /// \param theObjects [out] container of objects + static void updateProcessedObjects(QMap > theItems, + std::set >& theObjects); /// Generates a presentation name in form: /_ /// \param thePrs a presentation @@ -162,6 +173,9 @@ protected slots: /// Deletes element in list of items void onDeleteItem(); + /// Upates hidden faces to be hidden or transparent + void onTransparencyChanged(); + /// Closes faces panel restore all hidden faces by calling reset() void onClosed(); @@ -174,6 +188,7 @@ protected: int myLastItemIndex; ///< last index to be used in the map of items for the next added item QMap > myItems; ///< selected face items + std::set > myItemObjects; ///< cached objects of myItems std::set > myHiddenObjects; ///< hidden objects }; diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index cb0f7a099..9d821a814 100755 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -1612,8 +1612,8 @@ bool XGUI_Workshop::prepareForDisplay(const std::set& theObjects) con // find hidden objects in faces panel std::set aHiddenObjects; QStringList aHiddenObjectNames; - for (std::set::const_iterator anObjectsIt = theObjects.begin(); - anObjectsIt != theObjects.end(); anObjectsIt++) { + for (std::set::const_iterator anObjectsIt = anAllProcessedObjects.begin(); + anObjectsIt != anAllProcessedObjects.end(); anObjectsIt++) { if (!facesPanel()->isObjectHiddenByPanel(*anObjectsIt)) continue; aHiddenObjects.insert(*anObjectsIt); @@ -1625,7 +1625,7 @@ bool XGUI_Workshop::prepareForDisplay(const std::set& theObjects) con int anAnswer = QMessageBox::question( desktop(), tr("Show object"), tr("'%1'\n are hidden by %2:\nRemove objects from the panel to be displayed?") - .arg(aHiddenObjectNames.join(',').arg(facesPanel()->windowTitle()), + .arg(aHiddenObjectNames.join(',')).arg(facesPanel()->windowTitle(), QMessageBox::Yes | QMessageBox::No, QMessageBox::No)); bool aToBeDisplayed = anAnswer == QMessageBox::Yes; -- 2.39.2