From da143d308e45b2752cc2d34436c9a21a057816de Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me?= Date: Wed, 4 Nov 2020 18:37:19 +0100 Subject: [PATCH] CEA : Lot2 - Auto Color for Groups --- src/ModelAPI/ModelAPI_Feature.cpp | 15 ++++ src/ModelAPI/ModelAPI_Tools.cpp | 112 ++++++++++++++++++++++++++---- src/ModelAPI/ModelAPI_Tools.h | 9 +++ src/PartSet/PartSet_Module.cpp | 12 ++-- src/XGUI/XGUI_ColorDialog.cpp | 99 +------------------------- src/XGUI/XGUI_ContextMenuMgr.cpp | 28 +++++++- src/XGUI/XGUI_Workshop.cpp | 68 ++++++++++++++++++ src/XGUI/XGUI_Workshop.h | 7 +- 8 files changed, 232 insertions(+), 118 deletions(-) diff --git a/src/ModelAPI/ModelAPI_Feature.cpp b/src/ModelAPI/ModelAPI_Feature.cpp index 14397b0fe..a35343218 100644 --- a/src/ModelAPI/ModelAPI_Feature.cpp +++ b/src/ModelAPI/ModelAPI_Feature.cpp @@ -23,8 +23,11 @@ #include #include #include +#include +#include #include #include +#include void ModelAPI_Feature::setError(const std::string& theError, bool isSend, @@ -70,6 +73,18 @@ void ModelAPI_Feature::setResult(const std::shared_ptr& theResu // in any case result becomes enabled if (!isDisabled()) // disabled feature may be executed when it is added as not enabled (#2078) theResult->setDisabled(theResult, false); + + Config_Prop* aProp = Config_PropManager::findProp("Visualization", "result_group_Auto_color"); + + if (aProp) { + bool anIsAutoColor = Config_PropManager::boolean("Visualization", "result_group_Auto_color"); + + if (anIsAutoColor && theResult->groupName() == ModelAPI_ResultGroup::group()) { + std::vector aColor; + ModelAPI_Tools::findRandomColor(aColor); + ModelAPI_Tools::setColor(theResult, aColor); + } + } } void ModelAPI_Feature::setResult(const std::shared_ptr& theResult, diff --git a/src/ModelAPI/ModelAPI_Tools.cpp b/src/ModelAPI/ModelAPI_Tools.cpp index e15b280af..5c4e6eae4 100644 --- a/src/ModelAPI/ModelAPI_Tools.cpp +++ b/src/ModelAPI/ModelAPI_Tools.cpp @@ -17,35 +17,38 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include "ModelAPI_Tools.h" -#include + +#include +#include +#include +#include +#include #include #include +#include #include -#include -#include #include +#include +#include #include #include -#include -#include +#include +#include "ModelAPI_Tools.h" #include -#include -#include -#include -#include -#include -#include -#include +#include #include #include -#include -#include #include #include +#include +#include +#include +#include +#include + #define RECURSE_TOP_LEVEL 50 //#define DEBUG_REMOVE_FEATURES @@ -1116,6 +1119,85 @@ std::list referencedFeatures( return aResList; } +void setValues(std::vector& theRGB, const int theRed, const int theGreen, const int theBlue) +{ + theRGB.push_back(theRed); + theRGB.push_back(theGreen); + theRGB.push_back(theBlue); +} + +std::vector HSVtoRGB(int theH, int theS, int theV) +{ + std::vector aRGB; + if (theH < 0 || theH > 360 || + theS < 0 || theS > 100 || + theV < 0 || theV > 100) + return aRGB; + + int aHi = (int)theH/60; + double aV = theV; + double aVmin = (100 - theS)*theV/100; + double anA = (theV - aVmin)* (theH % 60) / 60; + double aVinc = aVmin + anA; + double aVdec = theV - anA; + double aPercentToValue = 255./100; + int aV_int = (int)(aV*aPercentToValue); + int aVinc_int = (int)(aVinc*aPercentToValue); + int aVmin_int = (int)(aVmin*aPercentToValue); + int aVdec_int = (int)(aVdec*aPercentToValue); + + switch(aHi) { + case 0: setValues(aRGB, aV_int, aVinc_int, aVmin_int); break; + case 1: setValues(aRGB, aVdec_int, aV_int, aVmin_int); break; + case 2: setValues(aRGB, aVmin_int, aV_int, aVinc_int); break; + case 3: setValues(aRGB, aVmin_int, aVdec_int, aV_int); break; + case 4: setValues(aRGB, aVinc_int, aVmin_int, aV_int); break; + case 5: setValues(aRGB, aV_int, aVmin_int, aVdec_int); break; + default: break; + } + return aRGB; +} + +std::array, 10> myColorTab = { + std::vector {255, 0, 0}, + std::vector {0, 255, 0}, + std::vector {0, 0, 255}, + std::vector {255, 255, 0}, + std::vector {0, 255, 255}, + std::vector {255, 0, 255}, + std::vector {255, 94, 0}, + std::vector {132, 255, 0}, + std::vector {132, 0, 255}, + std::vector {0, 0, 0}, +}; + +void findRandomColor(std::vector& theValues) +{ + static int i = 0; + static std::vector> usedGeneratedColor; + + theValues.clear(); + if (i < myColorTab.size()) { + theValues = myColorTab[i++]; + } else { + int timeout = 0; + std::vector aHSVColor; + std::vector aRGBColor; + + do { + aHSVColor = {rand() % 360 , rand()%(100 - 75 + 1) + 60, rand()%(100 - 60 + 1) + 75}; + aRGBColor = HSVtoRGB(aHSVColor[0], aHSVColor[1], aHSVColor[2]); + timeout++; + } while ( + timeout < 20 && + std::find(usedGeneratedColor.begin(), usedGeneratedColor.end(), aHSVColor) + != usedGeneratedColor.end() && + std::find(myColorTab.begin(), myColorTab.end(), aRGBColor) != myColorTab.end()); + usedGeneratedColor.push_back(aHSVColor); + theValues = aRGBColor; + } +} + // LCOV_EXCL_STOP } // namespace ModelAPI_Tools diff --git a/src/ModelAPI/ModelAPI_Tools.h b/src/ModelAPI/ModelAPI_Tools.h index e740cd1c9..2e2bbaeb4 100644 --- a/src/ModelAPI/ModelAPI_Tools.h +++ b/src/ModelAPI/ModelAPI_Tools.h @@ -302,6 +302,15 @@ MODELAPI_EXPORT void copyVisualizationAttrs(std::shared_ptr the MODELAPI_EXPORT std::list > referencedFeatures( std::shared_ptr theTarget, const std::string& theFeatureKind, const bool theSortResults); + + +/*! Returns a container with the current color value. +* These are tree int values for RGB definition. +* It returns the next random color. +* \param theValues vector of values +*/ +MODELAPI_EXPORT void findRandomColor(std::vector& theValues); + } #endif diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 78130efca..7f4ef84fa 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -202,9 +202,13 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop) Config_PropManager::registerProp("Visualization", "result_group_color", "Group color", Config_Prop::Color, ModelAPI_ResultGroup::DEFAULT_COLOR()); - Config_PropManager::registerProp("Visualization", - ModelAPI_ResultConstruction::RESULT_COLOR_NAME(), - "Construction color", Config_Prop::Color, ModelAPI_ResultConstruction::DEFAULT_COLOR()); + Config_PropManager::registerProp("Visualization", "result_group_Auto_color", "Auto color", + Config_Prop::Boolean, "false"); + + Config_PropManager::registerProp("Visualization", "result_construction_color", + "Construction color", + Config_Prop::Color, + ModelAPI_ResultConstruction::DEFAULT_COLOR()); Config_PropManager::registerProp("Visualization", "result_part_color", "Part color", Config_Prop::Color, ModelAPI_ResultPart::DEFAULT_COLOR()); @@ -1700,7 +1704,7 @@ void PartSet_Module::processEvent(const std::shared_ptr& theMess CompositeFeaturePtr aSketch = mySketchMgr->activeSketch(); if (aSketch.get()) { ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); - if (PartSet_SketcherMgr::isSketchOperation(anOperation) && + if (PartSet_SketcherMgr::isSketchOperation(anOperation)&& mySketchMgr->previewSketchPlane()->isDisplayed()) mySketchMgr->previewSketchPlane()->createSketchPlane(aSketch, myWorkshop); } diff --git a/src/XGUI/XGUI_ColorDialog.cpp b/src/XGUI/XGUI_ColorDialog.cpp index a3cabb6ff..a37df57fb 100644 --- a/src/XGUI/XGUI_ColorDialog.cpp +++ b/src/XGUI/XGUI_ColorDialog.cpp @@ -84,108 +84,13 @@ std::vector XGUI_ColorDialog::getColor() const return aValues; } -// contains global cash for integer index of the color -> RGB of this color -static std::map > myColorMap; - -void appendValues(std::vector& theRGB, const int theRed, const int theGreen, const int theBlue) -{ - theRGB.push_back(theRed); - theRGB.push_back(theGreen); - theRGB.push_back(theBlue); -} - -bool containsValues(std::map >& theColorMap, std::vector& theValues) -{ - std::map >::const_iterator anIt = theColorMap.begin(), - aLast = theColorMap.end(); - bool isFound = false; - for (; anIt != aLast && !isFound; anIt++) { - std::vector aValues = anIt->second; - isFound = aValues[0] == theValues[0] && - aValues[1] == theValues[1] && - aValues[2] == theValues[2]; - } - return isFound; -} - -std::vector HSVtoRGB(int theH, int theS, int theV) -{ - std::vector aRGB; - if (theH < 0 || theH > 360 || - theS < 0 || theS > 100 || - theV < 0 || theV > 100) - return aRGB; - - int aHi = (int)theH/60; - - double aV = theV; - double aVmin = (100 - theS)*theV/100; - - double anA = (theV - aVmin)* (theH % 60) / 60; - - double aVinc = aVmin + anA; - double aVdec = theV - anA; - - double aPercentToValue = 255./100; - int aV_int = (int)(aV*aPercentToValue); - int aVinc_int = (int)(aVinc*aPercentToValue); - int aVmin_int = (int)(aVmin*aPercentToValue); - int aVdec_int = (int)(aVdec*aPercentToValue); - - switch(aHi) { - case 0: appendValues(aRGB, aV_int, aVinc_int, aVmin_int); break; - case 1: appendValues(aRGB, aVdec_int, aV_int, aVmin_int); break; - case 2: appendValues(aRGB, aVmin_int, aV_int, aVinc_int); break; - case 3: appendValues(aRGB, aVmin_int, aVdec_int, aV_int); break; - case 4: appendValues(aRGB, aVinc_int, aVmin_int, aV_int); break; - case 5: appendValues(aRGB, aV_int, aVmin_int, aVdec_int); break; - default: break; - } - return aRGB; -} - - -void fillColorMap() -{ - if (!myColorMap.empty()) - return; - - int i = 0; - for (int s = 100; s > 0; s = s - 50) - { - for (int v = 100; v >= 40; v = v - 20) - { - for (int h = 0; h < 359 ; h = h + 60) - { - std::vector aColor = HSVtoRGB(h, s, v); - if (containsValues(myColorMap, aColor)) - continue; - myColorMap[i] = aColor; - i++; - } - } - } -} - -void findRandomColor(std::vector& theValues) -{ - theValues.clear(); - if (myColorMap.empty()) { - fillColorMap(); - } - - size_t aSize = myColorMap.size(); - int anIndex = rand() % aSize; - if (myColorMap.find(anIndex) != myColorMap.end()) { - theValues = myColorMap.at(anIndex); - } -} std::vector XGUI_ColorDialog::getRandomColor() const { std::vector aValues; if (isRandomColor()) { - findRandomColor(aValues); + ModelAPI_Tools::findRandomColor(aValues); } return aValues; } + diff --git a/src/XGUI/XGUI_ContextMenuMgr.cpp b/src/XGUI/XGUI_ContextMenuMgr.cpp index 6e1d82e5d..0786609f5 100644 --- a/src/XGUI/XGUI_ContextMenuMgr.cpp +++ b/src/XGUI/XGUI_ContextMenuMgr.cpp @@ -114,6 +114,9 @@ void XGUI_ContextMenuMgr::createActions() aAction = ModuleBase_Tools::createAction(QIcon(":pictures/color.png"), tr("Color..."), aDesktop); addAction("COLOR_CMD", aAction); + aAction = ModuleBase_Tools::createAction(QIcon(""), tr("Auto color"), aDesktop); + addAction("AUTOCOLOR_CMD", aAction); + aAction = ModuleBase_Tools::createAction(QIcon(""), tr("Deflection..."), aDesktop); addAction("DEFLECTION_CMD", aAction); @@ -506,6 +509,8 @@ void XGUI_ContextMenuMgr::updateObjectBrowserMenu() action("COLOR_CMD")->setEnabled(myWorkshop->canChangeProperty("COLOR_CMD")); action("DEFLECTION_CMD")->setEnabled(myWorkshop->canChangeProperty("DEFLECTION_CMD")); action("TRANSPARENCY_CMD")->setEnabled(myWorkshop->canChangeProperty("TRANSPARENCY_CMD")); + action("AUTOCOLOR_CMD")->setEnabled(myWorkshop->canChangeProperty("AUTOCOLOR_CMD")); + #ifdef _DEBUG #ifdef TINSPECTOR action("TINSPECTOR_VIEW")->setEnabled(true); @@ -685,10 +690,31 @@ void XGUI_ContextMenuMgr::buildObjBrowserMenu() aList.append(action("DELETE_CMD")); myObjBrowserMenus[ModelAPI_ResultBody::group()] = aList; // Group menu - myObjBrowserMenus[ModelAPI_ResultGroup::group()] = aList; myObjBrowserMenus[ModelAPI_ResultField::group()] = aList; // Result part menu myObjBrowserMenus[ModelAPI_ResultPart::group()] = aList; + + aList.clear(); + aList.append(action("WIREFRAME_CMD")); + aList.append(action("SHADING_CMD")); + aList.append(mySeparator1); // this separator is not shown as this action is added after show only + // qt list container contains only one instance of the same action + aList.append(action("SHOW_CMD")); + aList.append(action("HIDE_CMD")); + aList.append(action("SHOW_ONLY_CMD")); + aList.append(mySeparator2); + aList.append(action("AUTOCOLOR_CMD")); + aList.append(action("RENAME_CMD")); + aList.append(action("COLOR_CMD")); + aList.append(action("DEFLECTION_CMD")); + aList.append(action("TRANSPARENCY_CMD")); + aList.append(action("SHOW_ISOLINES_CMD")); + aList.append(action("ISOLINES_CMD")); + aList.append(action("SHOW_FEATURE_CMD")); + aList.append(mySeparator3); + aList.append(action("DELETE_CMD")); + // Group menu + myObjBrowserMenus[ModelAPI_ResultGroup::group()] = aList; //------------------------------------- // Feature menu aList.clear(); diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 79ccfdc05..5deed2906 100644 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -154,6 +154,7 @@ #include #include +#include #include #ifdef TINSPECTOR @@ -1740,6 +1741,8 @@ void XGUI_Workshop::onContextMenuCommand(const QString& theId, bool isChecked) moveObjects(theId == "MOVE_SPLIT_CMD"); else if (theId == "COLOR_CMD") changeColor(aObjects); + else if (theId == "AUTOCOLOR_CMD") + changeAutoColor(aObjects); else if (theId == "ISOLINES_CMD") changeIsoLines(aObjects); else if (theId == "SHOW_ISOLINES_CMD") { @@ -2429,6 +2432,15 @@ bool XGUI_Workshop::canChangeProperty(const QString& theActionName) const return hasResults(aObjects, aTypes); } + if (theActionName == "AUTOCOLOR_CMD") { + + QObjectPtrList aObjects = mySelector->selection()->selectedObjects(); + + std::set aTypes; + aTypes.insert(ModelAPI_ResultGroup::group()); + + return hasResults(aObjects, aTypes); + } return false; } @@ -2497,6 +2509,7 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) // 3. abort the previous operation and start a new one SessionPtr aMgr = ModelAPI_Session::get(); QString aDescription = contextMenuMgr()->action("COLOR_CMD")->text(); + aMgr->startOperation(aDescription.toStdString()); // 4. set the value to all results @@ -2521,6 +2534,61 @@ void XGUI_Workshop::changeColor(const QObjectPtrList& theObjects) myViewerProxy->update(); } +//************************************************************** +void XGUI_Workshop::changeAutoColor(const QObjectPtrList& theObjects) +{ + if (!abortAllOperations()) + return; + + std::vector aColor; + + // abort the previous operation and start a new one + SessionPtr aMgr = ModelAPI_Session::get(); + QString aDescription = contextMenuMgr()->action("AUTOCOLOR_CMD")->text(); + aMgr->startOperation(aDescription.toStdString()); + + Config_Prop* aProp = Config_PropManager::findProp("Visualization", "result_group_Auto_color"); + + if (aProp) { + bool anIsAutoColor = Config_PropManager::boolean("Visualization", "result_group_Auto_color"); + + if (anIsAutoColor) { + contextMenuMgr()->action("AUTOCOLOR_CMD")->setText(tr("Auto color")); + aProp->setValue("false"); + } else { + // set the value to all results + foreach (ObjectPtr anObj, theObjects) { + DocumentPtr aDocument = anObj->document(); + std::list anAllFeatures = allFeatures(aDocument); + // find the object iterator + std::list::iterator aObjectIt = anAllFeatures.begin(); + for (; aObjectIt != anAllFeatures.end(); ++ aObjectIt) { + FeaturePtr aFeature = *aObjectIt; + if (aFeature.get()) { + std::list aResults; + ModelAPI_Tools::allResults(aFeature, aResults); + std::list >::const_iterator aIt; + for (aIt = aResults.cbegin(); aIt != aResults.cend(); aIt++) { + ResultPtr aGroupResult = *aIt; + if (aGroupResult.get() && + aGroupResult->groupName() == ModelAPI_ResultGroup::group()) { + ModelAPI_Tools::findRandomColor(aColor); + ModelAPI_Tools::setColor(aGroupResult, aColor); + } + } + } + } + } + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + aMgr->finishOperation(); + updateCommandStatus(); + myViewerProxy->update(); + contextMenuMgr()->action("AUTOCOLOR_CMD")->setText(tr("Disable auto color")); + aProp->setValue("true"); + } + } +} + //************************************************************** void setTransparency(double theTransparency, const QObjectPtrList& theObjects) { diff --git a/src/XGUI/XGUI_Workshop.h b/src/XGUI/XGUI_Workshop.h index 7b996aaa4..3050590c0 100644 --- a/src/XGUI/XGUI_Workshop.h +++ b/src/XGUI/XGUI_Workshop.h @@ -203,6 +203,11 @@ Q_OBJECT /// theObjects a list of selected objects void changeColor(const QObjectPtrList& theObjects); + /// Change Autocolor of the results if it is possible + /// The operation is available for group results + /// theObjects a list of selected objects + void changeAutoColor(const QObjectPtrList& theObjects); + /// 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 @@ -440,7 +445,7 @@ signals: /// Sets the granted operations for the parameter operation. Firstly, it finds the nested features /// and set them into the operation. Secondly, it asks the module about ids of granted operations. /// \param theOperation an operation - void setGrantedFeatures(ModuleBase_Operation* theOperation); + void setGrantedFeatures(ModuleBase_Operation* theOperation); private: /// Display results from document -- 2.39.2