diff --git a/ApplicationComponents/CMakeLists.txt b/ApplicationComponents/CMakeLists.txt index 2530060dcab226311263cca86896cb1ce63e80cf..e1fd159c64092ab01d69cf123e18f4c17670f2df 100644 --- a/ApplicationComponents/CMakeLists.txt +++ b/ApplicationComponents/CMakeLists.txt @@ -37,6 +37,8 @@ add_library(lqApplicationComponents LidarCameraToolbar/lqLidarCameraToolbar.cxx LidarCameraToolbar/lqLidarCameraToolbar.h LidarCameraToolbar/lqLidarCameraToolbar.ui + lqEnableAdvancedArraysReaction.cxx + lqEnableAdvancedArraysReaction.h lqResources.qrc ) target_include_directories(lqApplicationComponents PUBLIC diff --git a/ApplicationComponents/Icons/DisableAdvancedArrays.png b/ApplicationComponents/Icons/DisableAdvancedArrays.png new file mode 100644 index 0000000000000000000000000000000000000000..6eb6def7ac7a07d830ba92be67fec01df55837da Binary files /dev/null and b/ApplicationComponents/Icons/DisableAdvancedArrays.png differ diff --git a/ApplicationComponents/Icons/EnableAdvancedArrays.png b/ApplicationComponents/Icons/EnableAdvancedArrays.png new file mode 100644 index 0000000000000000000000000000000000000000..f016635d46f6c2b0358aabc4b3146e1b0d1363cc Binary files /dev/null and b/ApplicationComponents/Icons/EnableAdvancedArrays.png differ diff --git a/ApplicationComponents/SaveAndLoadLidarState/lqLoadLidarStateReaction.cxx b/ApplicationComponents/SaveAndLoadLidarState/lqLoadLidarStateReaction.cxx index 5201b6e3d0c059dc50f378c5834e3f73d5d7abe8..41ae3f8b28323f2c8db64aafcadc6c7564dfaccd 100644 --- a/ApplicationComponents/SaveAndLoadLidarState/lqLoadLidarStateReaction.cxx +++ b/ApplicationComponents/SaveAndLoadLidarState/lqLoadLidarStateReaction.cxx @@ -7,8 +7,6 @@ #include <QMessageBox> #include <pqApplicationCore.h> -#include <pqPipelineSource.h> -#include <pqServerManagerModel.h> #include <vtkSmartPointer.h> #include <vtkSMProxy.h> @@ -16,7 +14,6 @@ #include <vtkSMPropertyIterator.h> #include <vtkSMPropertyHelper.h> #include <vtkSMSourceProxy.h> -#include <vtkSMBooleanDomain.h> #include <cstring> #include <vector> @@ -43,33 +40,21 @@ void lqLoadLidarStateReaction::onTriggered() } // Get the first lidar source - pqServerManagerModel* smmodel = pqApplicationCore::instance()->getServerManagerModel(); - if(smmodel == nullptr) + std::vector<vtkSMProxy*> lidarProxys = GetLidarsProxy(); + + if(lidarProxys.empty()) { + QMessageBox::warning(nullptr, tr(""), tr("No lidar source found in the pipeline") ); return; } - vtkSMProxy * lidarCurrentProxy = nullptr; - foreach (pqPipelineSource* src, smmodel->findItems<pqPipelineSource*>()) - { - if(IsLidarProxy(src->getProxy())) - { - if(lidarCurrentProxy == nullptr) - { - lidarCurrentProxy = src->getProxy(); - } - else - { - QMessageBox::warning(nullptr, tr(""), tr("Multiple lidars sources found, only the first one will be updated") ); - } - } - } - if(lidarCurrentProxy == nullptr) + if(lidarProxys.size() > 1) { - QMessageBox::warning(nullptr, tr(""), tr("No lidar source found in the pipeline") ); - return; + QMessageBox::warning(nullptr, tr(""), tr("Multiple lidars sources found, only the first one will be updated") ); } + vtkSMProxy * lidarCurrentProxy = lidarProxys[0]; + // Read and get information of the JSON file Json::Value contents; std::ifstream file(LidarStateFile.toStdString()); @@ -104,7 +89,7 @@ void lqLoadLidarStateReaction::onTriggered() { std::string proxyName = currentProp.proxyName; std::string propertyName = currentProp.propertyName; - vtkSMProxy* lidarProxy = this->SearchProxy(lidarCurrentProxy, proxyName); + vtkSMProxy* lidarProxy = SearchProxyByName(lidarCurrentProxy, proxyName); if (lidarProxy == nullptr) { @@ -113,7 +98,7 @@ void lqLoadLidarStateReaction::onTriggered() } else { - this->UpdateProperty(lidarProxy, propertyName, currentProp.values); + UpdateProperty(lidarProxy, propertyName, currentProp.values); } } } @@ -165,102 +150,3 @@ void lqLoadLidarStateReaction::ParseJsonContent(Json::Value contents, std::strin } } - -//----------------------------------------------------------------------------- -vtkSMProxy* lqLoadLidarStateReaction::SearchProxy(vtkSMProxy * base_proxy, - std::string proxyName) -{ - if(std::strcmp(base_proxy->GetXMLName(), proxyName.c_str()) == 0) - { - return base_proxy; - } - - vtkSmartPointer<vtkSMPropertyIterator> propIter; - propIter.TakeReference(base_proxy->NewPropertyIterator()); - for (propIter->Begin(); !propIter->IsAtEnd(); propIter->Next()) - { - vtkSMProperty* prop = propIter->GetProperty(); - - // If the property is a valid proxy, we print all the properties of the proxy at the end - vtkSMProxy* propertyAsProxy = vtkSMPropertyHelper(prop).GetAsProxy(); - if(propertyAsProxy) - { - return SearchProxy(propertyAsProxy, proxyName); - } - } - return nullptr; -} - -//----------------------------------------------------------------------------- -void lqLoadLidarStateReaction::UpdateProperty(vtkSMProxy * proxy, - std::string propNameToFind, - std::vector<std::string> values) -{ - // If there is no value to set, the request is skipped - if(values.size() < 1) - { - std::string message = "Property " + propNameToFind + " couldn't be applied"; - QMessageBox::information(nullptr, tr(""), tr(message.c_str()) ); - return; - } - - vtkSmartPointer<vtkSMPropertyIterator> propIter; - propIter.TakeReference(proxy->NewPropertyIterator()); - for (propIter->Begin(); !propIter->IsAtEnd(); propIter->Next()) - { - vtkSMProperty* prop = propIter->GetProperty(); - const char* propName = propIter->GetKey(); - - // If the name does not match we skip the property - if(std::strcmp(propName, propNameToFind.c_str()) != 0) - { - continue; - } - - // Both properties match - std::vector<double> propertyAsDoubleArray = vtkSMPropertyHelper(prop).GetDoubleArray(); - if(propertyAsDoubleArray.size() > 1) - { - if(propertyAsDoubleArray.size() != values.size()) - { - std::cout << "Values to applied and base property does not have the same size" << std::endl; - } - std::vector<double> d; - for(unsigned int j = 0; j < values.size(); j++) - { - d.push_back(std::stod(values[j])); - } - vtkSMPropertyHelper(prop).Set(d.data(), d.size()); - } - else - { - // If the property is a valid variant we display it to the user - vtkVariant propertyAsVariant = vtkSMPropertyHelper(prop).GetAsVariant(0); - if(propertyAsVariant.IsValid()) - { - if(propertyAsVariant.IsInt()) - { - vtkSMBooleanDomain * boolDomain = vtkSMBooleanDomain::SafeDownCast(prop->FindDomain("vtkSMBooleanDomain")); - if(boolDomain) - { - int value = (values[0].compare("false") == 0) ? 0 : 1; - vtkSMPropertyHelper(prop).Set(value); - } - else - { - vtkSMPropertyHelper(prop).Set(std::stoi(values[0])); - } - } - else if(propertyAsVariant.IsNumeric()) - { - vtkSMPropertyHelper(prop).Set(std::stof(values[0])); - - } - else if(propertyAsVariant.IsString()) - { - vtkSMPropertyHelper(prop).Set(values[0].c_str()); - } - } - } - } -} diff --git a/ApplicationComponents/SaveAndLoadLidarState/lqLoadLidarStateReaction.h b/ApplicationComponents/SaveAndLoadLidarState/lqLoadLidarStateReaction.h index 5c50d6d3d58ddb7eec70aab6fb75e90b4bdb9dca..49eecf7ac43c1f432fd1478620caf4c3782560b6 100644 --- a/ApplicationComponents/SaveAndLoadLidarState/lqLoadLidarStateReaction.h +++ b/ApplicationComponents/SaveAndLoadLidarState/lqLoadLidarStateReaction.h @@ -44,24 +44,6 @@ private: */ void ParseJsonContent(Json::Value contents, std::string ObjectName, std::vector<propertyInfo>& propertyInfo); - /** - * @brief SearchProxy search recursively a proxy in an other one - * @param base_proxy - * @param proxyName name of the proxy to search - * @return the subproxy of name proxyname, nullptr if nothing found - */ - vtkSMProxy* SearchProxy(vtkSMProxy * base_proxy, std::string proxyName); - - /** - * @brief UpdateProperty set the values to the property "propNameToFind" of the proxy - * If the property is not found in the proxy, a message is displayed but nothing is done - * @param proxy proxy where to search the property - * @param propNameToFind name of the property - * @param values properties values to set - */ - void UpdateProperty(vtkSMProxy * proxy, std::string propNameToFind, - std::vector<std::string> values); - }; #endif // LQLOADLIDARSTATEREACTION_H diff --git a/ApplicationComponents/lqEnableAdvancedArraysReaction.cxx b/ApplicationComponents/lqEnableAdvancedArraysReaction.cxx new file mode 100644 index 0000000000000000000000000000000000000000..acd4647b150f2fdee78dc7b9f6e6aab522e1f82a --- /dev/null +++ b/ApplicationComponents/lqEnableAdvancedArraysReaction.cxx @@ -0,0 +1,92 @@ +#include "lqEnableAdvancedArraysReaction.h" + +#include "lqHelper.h" + +#include <QFileDialog> +#include <QMessageBox> + +#include <pqApplicationCore.h> +#include <pqFileDialog.h> +#include <pqServerManagerModel.h> +#include <pqPipelineSource.h> +#include <vtkSMSourceProxy.h> +#include <vtkSMPropertyHelper.h> + +//----------------------------------------------------------------------------- +lqEnableAdvancedArraysReaction::lqEnableAdvancedArraysReaction(QAction *action) + : Superclass(action) +{ + this->parentAction()->setEnabled(false); + auto* core = pqApplicationCore::instance(); + + pqServerManagerModel* smmodel = core->getServerManagerModel(); + this->connect(smmodel, SIGNAL(sourceAdded(pqPipelineSource*)), SLOT(onSourceAdded(pqPipelineSource*))); + this->connect(smmodel, SIGNAL(sourceRemoved(pqPipelineSource*)), SLOT(onSourceRemoved(pqPipelineSource*))); + + foreach (pqPipelineSource* src, smmodel->findItems<pqPipelineSource*>()) + this->onSourceAdded(src); + + this->parentAction()->setCheckable(true); +} + +//----------------------------------------------------------------------------- +void lqEnableAdvancedArraysReaction::onTriggered() +{ + int booleanToSet = 0; + // Declare the value to set to the property + if(this->parentAction()->isChecked()) + { + booleanToSet = 1; // the property should be set to "true" + // Change icon and tooltip of the button to disable advance array + this->parentAction()->setIcon(QIcon(":/lqResources/Icons/DisableAdvancedArrays.png")); + this->parentAction()->setToolTip(QString("Disable the interpreter's advanced arrays.")); + + } + else + { + booleanToSet = 0; // the property should be set to "false" + // Change icon and tooltip of the button to enable advance array + this->parentAction()->setIcon(QIcon(":/lqResources/Icons/EnableAdvancedArrays.png")); + this->parentAction()->setToolTip(QString("Enable the interpreter's advanced arrays.")); + } + + // Update all lidar proxy with the new property value + std::vector<vtkSMProxy*> lidarProxys = GetLidarsProxy(); + for(vtkSMProxy* proxy : lidarProxys) + { + vtkSMProxy* interp = SearchProxyByGroupName(proxy, "LidarPacketInterpreter"); + if(interp != nullptr) + { + vtkSMProperty* property = GetPropertyFromProxy(interp, "EnableAdvancedArrays"); + vtkSMPropertyHelper(property).Set(booleanToSet); + + //Update the proxy + proxy->UpdateSelfAndAllInputs(); + vtkSMSourceProxy * sourcelidarProxy = vtkSMSourceProxy::SafeDownCast(proxy); + if(sourcelidarProxy) + { + sourcelidarProxy->UpdatePipelineInformation(); + } + pqApplicationCore::instance()->render(); + } + } +} + +//----------------------------------------------------------------------------- +void lqEnableAdvancedArraysReaction::onSourceAdded(pqPipelineSource *src) +{ + if (!this->parentAction()->isEnabled() && IsLidarProxy(src->getProxy())) + { + this->parentAction()->setEnabled(true); + } +} + +//----------------------------------------------------------------------------- +void lqEnableAdvancedArraysReaction::onSourceRemoved(pqPipelineSource * vtkNotUsed(src)){ + if (this->parentAction()->isEnabled() && !HasLidarProxy()) + { + this->parentAction()->setEnabled(false); + this->parentAction()->setChecked(false); + this->parentAction()->setIcon(QIcon(":/lqResources/Icons/EnableAdvancedArrays.png")); + } +} diff --git a/ApplicationComponents/lqEnableAdvancedArraysReaction.h b/ApplicationComponents/lqEnableAdvancedArraysReaction.h new file mode 100644 index 0000000000000000000000000000000000000000..c8bbde2c2e950d693dfdd2310c382d913675669d --- /dev/null +++ b/ApplicationComponents/lqEnableAdvancedArraysReaction.h @@ -0,0 +1,39 @@ +#ifndef LqEnableAdvancedArraysReaction_h +#define LqEnableAdvancedArraysReaction_h + +#include <pqReaction.h> + +#include "lqapplicationcomponents_export.h" + +class pqPipelineSource; +/** +* @ingroup Reactions +* Reaction to enable and disable advanced arrays +*/ +class LQAPPLICATIONCOMPONENTS_EXPORT lqEnableAdvancedArraysReaction : public pqReaction +{ + Q_OBJECT + typedef pqReaction Superclass; + +public: + lqEnableAdvancedArraysReaction(QAction* action); + +public slots: + /** + * Called when the action is triggered. + */ + void onTriggered() override; + + /** + * Monitor the added/deleted source to enable/disable the QAction + */ + void onSourceAdded(pqPipelineSource* src); + void onSourceRemoved(pqPipelineSource* src); + + +private: + Q_DISABLE_COPY(lqEnableAdvancedArraysReaction) + +}; + +#endif // LqEnableAdvancedArraysReaction_h diff --git a/ApplicationComponents/lqHelper.cxx b/ApplicationComponents/lqHelper.cxx index 972f5ba37389d57134fd0bc2ca1ee66e76ed0895..0d2fb69b9bf03d3cd72168facb3d30ab85847902 100644 --- a/ApplicationComponents/lqHelper.cxx +++ b/ApplicationComponents/lqHelper.cxx @@ -1,7 +1,21 @@ #include "lqHelper.h" +#include <QMessageBox> +#include <QString> +#include <QObject> + #include "vtkLidarReader.h" #include "vtkLidarStream.h" +#include <vtkSMBooleanDomain.h> +#include <vtkSMPropertyIterator.h> +#include <vtkSMPropertyHelper.h> + +#include <pqApplicationCore.h> +#include <pqPipelineSource.h> +#include <pqServerManagerModel.h> + +#include <cstring> +#include <iostream> //----------------------------------------------------------------------------- bool IsLidarProxy(vtkSMProxy * proxy) @@ -17,3 +31,178 @@ bool IsLidarProxy(vtkSMProxy * proxy) } return false; } + +//----------------------------------------------------------------------------- +bool HasLidarProxy() +{ + pqServerManagerModel* smmodel = pqApplicationCore::instance()->getServerManagerModel(); + foreach (pqPipelineSource* src, smmodel->findItems<pqPipelineSource*>()) + { + if (IsLidarProxy(src->getProxy())) + { + return true; + } + } + return false; +} + +//----------------------------------------------------------------------------- +vtkSMProxy* SearchProxyByName(vtkSMProxy * base_proxy, const std::string &proxyName) +{ + if(std::strcmp(base_proxy->GetXMLName(), proxyName.c_str()) == 0 || + std::strcmp(base_proxy->GetXMLLabel(), proxyName.c_str()) == 0) + { + return base_proxy; + } + + vtkSmartPointer<vtkSMPropertyIterator> propIter; + propIter.TakeReference(base_proxy->NewPropertyIterator()); + for (propIter->Begin(); !propIter->IsAtEnd(); propIter->Next()) + { + vtkSMProperty* prop = propIter->GetProperty(); + + // Search the proxy in the subProxy if its valid + vtkSMProxy* propertyAsProxy = vtkSMPropertyHelper(prop).GetAsProxy(); + if(propertyAsProxy) + { + vtkSMProxy* subProxy = SearchProxyByName(propertyAsProxy, proxyName); + if(subProxy) + { + return subProxy; + } + } + } + return nullptr; +} + +//----------------------------------------------------------------------------- +vtkSMProxy* SearchProxyByGroupName(vtkSMProxy * base_proxy, const std::string &proxyGroupName) +{ + if(std::strcmp(base_proxy->GetXMLGroup(), proxyGroupName.c_str()) == 0) + { + return base_proxy; + } + + vtkSmartPointer<vtkSMPropertyIterator> propIter; + propIter.TakeReference(base_proxy->NewPropertyIterator()); + for (propIter->Begin(); !propIter->IsAtEnd(); propIter->Next()) + { + vtkSMProperty* prop = propIter->GetProperty(); + + // Search the proxy in the subProxy if its valid + vtkSMProxy* propertyAsProxy = vtkSMPropertyHelper(prop).GetAsProxy(); + if(propertyAsProxy) + { + vtkSMProxy* subProxy = SearchProxyByGroupName(propertyAsProxy, proxyGroupName); + if(subProxy) + { + return subProxy; + } + } + } + return nullptr; +} + +//----------------------------------------------------------------------------- +std::vector<vtkSMProxy*> GetLidarsProxy() +{ + std::vector<vtkSMProxy*> lidarProxys; + pqServerManagerModel* smmodel = pqApplicationCore::instance()->getServerManagerModel(); + if(smmodel == nullptr) + { + return lidarProxys; + } + foreach (pqPipelineSource* src, smmodel->findItems<pqPipelineSource*>()) + { + if(IsLidarProxy(src->getProxy())) + { + lidarProxys.push_back(src->getProxy()); + } + } + return lidarProxys; +} + +//----------------------------------------------------------------------------- +vtkSMProperty* GetPropertyFromProxy(vtkSMProxy * proxy, const std::string &propNameToFind) +{ + vtkSmartPointer<vtkSMPropertyIterator> propIter; + propIter.TakeReference(proxy->NewPropertyIterator()); + for (propIter->Begin(); !propIter->IsAtEnd(); propIter->Next()) + { + vtkSMProperty* prop = propIter->GetProperty(); + const char* propName = propIter->GetKey(); + + // If the name does not match we skip the property + if(std::strcmp(propName, propNameToFind.c_str()) == 0) + { + return prop; + } + } + std::cout << "Property not found " << std::endl; + return nullptr; +} + +//----------------------------------------------------------------------------- +void UpdateProperty(vtkSMProxy * proxy, const std::string &propNameToFind, + const std::vector<std::string> &values) +{ + // If there is no value to set, the request is skipped + if(values.empty()) + { + std::string message = "Property " + propNameToFind + " couldn't be applied"; + QMessageBox::information(nullptr, QObject::tr(""), QObject::tr(message.c_str()) ); + return; + } + + vtkSMProperty* prop = GetPropertyFromProxy(proxy, propNameToFind); + + if(!prop) + { + return; + } + + std::vector<double> propertyAsDoubleArray = vtkSMPropertyHelper(prop).GetDoubleArray(); + if(propertyAsDoubleArray.size() > 1) + { + if(propertyAsDoubleArray.size() != values.size()) + { + std::cout << "Values to applied and base property does not have the same size" << std::endl; + } + std::vector<double> d; + for(unsigned int j = 0; j < values.size(); j++) + { + d.push_back(std::stod(values[j])); + } + vtkSMPropertyHelper(prop).Set(d.data(), d.size()); + } + else + { + // If the property is a valid variant we display it to the user + vtkVariant propertyAsVariant = vtkSMPropertyHelper(prop).GetAsVariant(0); + if(propertyAsVariant.IsValid()) + { + if(propertyAsVariant.IsInt()) + { + vtkSMBooleanDomain * boolDomain = vtkSMBooleanDomain::SafeDownCast(prop->FindDomain("vtkSMBooleanDomain")); + if(boolDomain) + { + int value = (values[0].compare("false") == 0) ? 0 : 1; + vtkSMPropertyHelper(prop).Set(value); + } + else + { + vtkSMPropertyHelper(prop).Set(std::stoi(values[0])); + } + } + else if(propertyAsVariant.IsNumeric()) + { + vtkSMPropertyHelper(prop).Set(std::stof(values[0])); + + } + else if(propertyAsVariant.IsString()) + { + vtkSMPropertyHelper(prop).Set(values[0].c_str()); + } + } + } +} diff --git a/ApplicationComponents/lqHelper.h b/ApplicationComponents/lqHelper.h index 567923ce8a235cfe44f9c4bc25859bdb349b25b2..66f3d47d10ff0f151cb594b830cef9f65c280e31 100644 --- a/ApplicationComponents/lqHelper.h +++ b/ApplicationComponents/lqHelper.h @@ -1,7 +1,9 @@ #ifndef LQHELPER_H #define LQHELPER_H +#include <vtkSMProperty.h> #include <vtkSMProxy.h> +#include <vector> /** * @brief IsLidarProxy return true if the proxy is a LidarReader or a LidarStream @@ -10,5 +12,52 @@ */ bool IsLidarProxy(vtkSMProxy * proxy); +/** + * @brief hasLidarProxy look for a lidar proxy in the pipeline + * @return true if there is a lidar proxy in the pipeline + */ +bool HasLidarProxy(); + +/** + * @brief SearchProxyByName search recursively a proxy in an other one using XMLName and XMLLabel + * @param base_proxy + * @param proxyName name of the proxy to search + * @return the subproxy named 'proxyName', nullptr if nothing found + */ +vtkSMProxy* SearchProxyByName(vtkSMProxy * base_proxy, const std::string & proxyName); + +/** + * @brief SearchProxyByGroupName search recursively a proxy in an other one using the XMLGroup + * @param base_proxy + * @param proxyGroupName name of the XML group of the proxy to search + * @return the subproxy of XML group 'proxyGroupName', nullptr if nothing found + */ +vtkSMProxy* SearchProxyByGroupName(vtkSMProxy * base_proxy, const std::string & proxyGroupName); + +/** + * @brief getLidarsProxy search lidar Proxy in the current pipeline + * @return vector of all lidars proxys found + */ +std::vector<vtkSMProxy*> GetLidarsProxy(); + +/** + * @brief GetPropertyFromProxy search a property in a proxy + * @param proxy + * @param propNameToFind name of the property to search + * @return the property named 'propNameToFind', nullptr if nothing found + */ +vtkSMProperty* GetPropertyFromProxy(vtkSMProxy * proxy, const std::string &propNameToFind); + +/** + * @brief UpdateProperty set the values to the property "propNameToFind" of the proxy + * If the property is not found in the proxy, a message is displayed but nothing is done. + * This function is useful, if the property type is unknown. + * If it is known, you should directly use vtkSMPropertyHelper to set the property + * @param proxy proxy where to search the property + * @param propNameToFind name of the property + * @param values properties values to set + */ +void UpdateProperty(vtkSMProxy * proxy, const std::string & propNameToFind, + const std::vector<std::string> & values); #endif // LQHELPER_H diff --git a/ApplicationComponents/lqResources.qrc b/ApplicationComponents/lqResources.qrc index 4f936c2a5623658f87cec9b105a28ec947bdfdf3..a3a024864838046d28405e746825fcacc88f3e8c 100644 --- a/ApplicationComponents/lqResources.qrc +++ b/ApplicationComponents/lqResources.qrc @@ -13,5 +13,7 @@ <file>Icons/pqRotateCameraCW.png</file> <file>Icons/pqZoomToData.png</file> <file>Icons/pqZoomToSelection.png</file> + <file>Icons/EnableAdvancedArrays.png</file> + <file>Icons/DisableAdvancedArrays.png</file> </qresource> </RCC>