From 7f8102c36933647ceb675ed39c11601f8fcfe0bd Mon Sep 17 00:00:00 2001 From: Mathias Paulin <mathias.paulin@irit.fr> Date: Fri, 11 Feb 2022 16:51:11 +0100 Subject: [PATCH] [nodeeditor] fix loading/updating nodeGraph when the renderer has already one --- src/Mara/RadiumPlayer.cpp | 21 +++--- .../include/nodes/internal/FlowScene.hpp | 10 +++ .../RadiumNBR/Gui/NodeGraphControllerGui.cpp | 34 ++++++++- .../RenderGraphEditor/EnvMapSourceModel.cpp | 3 + .../RenderGraphEditor/EnvMapSourceModel.hpp | 2 + .../RenderGraphEditor/NodeAdapterModel.hpp | 4 + .../RenderGraphEditor/NodeAdapterModel.inl | 73 +++++++++++++++++++ .../RenderGraphEditorView.cpp | 4 +- .../RadiumNBR/NodeGraph/NodeFactory.cpp | 1 + .../RadiumNBR/NodeGraph/RenderGraph.cpp | 4 +- 10 files changed, 141 insertions(+), 15 deletions(-) diff --git a/src/Mara/RadiumPlayer.cpp b/src/Mara/RadiumPlayer.cpp index e49edd4..0525110 100644 --- a/src/Mara/RadiumPlayer.cpp +++ b/src/Mara/RadiumPlayer.cpp @@ -218,7 +218,17 @@ void RadiumPlayer::addRenderers() { // 2 - Initialize the renderer using default or customized NodeGraphController auto renderControl = new RadiumNBR::NodeGraphController; auto myRenderer = std::make_shared<RadiumNBR::NodeBasedRenderer>( *renderControl ); -// TODO find why this is problematic as the graph is not displayed in the editor + + std::string rendererName = myRenderer->getRendererName(); + // The panel returned by buildNodeGraphControllerGui will manage the Qt NodeEditor window + // This function must initialize the default nodeEditor functionality for the edited renderGraph + // (i.e. DataModelRegistry) + auto controlPanel = RadiumNBR::buildNodeGraphControllerGui( + myRenderer.get(), [this]() { this->askForUpdate(); } ); + + + mainWindow->addRenderer( rendererName, myRenderer, controlPanel ); + #if 1 // 3 - load default graph or user provided graph auto resourcesCheck = @@ -238,15 +248,6 @@ void RadiumPlayer::addRenderers() { myRenderer->signalReloadJson(); #endif - std::string rendererName = myRenderer->getRendererName(); - // The panel returned by buildNodeGraphControllerGui will manage the Qt NodeEditor window - // This function must initialize the default nodeEditor functionality for the edited renderGraph - // (i.e. DataModelRegistry) - auto controlPanel = RadiumNBR::buildNodeGraphControllerGui( - myRenderer.get(), [this]() { this->askForUpdate(); } ); - - - mainWindow->addRenderer( rendererName, myRenderer, controlPanel ); } // add the default forward renderer diff --git a/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/FlowScene.hpp b/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/FlowScene.hpp index 6d59725..184f727 100644 --- a/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/FlowScene.hpp +++ b/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/FlowScene.hpp @@ -100,6 +100,14 @@ public: void loadFromMemory(const QByteArray& data); + void setSceneName(const QString& newname) { + _scenename = newname; + } + + QString getSceneName() const { + return _scenename; + } + Q_SIGNALS: /** @@ -148,6 +156,8 @@ private: std::unordered_map<QUuid, SharedConnection> _connections; std::unordered_map<QUuid, UniqueNode> _nodes; + // name of the scene + QString _scenename {""}; private Q_SLOTS: void setupConnectionSignals(Connection const& c); diff --git a/src/libRender/RadiumNBR/Gui/NodeGraphControllerGui.cpp b/src/libRender/RadiumNBR/Gui/NodeGraphControllerGui.cpp index bfe42ae..7d1248e 100644 --- a/src/libRender/RadiumNBR/Gui/NodeGraphControllerGui.cpp +++ b/src/libRender/RadiumNBR/Gui/NodeGraphControllerGui.cpp @@ -37,6 +37,7 @@ RadiumNBR::Gui::RendererPanel* buildNodeGraphControllerGui( NodeBasedRenderer* r QFile file( fileName ); if ( file.open( QIODevice::ReadOnly ) ) { nodeEditor->scene->clearScene(); + renderer->getRenderGraph()->clearNodes(); QByteArray wholeFile = file.readAll(); nodeEditor->scene->loadFromMemory( wholeFile ); nodeEditor->setWindowTitle( std::string( "RenderGraph Node Editor - " + @@ -44,6 +45,7 @@ RadiumNBR::Gui::RendererPanel* buildNodeGraphControllerGui( NodeBasedRenderer* r " - " + fileName.toStdString() ) .c_str() ); renderer->setJsonFilePath( fileName.toStdString() ); + nodeEditor->scene->setSceneName( fileName ); appUpdateCallback(); } } @@ -109,15 +111,43 @@ RadiumNBR::Gui::RendererPanel* buildNodeGraphControllerGui( NodeBasedRenderer* r nodeEditor->connections.push_back( QObject::connect( nodeEditor->newAction, &QAction::triggered, newGraph) ); - controlPanel->addButton( "Node Editor", [nodeEditor]() { + + auto show_hideNodeEditor = [renderer, nodeEditor]() { if ( !nodeEditor->isVisible() ) { + // Fill the flowscene in the editor with the current graph if any + if ( renderer->getJsonFilePath() != "" ) { + // Fill the editor with the current graph ... + // TODO modify the editor to reflect exactly the same graph than in the renderer (e.g. if adding a node programatically, update the flowscene + if ( nodeEditor->scene->getSceneName().compare( renderer->getJsonFilePath().c_str() ) != 0) { + if ( QFileInfo::exists( renderer->getJsonFilePath().c_str() ) ) + { + QFile file( renderer->getJsonFilePath().c_str() ); + if ( file.open( QIODevice::ReadOnly ) ) + { + std::cerr << "Loading nodegraph " << renderer->getJsonFilePath() << " in the editor." << std::endl; + nodeEditor->scene->clearScene(); + renderer->getRenderGraph()->clearNodes(); + QByteArray wholeFile = file.readAll(); + nodeEditor->scene->loadFromMemory( wholeFile ); + nodeEditor->scene->setSceneName( renderer->getJsonFilePath().c_str() ); + nodeEditor->setWindowTitle( std::string( "RenderGraph Node Editor - " + + renderer->getRendererName() + " - " + + renderer->getJsonFilePath() ) + .c_str() ); + } + } + } + } + nodeEditor->resize(800, 600); nodeEditor->show(); } else { nodeEditor->hide(); } - } ); + }; + + controlPanel->addButton( "Node Editor", show_hideNodeEditor ); controlPanel->beginLayout( QBoxLayout::LeftToRight ); controlPanel->addButton( "Open graph", loadGraph ); diff --git a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/EnvMapSourceModel.cpp b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/EnvMapSourceModel.cpp index c7e8430..a8371fd 100644 --- a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/EnvMapSourceModel.cpp +++ b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/EnvMapSourceModel.cpp @@ -1,3 +1,4 @@ +#if 0 #include <RadiumNBR/Gui/PowerSlider.hpp> #include <RadiumNBR/Gui/RenderGraphEditor/EnvMapSourceModel.hpp> #include <RadiumNBR/Gui/RendererPanel.hpp> @@ -105,3 +106,5 @@ NodeBasedRenderer_LIBRARY_API void EnvMapSourceModel::restore( QJsonObject const slider->setValue( s ); } } + +#endif diff --git a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/EnvMapSourceModel.hpp b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/EnvMapSourceModel.hpp index aa626bd..d48afe2 100644 --- a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/EnvMapSourceModel.hpp +++ b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/EnvMapSourceModel.hpp @@ -1,6 +1,8 @@ +#if 0 #pragma once #include <RadiumNBR/Gui/RenderGraphEditor/SourceNodeModel.hpp> #include <RadiumNBR/EnvMap.hpp> using EnvMapData = std::shared_ptr<RadiumNBR::EnvMap>; using EnvMapSourceModel = SourceNodeModel<EnvMapData>; +#endif diff --git a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.hpp b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.hpp index bf59f68..1c5ca10 100644 --- a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.hpp +++ b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.hpp @@ -200,6 +200,10 @@ class NodeAdapterModel : public QtNodes::NodeDataModel std::vector<bool> m_inputsConnected; mutable QtNodes::NodeValidationState m_validationState = QtNodes::NodeValidationState::Valid; mutable QString m_validationError = QString( "" ); + + public: + QJsonObject save() const override; + void restore(QJsonObject const & p) override; }; #include <RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.inl> diff --git a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.inl b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.inl index c6734ca..a13f4f4 100644 --- a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.inl +++ b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.inl @@ -1,3 +1,14 @@ + +template <typename T> +QJsonObject NodeAdapterModel<T>::save() const { + return QtNodes::NodeDataModel::save(); +} + +template <typename T> +void NodeAdapterModel<T>::restore( const QJsonObject& p ) { + QtNodes::NodeDataModel::restore(p); +} + template <> void NodeAdapterModel<DataNode<NodeTypeRenderObject>>::init() { m_node = m_renderGraph->getDataNode<NodeTypeRenderObject>(); @@ -45,3 +56,65 @@ template <> void NodeAdapterModel<DisplaySinkNode>::destroy() { } + +// --------- +// method specialization for models with internal parameters +#include <RadiumNBR/NodeGraph/PremadeNodes/Sources/SourceNode.hpp> +#include <RadiumNBR/Gui/PowerSlider.hpp> +#include <filesystem> +template <> +QJsonObject NodeAdapterModel<SourceNode<std::shared_ptr<RadiumNBR::EnvMap>>>::save() const { + QJsonObject modelJson = NodeDataModel::save(); + modelJson["files"] = m_node->getData()->getImageName().c_str(); + modelJson["type"] = QString::number( int( m_node->getData()->getImageType() ) ); + modelJson["strength"] = QString::number( float( m_node->getData()->getEnvStrength() ) * 100. ); + return modelJson; +} + +template <> +void NodeAdapterModel<SourceNode<std::shared_ptr<RadiumNBR::EnvMap>>>::restore( QJsonObject const& p ) { + auto controlPanel = dynamic_cast<RadiumNBR::Gui::RendererPanel*>( m_widget ); + + QJsonValue n = p["files"]; + std::string files = n.toString().toStdString(); + if ( files.empty() ) { m_node->setData( nullptr ); } + else + { + std::string type = p["type"].toString().toStdString(); + int t = std::stoi( type ); + RadiumNBR::EnvMap::EnvMapType envType; + switch ( t ) + { + case 0: + envType = RadiumNBR::EnvMap::EnvMapType::ENVMAP_PFM; + break; + case 1: + envType = RadiumNBR::EnvMap::EnvMapType::ENVMAP_CUBE; + break; + case 2: + envType = RadiumNBR::EnvMap::EnvMapType::ENVMAP_LATLON; + break; + } + // check if the file exists + bool envmap_exist; + float s = 100.; + if ( envType == RadiumNBR::EnvMap::EnvMapType::ENVMAP_CUBE ) + { + std::string f1 = files.substr( 0, files.find( ';' ) - 1 ); + envmap_exist = std::filesystem::exists( f1 ); + } + else + { envmap_exist = std::filesystem::exists( files ); } + if ( !envmap_exist ) { m_node->setData( nullptr ); } + else + { + // for now, only skyboxes are managed + m_node->setData( std::make_shared<RadiumNBR::EnvMap>( files, envType, true ) ); + s = std::atof( p["strength"].toString().toStdString().c_str() ); + m_node->getData()->setEnvStrength( s / 100. ); + } + // This assume thereis only one powerslider in the control panel + auto slider = controlPanel->findChild<PowerSlider*>( "Strength" ); + slider->setValue( s ); + } +} diff --git a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/RenderGraphEditorView.cpp b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/RenderGraphEditorView.cpp index c8fe4aa..415c253 100644 --- a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/RenderGraphEditorView.cpp +++ b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/RenderGraphEditorView.cpp @@ -223,10 +223,10 @@ RenderGraphEditorView::RenderGraphEditorView( QWidget* parent ) : QWidget( paren #include <RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.hpp> #include <RadiumNBR/Gui/RenderGraphEditor/FilterRenderObjectNameModel.hpp> #include <RadiumNBR/Gui/RenderGraphEditor/FilterRenderObjectTypeModel.hpp> -#include <RadiumNBR/Gui/RenderGraphEditor/EnvMapSourceModel.hpp> #include <RadiumNBR/Gui/RenderGraphEditor/SourceColorTextureModel.hpp> #include <RadiumNBR/Gui/RenderGraphEditor/SourceDepthTextureModel.hpp> -#include <RadiumNBR/Gui/RenderGraphEditor/SourceNodeModel.hpp> + +using EnvMapData = std::shared_ptr<RadiumNBR::EnvMap>; #include <RadiumNBR/NodeGraph/PremadeNodes/PremadeNodesIncludes.hpp> diff --git a/src/libRender/RadiumNBR/NodeGraph/NodeFactory.cpp b/src/libRender/RadiumNBR/NodeGraph/NodeFactory.cpp index 4949c9c..a8aabc7 100644 --- a/src/libRender/RadiumNBR/NodeGraph/NodeFactory.cpp +++ b/src/libRender/RadiumNBR/NodeGraph/NodeFactory.cpp @@ -69,6 +69,7 @@ void initializeNodeFactory() { float red = std::stof( valueRed ) / 255.0f; float green = std::stof( valueGreen ) / 255.0f; float blue = std::stof( valueBlue ) / 255.0f; + auto sourceColor = new SourceNode<NodeTypeColor>( "color" + std::to_string( NodeFactory::newNodeId() ) ); diff --git a/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp b/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp index 26bc5ae..0b44a8a 100644 --- a/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp +++ b/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp @@ -124,7 +124,9 @@ void RenderGraph::loadFromJson( const std::string& jsonFilePath ) { { nodeById.emplace( id, getDisplayNode() ); } else { - Node* newNode = NodeFactory::createNode( name, n ); + auto newNode = NodeFactory::createNode( name, n ); + + std::cerr << "TYPE = " << typeid(*newNode).name() << " --- " << std::endl; nodeById.emplace( id, newNode ); addNode( newNode ); } -- GitLab