From 6f213b9cc0ff018596fee19029d88ff8f8346025 Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 31 Oct 2017 15:18:03 +0300 Subject: [PATCH] Draft of transparency --- src/GeomAPI/GeomAPI_AISObject.cpp | 33 ++++ src/GeomAPI/GeomAPI_AISObject.h | 12 ++ src/Model/Model_ResultPart.cpp | 1 + src/ModelAPI/ModelAPI_Result.cpp | 1 + src/ModelAPI/ModelAPI_Result.h | 10 +- src/ModelHighAPI/ModelHighAPI_Dumper.cpp | 22 ++- src/ModelHighAPI/ModelHighAPI_Dumper.h | 3 + src/ModelHighAPI/ModelHighAPI_Selection.cpp | 11 ++ src/ModelHighAPI/ModelHighAPI_Selection.h | 4 + src/XGUI/CMakeLists.txt | 6 + src/XGUI/XGUI_ContextMenuMgr.cpp | 46 ++++-- src/XGUI/XGUI_CustomPrs.cpp | 33 +++- src/XGUI/XGUI_CustomPrs.h | 5 + src/XGUI/XGUI_PropertyDialog.cpp | 43 +++++ src/XGUI/XGUI_PropertyDialog.h | 53 +++++++ src/XGUI/XGUI_TransparencyWidget.cpp | 87 +++++++++++ src/XGUI/XGUI_TransparencyWidget.h | 79 ++++++++++ src/XGUI/XGUI_Workshop.cpp | 165 +++++++++++++++++--- src/XGUI/XGUI_Workshop.h | 17 +- src/XGUI/XGUI_pictures.qrc | 2 + src/XGUI/pictures/transparency.png | Bin 0 -> 860 bytes 21 files changed, 588 insertions(+), 45 deletions(-) create mode 100644 src/XGUI/XGUI_PropertyDialog.cpp create mode 100644 src/XGUI/XGUI_PropertyDialog.h create mode 100644 src/XGUI/XGUI_TransparencyWidget.cpp create mode 100644 src/XGUI/XGUI_TransparencyWidget.h create mode 100644 src/XGUI/pictures/transparency.png diff --git a/src/GeomAPI/GeomAPI_AISObject.cpp b/src/GeomAPI/GeomAPI_AISObject.cpp index f25ab2e7c..a94c7b425 100644 --- a/src/GeomAPI/GeomAPI_AISObject.cpp +++ b/src/GeomAPI/GeomAPI_AISObject.cpp @@ -428,6 +428,39 @@ double GeomAPI_AISObject::getDeflection() const return aDeflection; } +bool GeomAPI_AISObject::setTransparency(const double theTransparency) +{ + bool isModified = false; + Handle(AIS_InteractiveObject) anAIS = impl(); + if (!anAIS.IsNull()) { + Handle(AIS_Shape) anAISShape = Handle(AIS_Shape)::DownCast(anAIS); + if (!anAISShape.IsNull()) { + Standard_Real aPreviousValue = anAISShape->Transparency(); + if (fabs(aPreviousValue - theTransparency) > Precision::Confusion()) { + anAISShape->SetTransparency(theTransparency); + //>SetOwnDeviationCoefficient(theTransparency); + isModified = true; + // redisplay is necessary here to update presentation in all modes + // Standard True flag. Displayer uses Standard False flag. If it will be changed in + // displayer, redisplay here will not be necessary. But performance should be checked. + anAISShape->Redisplay(Standard_True); + } + } + } + return isModified; +} + +double GeomAPI_AISObject::getTransparency() const +{ + double aTransparency = 0; + + Handle(AIS_InteractiveObject) anAIS = impl(); + if (!anAIS.IsNull()) { + aTransparency = anAIS->Transparency(); + } + return aTransparency; +} + bool GeomAPI_AISObject::empty() const { diff --git a/src/GeomAPI/GeomAPI_AISObject.h b/src/GeomAPI/GeomAPI_AISObject.h index 5a4cd78e9..54c6840b2 100644 --- a/src/GeomAPI/GeomAPI_AISObject.h +++ b/src/GeomAPI/GeomAPI_AISObject.h @@ -148,6 +148,18 @@ class GeomAPI_AISObject : public GeomAPI_Interface GEOMAPI_EXPORT double getDeflection() const; + /** \brief Assigns the transparency to the shape + * \param[in] theTransparency value of transparency + */ + GEOMAPI_EXPORT + bool setTransparency(const double theTransparency); + + /** \brief Returns deflection for the shape + * \return double value + */ + GEOMAPI_EXPORT + double getTransparency() const; + /// \return Current width of the lines of shape GEOMAPI_EXPORT double width(); diff --git a/src/Model/Model_ResultPart.cpp b/src/Model/Model_ResultPart.cpp index ddac1acb2..255f5e380 100644 --- a/src/Model/Model_ResultPart.cpp +++ b/src/Model/Model_ResultPart.cpp @@ -54,6 +54,7 @@ void Model_ResultPart::initAttributes() data()->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId()); data()->addAttribute(BASE_REF_ID(), ModelAPI_AttributeReference::typeId()); data()->addAttribute(DEFLECTION_ID(), ModelAPI_AttributeDouble::typeId()); + data()->addAttribute(TRANSPARENCY_ID(), ModelAPI_AttributeDouble::typeId()); if (aDocRef->isInitialized() && // initialized immideately means already exist and will be loaded !Model_Application::getApplication()->hasDocument(aDocRef->docId())) diff --git a/src/ModelAPI/ModelAPI_Result.cpp b/src/ModelAPI/ModelAPI_Result.cpp index 6569136a6..4aac574bf 100644 --- a/src/ModelAPI/ModelAPI_Result.cpp +++ b/src/ModelAPI/ModelAPI_Result.cpp @@ -37,6 +37,7 @@ void ModelAPI_Result::initAttributes() DataPtr aData = data(); aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::typeId()); aData->addAttribute(DEFLECTION_ID(), ModelAPI_AttributeDouble::typeId()); + aData->addAttribute(TRANSPARENCY_ID(), ModelAPI_AttributeDouble::typeId()); } bool ModelAPI_Result::setDisabled(std::shared_ptr theThis, const bool theFlag) diff --git a/src/ModelAPI/ModelAPI_Result.h b/src/ModelAPI/ModelAPI_Result.h index 5036b12fb..c418e7ac7 100644 --- a/src/ModelAPI/ModelAPI_Result.h +++ b/src/ModelAPI/ModelAPI_Result.h @@ -49,13 +49,21 @@ class ModelAPI_Result : public ModelAPI_Object } /// Reference to the deflection of the result. - /// The double value is used. The values is in [0, 1] range + /// The double value is used. The value is in [0, 1] range inline static const std::string& DEFLECTION_ID() { static const std::string MY_DEFLECTION_ID("Deflection"); return MY_DEFLECTION_ID; } + /// Reference to the transparency of the result. + /// The double value is used. The value is in [0, 1] range + inline static const std::string& TRANSPARENCY_ID() + { + static const std::string MY_TRANSPARENCY_ID("Transparency"); + return MY_TRANSPARENCY_ID; + } + /// Returns true if the result is concealed from the data tree (referenced by other objects) MODELAPI_EXPORT virtual bool isConcealed(); diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp index c005e37f0..ba329d412 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.cpp @@ -474,6 +474,15 @@ void ModelHighAPI_Dumper::dumpEntitySetName() myDumpBuffer << ".setDeflection(" << aDeflectionAttr->value() << ")" << std::endl; } } + // set result transparency + if (!isDefaultTransparency(*aResIt)) { + AttributeDoublePtr aTransparencyAttr = + (*aResIt)->data()->real(ModelAPI_Result::TRANSPARENCY_ID()); + if(aTransparencyAttr.get() && aTransparencyAttr->isInitialized()) { + *this << *aResIt; + myDumpBuffer << ".setTransparency(" << aTransparencyAttr->value() << ")" << std::endl; + } + } } myNames[aLastDumped.myEntity].myIsDumped = true; @@ -534,6 +543,15 @@ bool ModelHighAPI_Dumper::isDefaultDeflection(const ResultPtr& theResult) const return fabs(aCurrent - aDefault) < 1.e-12; } +bool ModelHighAPI_Dumper::isDefaultTransparency(const ResultPtr& theResult) const +{ + AttributeDoublePtr anAttribute = theResult->data()->real(ModelAPI_Result::TRANSPARENCY_ID()); + if(!anAttribute || !anAttribute->isInitialized()) { + return true; + } + return fabs(anAttribute->value()) < 1.e-12; +} + ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const char theChar) { myDumpBuffer << theChar; @@ -674,7 +692,7 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FeaturePtr& theEntity std::list::const_iterator aResIt = aResults.begin(); for (; aResIt != aResults.end(); ++aResIt) { if (!myNames[*aResIt].myIsDefault || !isDefaultColor(*aResIt) || - !isDefaultDeflection(*aResIt)) + !isDefaultDeflection(*aResIt) || !isDefaultTransparency(*aResIt)) aResultsWithNameOrColor.push_back(*aResIt); ResultCompSolidPtr aCompSolid = @@ -684,7 +702,7 @@ ModelHighAPI_Dumper& ModelHighAPI_Dumper::operator<<(const FeaturePtr& theEntity for (int i = 0; i < aNbSubs; ++i) { ResultPtr aCurRes = aCompSolid->subResult(i); if (!myNames[aCurRes].myIsDefault || !isDefaultColor(aCurRes) || - !isDefaultDeflection(aCurRes)) + !isDefaultDeflection(aCurRes) || !isDefaultTransparency(aCurRes)) aResultsWithNameOrColor.push_back(aCurRes); } } diff --git a/src/ModelHighAPI/ModelHighAPI_Dumper.h b/src/ModelHighAPI/ModelHighAPI_Dumper.h index b9478e61c..c2fe0cd54 100644 --- a/src/ModelHighAPI/ModelHighAPI_Dumper.h +++ b/src/ModelHighAPI/ModelHighAPI_Dumper.h @@ -278,6 +278,9 @@ private: /// Check the result feature has default deflection bool isDefaultDeflection(const ResultPtr& theResult) const; + /// Check the result feature has default transparency + bool isDefaultTransparency(const ResultPtr& theResult) const; + private: struct EntityName { std::string myCurrentName; ///< default name of current feature diff --git a/src/ModelHighAPI/ModelHighAPI_Selection.cpp b/src/ModelHighAPI/ModelHighAPI_Selection.cpp index 60017e8cc..0eb6c78c2 100644 --- a/src/ModelHighAPI/ModelHighAPI_Selection.cpp +++ b/src/ModelHighAPI/ModelHighAPI_Selection.cpp @@ -155,6 +155,17 @@ void ModelHighAPI_Selection::setDeflection(double theValue) aDeflectionAttr->setValue(theValue); } +void ModelHighAPI_Selection::setTransparency(double theValue) +{ + if (myVariantType != VT_ResultSubShapePair) + return; + + AttributeDoublePtr aTransparencyAttr = + myResultSubShapePair.first->data()->real(ModelAPI_Result::TRANSPARENCY_ID()); + + aTransparencyAttr->setValue(theValue); +} + int ModelHighAPI_Selection::numberOfSubs() const { if (myVariantType != VT_ResultSubShapePair) diff --git a/src/ModelHighAPI/ModelHighAPI_Selection.h b/src/ModelHighAPI/ModelHighAPI_Selection.h index c89b414fb..1aa1788e8 100644 --- a/src/ModelHighAPI/ModelHighAPI_Selection.h +++ b/src/ModelHighAPI/ModelHighAPI_Selection.h @@ -104,6 +104,10 @@ public: MODELHIGHAPI_EXPORT void setDeflection(double theValue); + /// Change result's transparency + MODELHIGHAPI_EXPORT + void setTransparency(double theValue); + /// Returns the number of sub-elements. MODELHIGHAPI_EXPORT int numberOfSubs() const; diff --git a/src/XGUI/CMakeLists.txt b/src/XGUI/CMakeLists.txt index 1bc373d68..9663e386a 100644 --- a/src/XGUI/CMakeLists.txt +++ b/src/XGUI/CMakeLists.txt @@ -44,12 +44,14 @@ SET(PROJECT_HEADERS XGUI_ModuleConnector.h XGUI_ObjectsBrowser.h XGUI_OperationMgr.h + XGUI_PropertyDialog.h XGUI_PropertyPanel.h XGUI_QtEvents.h XGUI_SalomeConnector.h XGUI_Selection.h XGUI_SelectionMgr.h XGUI_Tools.h + XGUI_TransparencyWidget.h XGUI_ViewerProxy.h XGUI_Workshop.h XGUI_WorkshopListener.h @@ -68,8 +70,10 @@ SET(PROJECT_MOC_HEADERS XGUI_ModuleConnector.h XGUI_ObjectsBrowser.h XGUI_OperationMgr.h + XGUI_PropertyDialog.h XGUI_PropertyPanel.h XGUI_SelectionMgr.h + XGUI_TransparencyWidget.h XGUI_ViewerProxy.h XGUI_Workshop.h XGUI_WorkshopListener.h @@ -95,12 +99,14 @@ SET(PROJECT_SOURCES XGUI_ModuleConnector.cpp XGUI_ObjectsBrowser.cpp XGUI_OperationMgr.cpp + XGUI_PropertyDialog.cpp XGUI_PropertyPanel.cpp XGUI_QtEvents.cpp XGUI_SalomeConnector.cpp XGUI_Selection.cpp XGUI_SelectionMgr.cpp XGUI_Tools.cpp + XGUI_TransparencyWidget.cpp XGUI_ViewerProxy.cpp XGUI_Workshop.cpp XGUI_WorkshopListener.cpp diff --git a/src/XGUI/XGUI_ContextMenuMgr.cpp b/src/XGUI/XGUI_ContextMenuMgr.cpp index d0ee1667c..1a986b377 100644 --- a/src/XGUI/XGUI_ContextMenuMgr.cpp +++ b/src/XGUI/XGUI_ContextMenuMgr.cpp @@ -107,6 +107,12 @@ void XGUI_ContextMenuMgr::createActions() aAction = ModuleBase_Tools::createAction(QIcon(""), tr("Deflection..."), aDesktop); addAction("DEFLECTION_CMD", aAction); +#ifdef USE_TRANSPARENCY + aAction = ModuleBase_Tools::createAction(QIcon(":pictures/transparency.png"), + tr("Transparency..."), aDesktop); + addAction("TRANSPARENCY_CMD", aAction); +#endif + aAction = ModuleBase_Tools::createAction(QIcon(":pictures/eye_pencil.png"), tr("Show"), aDesktop); addAction("SHOW_CMD", aAction); @@ -346,12 +352,11 @@ void XGUI_ContextMenuMgr::updateObjectBrowserMenu() action("SHOW_ONLY_CMD")->setEnabled(false); } - if (myWorkshop->canChangeColor()) - action("COLOR_CMD")->setEnabled(true); - - if (myWorkshop->canChangeDeflection()) - action("DEFLECTION_CMD")->setEnabled(true); - + action("COLOR_CMD")->setEnabled(myWorkshop->canChangeProperty("COLOR_CMD")); + action("DEFLECTION_CMD")->setEnabled(myWorkshop->canChangeProperty("DEFLECTION_CMD")); +#ifdef USE_TRANSPARENCY + action("TRANSPARENCY_CMD")->setEnabled(myWorkshop->canChangeProperty("TRANSPARENCY_CMD")); +#endif #ifdef _DEBUG #ifdef TINSPECTOR action("TINSPECTOR_VIEW")->setEnabled(true); @@ -449,12 +454,17 @@ void XGUI_ContextMenuMgr::updateViewerMenu() if (aModule) aModule->updateViewerMenu(myActions); - if (myWorkshop->canChangeColor()) + if (myWorkshop->canChangeProperty("COLOR_CMD")) action("COLOR_CMD")->setEnabled(true); - if (myWorkshop->canChangeDeflection()) + if (myWorkshop->canChangeProperty("DEFLECTION_CMD")) action("DEFLECTION_CMD")->setEnabled(true); +#ifdef USE_TRANSPARENCY + if (myWorkshop->canChangeProperty("TRANSPARENCY_CMD")) + action("TRANSPARENCY_CMD")->setEnabled(true); +#endif + action("DELETE_CMD")->setEnabled(true); } @@ -486,6 +496,9 @@ void XGUI_ContextMenuMgr::buildObjBrowserMenu() aList.append(action("RENAME_CMD")); aList.append(action("COLOR_CMD")); aList.append(action("DEFLECTION_CMD")); +#ifdef USE_TRANSPARENCY + aList.append(action("TRANSPARENCY_CMD")); +#endif aList.append(action("SHOW_FEATURE_CMD")); myObjBrowserMenus[ModelAPI_ResultConstruction::group()] = aList; @@ -503,6 +516,9 @@ void XGUI_ContextMenuMgr::buildObjBrowserMenu() aList.append(action("RENAME_CMD")); aList.append(action("COLOR_CMD")); aList.append(action("DEFLECTION_CMD")); +#ifdef USE_TRANSPARENCY + aList.append(action("TRANSPARENCY_CMD")); +#endif aList.append(action("SHOW_FEATURE_CMD")); myObjBrowserMenus[ModelAPI_ResultBody::group()] = aList; // Group menu @@ -539,6 +555,9 @@ void XGUI_ContextMenuMgr::buildViewerMenu() aList.append(mySeparator); aList.append(action("COLOR_CMD")); aList.append(action("DEFLECTION_CMD")); +#ifdef USE_TRANSPARENCY + aList.append(action("TRANSPARENCY_CMD")); +#endif myViewerMenu[ModelAPI_ResultConstruction::group()] = aList; // Result part menu myViewerMenu[ModelAPI_ResultPart::group()] = aList; @@ -553,6 +572,9 @@ void XGUI_ContextMenuMgr::buildViewerMenu() aList.append(mySeparator); aList.append(action("COLOR_CMD")); aList.append(action("DEFLECTION_CMD")); +#ifdef USE_TRANSPARENCY + aList.append(action("TRANSPARENCY_CMD")); +#endif myViewerMenu[ModelAPI_ResultBody::group()] = aList; // Group menu myViewerMenu[ModelAPI_ResultGroup::group()] = aList; @@ -589,7 +611,9 @@ void XGUI_ContextMenuMgr::addObjBrowserMenu(QMenu* theMenu) const //aActions.append(action("MOVE_CMD")); aActions.append(action("COLOR_CMD")); aActions.append(action("DEFLECTION_CMD")); - +#ifdef USE_TRANSPARENCY + aActions.append(action("TRANSPARENCY_CMD")); +#endif aActions.append(action("CLEAN_HISTORY_CMD")); aActions.append(action("DELETE_CMD")); } @@ -645,7 +669,9 @@ void XGUI_ContextMenuMgr::addViewerMenu(QMenu* theMenu) const aActions.append(action("HIDEALL_CMD")); aActions.append(action("COLOR_CMD")); aActions.append(action("DEFLECTION_CMD")); - +#ifdef USE_TRANSPARENCY + aActions.append(action("TRANSPARENCY_CMD")); +#endif theMenu->addActions(aActions); QMap aMenuActions; diff --git a/src/XGUI/XGUI_CustomPrs.cpp b/src/XGUI/XGUI_CustomPrs.cpp index cc12b8090..fe9fbfcdc 100644 --- a/src/XGUI/XGUI_CustomPrs.cpp +++ b/src/XGUI/XGUI_CustomPrs.cpp @@ -42,7 +42,7 @@ double getDeflection(const ResultPtr& theResult) { double aDeflection = -1; - // get color from the attribute of the result + // get deflection from the attribute of the result if (theResult.get() != NULL && theResult->data()->attribute(ModelAPI_Result::DEFLECTION_ID()).get() != NULL) { AttributeDoublePtr aDoubleAttr = theResult->data()->real(ModelAPI_Result::DEFLECTION_ID()); @@ -118,6 +118,27 @@ double XGUI_CustomPrs::getDefaultDeflection(const ObjectPtr& theObject) return aDeflection; } +double getTransparency(const ResultPtr& theResult) +{ + double aDeflection = -1; + // get transparency from the attribute of the result + if (theResult.get() != NULL && + theResult->data()->attribute(ModelAPI_Result::TRANSPARENCY_ID()).get() != NULL) { + AttributeDoublePtr aDoubleAttr = theResult->data()->real(ModelAPI_Result::TRANSPARENCY_ID()); + if (aDoubleAttr.get() && aDoubleAttr->isInitialized()) { + double aValue = aDoubleAttr->value(); + if (aValue > 0) /// zero value should not be used as a transparency(previous studies) + aDeflection = aDoubleAttr->value(); + } + } + return aDeflection; +} + +double getDefaultTransparency(const ResultPtr& theResult) +{ + return 0; +} + XGUI_CustomPrs::XGUI_CustomPrs(XGUI_Workshop* theWorkshop) : myWorkshop(theWorkshop) { @@ -138,6 +159,14 @@ double XGUI_CustomPrs::getResultDeflection(const ResultPtr& theResult) return aDeflection; } +double XGUI_CustomPrs::getResultTransparency(const ResultPtr& theResult) +{ + double aTransparency = getTransparency(theResult); + if (aTransparency < 0) + aTransparency = getDefaultTransparency(theResult); + return aTransparency; +} + bool XGUI_CustomPrs::customisePresentation(ResultPtr theResult, AISObjectPtr thePrs, std::shared_ptr theCustomPrs) { @@ -158,6 +187,8 @@ bool XGUI_CustomPrs::customisePresentation(ResultPtr theResult, AISObjectPtr the aCustomized = !aColor.empty() && thePrs->setColor(aColor[0], aColor[1], aColor[2]); aCustomized = thePrs->setDeflection(getResultDeflection(theResult)) | aCustomized; + + aCustomized = thePrs->setTransparency(getResultTransparency(theResult)) | aCustomized; } ModuleBase_IModule* aModule = myWorkshop->module(); aCustomized = aModule->customisePresentation(theResult, thePrs, theCustomPrs) || aCustomized; diff --git a/src/XGUI/XGUI_CustomPrs.h b/src/XGUI/XGUI_CustomPrs.h index 7b5e2e184..6a2af267c 100644 --- a/src/XGUI/XGUI_CustomPrs.h +++ b/src/XGUI/XGUI_CustomPrs.h @@ -55,6 +55,11 @@ public: /// \return theDeflection a real value static double getResultDeflection(const ResultPtr& theResult); + /// Returns transparency of a result object + /// \param theResult a result object + /// \return theTransparency a real value + static double getResultTransparency(const ResultPtr& theResult); + /// Returns the default object color. It obtains colorConfigInfo of the object /// and find it in preferences. If there are no this color in preference and an empty /// color is interpreted as invalid, it shows error message diff --git a/src/XGUI/XGUI_PropertyDialog.cpp b/src/XGUI/XGUI_PropertyDialog.cpp new file mode 100644 index 000000000..ab15ae812 --- /dev/null +++ b/src/XGUI/XGUI_PropertyDialog.cpp @@ -0,0 +1,43 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#include + +#include +#include +#include + +XGUI_PropertyDialog::XGUI_PropertyDialog(QWidget* theParent) +: QDialog(theParent), myContentWidget(0) +{ + myLayout = new QGridLayout(this); + + QDialogButtonBox* aButtons = new QDialogButtonBox( + QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this); + connect(aButtons, SIGNAL(accepted()), this, SLOT(accept())); + connect(aButtons, SIGNAL(rejected()), this, SLOT(reject())); + + myLayout->addWidget(aButtons, 1, 0); +} + +void XGUI_PropertyDialog::setContent(QWidget* theWidget) +{ + myLayout->addWidget(theWidget, 0, 0); +} diff --git a/src/XGUI/XGUI_PropertyDialog.h b/src/XGUI/XGUI_PropertyDialog.h new file mode 100644 index 000000000..647340f69 --- /dev/null +++ b/src/XGUI/XGUI_PropertyDialog.h @@ -0,0 +1,53 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#ifndef XGUI_PropertyDialog_H +#define XGUI_PropertyDialog_H + +#include "XGUI.h" + +#include + +class QGridLayout; +/** +* \ingroup GUI +* A dialog that contains property widget and accept/reject buttons. +*/ +class XGUI_PropertyDialog : public QDialog +{ + Q_OBJECT +public: + /// Constructor + /// \param theParent a parent widget for the dialog + XGUI_EXPORT XGUI_PropertyDialog(QWidget* theParent); + + XGUI_EXPORT virtual ~XGUI_PropertyDialog() {}; + + /// Set content of the dialog + /// \param theWidget a content widget + void setContent(QWidget* theWidget); + +private: + QGridLayout* myLayout; /// grid layout where the first row is reserved for content widget, + /// the second row contains dialog buttons + QWidget* myContentWidget; /// content widget of the dialog +}; + +#endif diff --git a/src/XGUI/XGUI_TransparencyWidget.cpp b/src/XGUI/XGUI_TransparencyWidget.cpp new file mode 100644 index 000000000..76ec83d82 --- /dev/null +++ b/src/XGUI/XGUI_TransparencyWidget.cpp @@ -0,0 +1,87 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#include "XGUI_TransparencyWidget.h" + +#include +#include +#include +#include +#include + +XGUI_TransparencyWidget::XGUI_TransparencyWidget(QWidget* theParent, const QString& theLabelText) + : QWidget(theParent) +{ + QHBoxLayout* aLay = new QHBoxLayout(this); + aLay->setContentsMargins(0, 0, 0, 0); + + mySpinValue = new QDoubleSpinBox(this); + mySpinValue->setRange(0, 1); + mySpinValue->setSingleStep(0.1); + mySliderValue = new QSlider(Qt::Horizontal, this); + mySliderValue->setRange(0, 100); + + myPreview = new QCheckBox("Preview", this); + myPreview->setChecked(true); + + if (!theLabelText.isEmpty()) + aLay->addWidget(new QLabel(theLabelText, this)); + aLay->addWidget(mySpinValue); + aLay->addWidget(mySliderValue); + aLay->addWidget(myPreview); + + connect(mySpinValue, SIGNAL(valueChanged(double)), this, SLOT(onSpinValueChanged(double))); + connect(mySliderValue, SIGNAL(valueChanged(int)), this, SLOT(onSliderValueChanged(int))); + connect(myPreview, SIGNAL(toggled(bool)), this, SIGNAL(previewStateChanged())); +} + +void XGUI_TransparencyWidget::setValue(double theValue) +{ + bool isSpinBlocked = mySpinValue->blockSignals(true); + bool isSliderBlocked = mySliderValue->blockSignals(true); + + mySpinValue->setValue(theValue); + mySliderValue->setValue(theValue * 100); + + mySpinValue->blockSignals(isSpinBlocked); + mySliderValue->blockSignals(isSliderBlocked); +} + +double XGUI_TransparencyWidget::getValue() const +{ + return mySpinValue->value(); +} + +bool XGUI_TransparencyWidget::isPreviewNeeded() const +{ + return myPreview->isChecked(); +} + +void XGUI_TransparencyWidget::onSpinValueChanged(double theValue) +{ + setValue(theValue); + emit transparencyValueChanged(); +} + +void XGUI_TransparencyWidget::onSliderValueChanged(int theValue) +{ + setValue((double)theValue / 100); + emit transparencyValueChanged(); +} diff --git a/src/XGUI/XGUI_TransparencyWidget.h b/src/XGUI/XGUI_TransparencyWidget.h new file mode 100644 index 000000000..006d1297a --- /dev/null +++ b/src/XGUI/XGUI_TransparencyWidget.h @@ -0,0 +1,79 @@ +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#ifndef XGUI_TransparencyWidget_H +#define XGUI_TransparencyWidget_H + +#include "XGUI.h" + +#include + +class QDoubleSpinBox; +class QSlider; +class QCheckBox; + +/** +* \ingroup GUI +* A class of a widget to chose transparency. range of values is [0, 1], +* where 0 - there is no transparency, 1 - the object is fully transparent. +*/ +class XGUI_TransparencyWidget : public QWidget +{ + Q_OBJECT +public: + /// Constructor + /// \param theParent a parent widget for the dialog + /// \param theLabelText if not empty, the information label will be shown in the widget + XGUI_EXPORT XGUI_TransparencyWidget(QWidget* theParent, + const QString& theLabelText = QString()); + XGUI_EXPORT virtual ~XGUI_TransparencyWidget() {}; + + /// Initializes the dialog with the given value. + /// \param theValue transparency value + void setValue(double theValue); + + /// Returns the current transparency value. + /// \return value + double getValue() const; + + /// Returns true if the value should be applyed immediatelly + /// \return state of preview check control + bool isPreviewNeeded() const; + +signals: + void transparencyValueChanged(); + void previewStateChanged(); + +private slots: + /// Update slider value by spin value + /// \param theValue the new spin value + void onSpinValueChanged(double theValue); + + /// Update spin value by slider value + /// \param theValue the new slider value + void onSliderValueChanged(int theValue); + +private: + QDoubleSpinBox* mySpinValue; /// value control + QSlider* mySliderValue; /// slider to select value + QCheckBox* myPreview; /// do preview immediatelly +}; + +#endif diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 7a11ee1bb..737d28e91 100755 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -24,6 +24,7 @@ #include "XGUI_MenuMgr.h" #include "XGUI_ColorDialog.h" #include "XGUI_DeflectionDialog.h" +#include "XGUI_TransparencyWidget.h" #include "XGUI_ContextMenuMgr.h" #include "XGUI_Displayer.h" #include "XGUI_ErrorDialog.h" @@ -32,6 +33,7 @@ #include "XGUI_ObjectsBrowser.h" #include "XGUI_OperationMgr.h" #include "XGUI_PropertyPanel.h" +#include "XGUI_PropertyDialog.h" #include "XGUI_SalomeConnector.h" #include "XGUI_Selection.h" #include "XGUI_SelectionMgr.h" @@ -1354,6 +1356,10 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) changeColor(aObjects); else if (theId == "DEFLECTION_CMD") changeDeflection(aObjects); +#ifdef USE_TRANSPARENCY + else if (theId == "TRANSPARENCY_CMD") + changeTransparency(aObjects); +#endif else if (theId == "SHOW_CMD") { showObjects(aObjects, true); mySelector->updateSelectionBy(ModuleBase_ISelection::Browser); @@ -1851,17 +1857,25 @@ bool XGUI_Workshop::canBeShaded(const ObjectPtr& theObject) const } //************************************************************** -bool XGUI_Workshop::canChangeColor() const +bool XGUI_Workshop::canChangeProperty(const QString& theActionName) const { - QObjectPtrList aObjects = mySelector->selection()->selectedObjects(); + if (theActionName == "COLOR_CMD" || + theActionName == "DEFLECTION_CMD" +#ifdef USE_TRANSPARENCY + || theActionName == "TRANSPARENCY_CMD" +#endif + ) { + QObjectPtrList aObjects = mySelector->selection()->selectedObjects(); - std::set aTypes; - aTypes.insert(ModelAPI_ResultGroup::group()); - aTypes.insert(ModelAPI_ResultConstruction::group()); - aTypes.insert(ModelAPI_ResultBody::group()); - aTypes.insert(ModelAPI_ResultPart::group()); + std::set aTypes; + aTypes.insert(ModelAPI_ResultGroup::group()); + aTypes.insert(ModelAPI_ResultConstruction::group()); + aTypes.insert(ModelAPI_ResultBody::group()); + aTypes.insert(ModelAPI_ResultPart::group()); - return hasResults(aObjects, aTypes); + return hasResults(aObjects, aTypes); + } + return false; } void setColor(ResultPtr theResult, const std::vector& theColor) @@ -1948,19 +1962,6 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) } //************************************************************** -bool XGUI_Workshop::canChangeDeflection() const -{ - QObjectPtrList aObjects = mySelector->selection()->selectedObjects(); - - std::set aTypes; - aTypes.insert(ModelAPI_ResultGroup::group()); - aTypes.insert(ModelAPI_ResultConstruction::group()); - aTypes.insert(ModelAPI_ResultBody::group()); - aTypes.insert(ModelAPI_ResultPart::group()); - - return hasResults(aObjects, aTypes); -} - void setDeflection(ResultPtr theResult, const double theDeflection) { if (!theResult.get()) @@ -1971,13 +1972,41 @@ void setDeflection(ResultPtr theResult, const double theDeflection) aDeflectionAttr->setValue(theDeflection); } +//************************************************************** +void setTransparency(ResultPtr theResult, double theTransparency) +{ + if (!theResult.get()) + return; + + AttributeDoublePtr anAttribute = theResult->data()->real(ModelAPI_Result::TRANSPARENCY_ID()); + if (anAttribute.get() != NULL) + anAttribute->setValue(theTransparency); +} + +//************************************************************** +void setTransparency(double theTransparency, const QObjectPtrList& theObjects) +{ + foreach(ObjectPtr anObj, theObjects) { + ResultPtr aResult = std::dynamic_pointer_cast(anObj); + if (aResult.get() != NULL) { + ResultCompSolidPtr aCompsolidResult = + std::dynamic_pointer_cast(aResult); + if (aCompsolidResult.get() != NULL) { // change property for all sub-solids + for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) { + setTransparency(aCompsolidResult->subResult(i), theTransparency); + } + } + setTransparency(aResult, theTransparency); + } + } +} //************************************************************** void XGUI_Workshop::changeDeflection(const QObjectPtrList& theObjects) { AttributeDoublePtr aDoubleAttr; - // 1. find the current color of the object. This is a color of AIS presentation - // The objects are iterated until a first valid color is found + // 1. find the current property of the object. This is a property of AIS presentation + // The objects are iterated until a first valid property is found double aDeflection = -1; foreach(ObjectPtr anObject, theObjects) { ResultPtr aResult = std::dynamic_pointer_cast(anObject); @@ -1985,9 +2014,9 @@ void XGUI_Workshop::changeDeflection(const QObjectPtrList& theObjects) aDeflection = XGUI_CustomPrs::getResultDeflection(aResult); } else { - // TODO: remove the obtaining a color from the AIS object + // TODO: remove the obtaining a property from the AIS object // this does not happen never because: - // 1. The color can be changed only on results + // 1. The property can be changed only on results // 2. The result can be not visualized in the viewer(e.g. Origin Construction) AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject); if (anAISObj.get()) { @@ -2022,7 +2051,7 @@ void XGUI_Workshop::changeDeflection(const QObjectPtrList& theObjects) if (aResult.get() != NULL) { ResultCompSolidPtr aCompsolidResult = std::dynamic_pointer_cast(aResult); - if (aCompsolidResult.get() != NULL) { // change colors for all sub-solids + if (aCompsolidResult.get() != NULL) { // change property for all sub-solids for(int i = 0; i < aCompsolidResult->numberOfSubs(); i++) { setDeflection(aCompsolidResult->subResult(i), aDeflection); } @@ -2034,6 +2063,90 @@ void XGUI_Workshop::changeDeflection(const QObjectPtrList& theObjects) updateCommandStatus(); } +//************************************************************** +void XGUI_Workshop::changeTransparency(const QObjectPtrList& theObjects) +{ + AttributeDoublePtr aDoubleAttr; + // 1. find the current property of the object. This is a property of AIS presentation + // The objects are iterated until a first valid property is found + double aCurrentValue = -1; + foreach(ObjectPtr anObject, theObjects) { + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + if (aResult.get()) { + aCurrentValue = XGUI_CustomPrs::getResultTransparency(aResult); + } + else { + // TODO: remove the obtaining a property from the AIS object + // this does not happen never because: + // 1. The property can be changed only on results + // 2. The result can be not visualized in the viewer(e.g. Origin Construction) + AISObjectPtr anAISObj = myDisplayer->getAISObject(anObject); + if (anAISObj.get()) { + aCurrentValue = anAISObj->getDeflection(); + } + } + if (aCurrentValue > 0) + break; + } + if (aCurrentValue < 0) + return; + + if (!abortAllOperations()) + return; + + // 2. show the dialog to change the value + XGUI_PropertyDialog* aDlg = new XGUI_PropertyDialog(desktop()); + aDlg->setWindowTitle("Transparency"); + XGUI_TransparencyWidget* aTransparencyWidget = new XGUI_TransparencyWidget(aDlg); + connect(aTransparencyWidget, SIGNAL(transparencyValueChanged()), + this, SLOT(onTransparencyValueChanged())); + connect(aTransparencyWidget, SIGNAL(previewStateChanged()), + this, SLOT(onPreviewStateChanged())); + aDlg->setContent(aTransparencyWidget); + aTransparencyWidget->setValue(aCurrentValue); + + // 3. abort the previous operation and start a new one + SessionPtr aMgr = ModelAPI_Session::get(); + QString aDescription = contextMenuMgr()->action("TRANSPARENCY_CMD")->text(); + aMgr->startOperation(aDescription.toStdString()); + + aDlg->move(QCursor::pos()); + bool isDone = aDlg->exec() == QDialog::Accepted; + if (!isDone) + return; + + // 4. set the value to all results + aCurrentValue = aTransparencyWidget->getValue(); + setTransparency(aCurrentValue, theObjects); + + aMgr->finishOperation(); + updateCommandStatus(); +} + +//************************************************************** +void XGUI_Workshop::onTransparencyValueChanged() +{ + XGUI_TransparencyWidget* aTransparencyWidget = (XGUI_TransparencyWidget*)sender(); + if (!aTransparencyWidget || !aTransparencyWidget->isPreviewNeeded()) + return; + + QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); + setTransparency(aTransparencyWidget->getValue(), anObjects); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); +} + +//************************************************************** +void XGUI_Workshop::onPreviewStateChanged() +{ + XGUI_TransparencyWidget* aTransparencyWidget = (XGUI_TransparencyWidget*)sender(); + if (!aTransparencyWidget || !aTransparencyWidget->isPreviewNeeded()) + return; + + QObjectPtrList anObjects = mySelector->selection()->selectedObjects(); + setTransparency(aTransparencyWidget->getValue(), anObjects); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); +} + //************************************************************** #define SET_DISPLAY_GROUP(aGroupName, aDisplay) \ for (int i = 0; i < aDoc->size(aGroupName); i++) { \ diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index 0f0c350fd..871e2df12 100755 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -211,23 +211,25 @@ Q_OBJECT bool canBeShaded(const ObjectPtr& theObject) const; //! Returns true if there is at least one selected body/construction/group result + //! \param theActionName text of the checked action //! \return boolean value - bool canChangeColor() const; + bool canChangeProperty(const QString& theActionName) const; //! Change color of the results if it is possible //! The operation is available for construction, body and group results //! theObjects a list of selected objects void changeColor(const QObjectPtrList& theObjects); - //! Returns true if there is at least one selected body/construction/group result - //! \return boolean value - bool canChangeDeflection() const; - //! Change deflection of the results if it is possible //! The operation is available for construction, body and group results //! theObjects a list of selected objects void changeDeflection(const QObjectPtrList& theObjects); + //! Change transparency of the results if it is possible + //! The operation is available for construction, body and group results + //! theObjects a list of selected objects + void changeTransparency(const QObjectPtrList& theObjects); + //! Show the given features in 3d Viewer void showObjects(const QObjectPtrList& theList, bool isVisible); @@ -423,6 +425,11 @@ signals: /// Activates/deactivates the trihedron in the viewer AIS context void onTrihedronVisibilityChanged(bool theState); + /// Apply the current transparency value if preview in transparency dialog is switched on + void onTransparencyValueChanged(); + + /// Switch on/off preview of transparency change + void onPreviewStateChanged(); protected: /// Sets the granted operations for the parameter operation. Firstly, it finds the nested features diff --git a/src/XGUI/XGUI_pictures.qrc b/src/XGUI/XGUI_pictures.qrc index 222dfd208..d2f9f767e 100644 --- a/src/XGUI/XGUI_pictures.qrc +++ b/src/XGUI/XGUI_pictures.qrc @@ -60,5 +60,7 @@ pictures/eyeclosed.png pictures/eyemiclosed.png pictures/eyeopen.png + + pictures/transparency.png diff --git a/src/XGUI/pictures/transparency.png b/src/XGUI/pictures/transparency.png new file mode 100644 index 0000000000000000000000000000000000000000..774160e4b109a1edc453f50b8646d226a63661b8 GIT binary patch literal 860 zcmV-i1Ec(jP)z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ;(n&-?RCwBA{Qv(y12q9a0I`4wMn*;yK^`6+l5AmN zVPW|2;RDzZfB<4amjoH6rl!UaRxyv^_uu~vfB*ht`1|ia7=r+a{_*QC!}ni*7{31a z!?3k25M&rgN*Rb>00a;dx?#2RkAm4?O+SH}fcOhg1HS(F4dnl3`26iR*f67v zB{1zCKr8_eKrG0HRn9rg@axY%Fdt;lPoSZ{K`sQk^dB&+L2d-GL9W}@7QkSdy`16q z_b)IbR6xc61P~)AQh0fJ35J<~fB=~O_3IbImoHx!%yU*S{Q3C}h`%x%pOFlbngGNL z00Ic^!t6==z~S{1=)$A3a~RaadKiBE2D%W)2fGexo?Gazae1=G92A728RDo3?%>mWBC8?FBl^OfB<4b82FFj7uXPpf&czv8U|wj{|Ax( z4|M6jzrQhD2oOMU13~HQ9~47efX%Q!K!bk6z5Mt04-5kV0tn${pjUqby$$#B??3SH z0vq`6AK1V@KfgmF=f`JYquz?p=AX_kTU)>;Nu zAe$A+2PGvC00|kIuN@4i@?IXlMP%J_M5A1z#BtX6R7wFwP`{%(7 z13B*nhz1BCcuoNo2+Vp3;FSOO_jhohgOkL6gbP72`xh7qclOPJxdUd{1t8u5q5%R3 zY#^}sBBxNqFbotG009K^vH=h$KxtwDhG8H