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 184f7270d36bf2bc0d2f5d5030ec6721e187913d..cff22a3f506bca39201465dfc5b57f3c13684588 100644 --- a/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/FlowScene.hpp +++ b/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/FlowScene.hpp @@ -54,10 +54,17 @@ public: std::shared_ptr<Connection> restoreConnection(QJsonObject const &connectionJson); + void importConnection(const QString& fromNodeId, + int fromNodePort, + const QString& toNodeId, + int toNodePort); + void deleteConnection(Connection& connection); Node&createNode(std::unique_ptr<NodeDataModel> && dataModel); + Node&importNode(std::unique_ptr<NodeDataModel> && dataModel); + Node&restoreNode(QJsonObject const& nodeJson); void removeNode(Node& node); diff --git a/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/Node.hpp b/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/Node.hpp index ada5a306651c356376ab197fe29ad1f85a3c4cd7..30742891940018124f127310b024638004ac7fd6 100644 --- a/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/Node.hpp +++ b/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/Node.hpp @@ -47,6 +47,9 @@ public: void restore(QJsonObject const &json) override; + void + import(); + public: QUuid diff --git a/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/NodeDataModel.hpp b/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/NodeDataModel.hpp index e13724860517c196dd98969386d3cc7ebc152cf0..9e2f887ec15aaac2657e5cbb5a024dcd919c41ed 100644 --- a/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/NodeDataModel.hpp +++ b/src/libRender/RadiumNBR/Gui/NodeEditor/include/nodes/internal/NodeDataModel.hpp @@ -66,6 +66,7 @@ public: virtual bool isDeletable() { return true; } + virtual void updateState() {} public: diff --git a/src/libRender/RadiumNBR/Gui/NodeEditor/src/FlowScene.cpp b/src/libRender/RadiumNBR/Gui/NodeEditor/src/FlowScene.cpp index a1c83883d0384960f1943c2b81ad5ed1be590d98..d5243236f2fc8c83a63477a9d908f0f964ca2f81 100644 --- a/src/libRender/RadiumNBR/Gui/NodeEditor/src/FlowScene.cpp +++ b/src/libRender/RadiumNBR/Gui/NodeEditor/src/FlowScene.cpp @@ -179,6 +179,37 @@ restoreConnection(QJsonObject const &connectionJson) return connection; } +void +FlowScene:: +importConnection(const QString& fromNodeId, + int fromNodePort, + const QString& toNodeId, + int toNodePort) +{ + QUuid nodeInId = QUuid(toNodeId); + QUuid nodeOutId = QUuid(fromNodeId); + auto nodeIn = _nodes[nodeInId].get(); + auto nodeOut = _nodes[nodeOutId].get(); + + auto connection = + std::make_shared<Connection>( *nodeIn, + toNodePort, + *nodeOut, + fromNodePort, + TypeConverter{} ); + + auto cgo = detail::make_unique<ConnectionGraphicsObject>(*this, *connection); + + nodeIn->nodeState().setConnection(PortType::In, toNodePort, *connection); + nodeOut->nodeState().setConnection(PortType::Out, fromNodePort, *connection); + + nodeIn->nodeDataModel()->updateState(); + + // after this function connection points are set to node port + connection->setGraphicsObject(std::move(cgo)); + + _connections[connection->id()] = connection; +} void FlowScene:: @@ -197,23 +228,39 @@ Node& FlowScene:: createNode(std::unique_ptr<NodeDataModel> && dataModel) { - auto node = detail::make_unique<Node>(std::move(dataModel)); - auto ngo = detail::make_unique<NodeGraphicsObject>(*this, *node); + auto node = detail::make_unique<Node>(std::move(dataModel)); + auto ngo = detail::make_unique<NodeGraphicsObject>(*this, *node); - // generates the uuid of the node (delegated to nodeDataModel implementation) - node->_uid = QUuid(node->nodeDataModel()->uuid()); - std::cout << "Generating an uuid for newly created node : " << node->_uid.toString().toStdString() << std::endl; + node->setGraphicsObject(std::move(ngo)); + // generates the uuid of the node (delegated to nodeDataModel implementation) + node->_uid = QUuid(node->nodeDataModel()->uuid()); + + auto nodePtr = node.get(); + _nodes[node->id()] = std::move(node); + + nodeCreated(*nodePtr); + return *nodePtr; +} + +Node& +FlowScene:: +importNode(std::unique_ptr<NodeDataModel> && dataModel) +{ + auto node = detail::make_unique<Node>(std::move(dataModel)); + auto ngo = detail::make_unique<NodeGraphicsObject>(*this, *node); node->setGraphicsObject(std::move(ngo)); + node->import(); + auto nodePtr = node.get(); _nodes[node->id()] = std::move(node); + nodePlaced(*nodePtr); nodeCreated(*nodePtr); return *nodePtr; } -// TODO MTHS -- Add a method that takes a datamodel and only create the node. Node& FlowScene:: restoreNode(QJsonObject const& nodeJson) diff --git a/src/libRender/RadiumNBR/Gui/NodeEditor/src/Node.cpp b/src/libRender/RadiumNBR/Gui/NodeEditor/src/Node.cpp index 7a859f3249b2d5830e00246c2b14bc32445946a5..6739d8602f56d9dcec469fb527344d57375f66f1 100644 --- a/src/libRender/RadiumNBR/Gui/NodeEditor/src/Node.cpp +++ b/src/libRender/RadiumNBR/Gui/NodeEditor/src/Node.cpp @@ -72,6 +72,18 @@ save() const } +void +Node:: +import() +{ + QJsonObject json = _nodeDataModel->save(); + _uid = QUuid(_nodeDataModel->uuid()); + QJsonObject positionJson = json["position"].toObject(); + QPointF point(positionJson["x"].toDouble(), + positionJson["y"].toDouble()); + _nodeGraphicsObject->setPos(point); +} + void Node:: restore(QJsonObject const& json) diff --git a/src/libRender/RadiumNBR/Gui/NodeGraphControllerGui.cpp b/src/libRender/RadiumNBR/Gui/NodeGraphControllerGui.cpp index 3f10f8acc49b61dfe77617b51ed6f8b9a6f49da9..ac51bd3c274fe12725fd2d53da454fd755921964 100644 --- a/src/libRender/RadiumNBR/Gui/NodeGraphControllerGui.cpp +++ b/src/libRender/RadiumNBR/Gui/NodeGraphControllerGui.cpp @@ -24,15 +24,11 @@ buildNodeGraphControllerGui( NodeBasedRenderer* renderer, nodeEditor->setGraph( renderer->getRenderGraph() ); - // TODO: find a way to refresh the main window when a widget gets updated instead of - // when the mouse moves + // TODO: find a way to refresh the main window when a widget gets updated instead of relying on nodeHoverLeft event - /* - nodeEditor->connections.push_back( - QObject::connect( nodeEditor, &RenderGraphEditorView::needUpdate, appUpdateCallback ) ); - */ QObject::connect( nodeEditor, &RenderGraphEditorView::needUpdate, appUpdateCallback ); + // TODO : change this to use the loadFromJson method on the graph auto loadGraph = [nodeEditor, renderer, appUpdateCallback]() { QString fileName = QFileDialog::getOpenFileName( nullptr, "Open Flow Scene", QDir::homePath(), "Flow Scene Files (*.flow)" ); @@ -58,11 +54,10 @@ buildNodeGraphControllerGui( NodeBasedRenderer* renderer, } }; - auto saveGraphToFile = []( const std::string& filename, FlowScene* scene ) { + auto saveGraphToFile = []( const std::string& filename, RenderGraph* graph ) { if ( !filename.empty() && QFileInfo::exists( filename.c_str() ) ) { - QFile file( filename.c_str() ); - if ( file.open( QIODevice::WriteOnly ) ) { file.write( scene->saveToMemory() ); } + graph->saveToJson( filename ); return filename; } else @@ -73,19 +68,18 @@ buildNodeGraphControllerGui( NodeBasedRenderer* renderer, { if ( !newFileName.endsWith( "flow", Qt::CaseInsensitive ) ) newFileName += ".flow"; - QFile file( newFileName ); - if ( file.open( QIODevice::WriteOnly ) ) { file.write( scene->saveToMemory() ); } + graph->saveToJson( newFileName.toStdString() ); } return newFileName.toStdString(); } }; - auto saveGraph = [nodeEditor, renderer, saveGraphToFile]() { - saveGraphToFile( renderer->getJsonFilePath(), nodeEditor->scene ); + auto saveGraph = [renderer, saveGraphToFile]() { + saveGraphToFile( renderer->getJsonFilePath(), renderer->getRenderGraph() ); }; auto saveGraphAs = [nodeEditor, renderer, saveGraphToFile]() { - auto filename = saveGraphToFile( "", nodeEditor->scene ); + auto filename = saveGraphToFile( "", renderer->getRenderGraph() ); renderer->setJsonFilePath( filename ); nodeEditor->setWindowTitle( std::string( "RenderGraph Node Editor - " + renderer->getRendererName() + " - " + filename ) @@ -102,19 +96,7 @@ buildNodeGraphControllerGui( NodeBasedRenderer* renderer, renderer->setJsonFilePath( "" ); appUpdateCallback(); }; - /* - nodeEditor->connections.push_back( - QObject::connect( nodeEditor->openAction, &QAction::triggered, loadGraph ) ); - nodeEditor->connections.push_back( - QObject::connect( nodeEditor->saveAsAction, &QAction::triggered, saveGraphAs ) ); - - nodeEditor->connections.push_back( - QObject::connect( nodeEditor->saveAction, &QAction::triggered, saveGraph ) ); - - nodeEditor->connections.push_back( - QObject::connect( nodeEditor->newAction, &QAction::triggered, newGraph ) ); - */ QObject::connect( nodeEditor->openAction, &QAction::triggered, loadGraph ); QObject::connect( nodeEditor->saveAsAction, &QAction::triggered, saveGraphAs ); QObject::connect( nodeEditor->saveAction, &QAction::triggered, saveGraph ); @@ -124,11 +106,12 @@ buildNodeGraphControllerGui( NodeBasedRenderer* renderer, if ( !nodeEditor->isVisible() ) { // Fill the flowscene in the editor with the current graph if any + // TODO change this detection method. Instead of the file name, set a flag on the graph that indicates it is available 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 + // (e.g. if adding a node programmatically, update the flowscene if ( nodeEditor->scene->getSceneName().compare( renderer->getJsonFilePath().c_str() ) != 0 ) { @@ -140,10 +123,9 @@ buildNodeGraphControllerGui( NodeBasedRenderer* renderer, std::cerr << "Loading nodegraph " << renderer->getJsonFilePath() << " in the editor." << std::endl; nodeEditor->disconnectAll(); + // nothing to do, the setGraph method of the editor will do that. nodeEditor->scene->clearScene(); - renderer->getRenderGraph()->clearNodes(); - QByteArray wholeFile = file.readAll(); - nodeEditor->scene->loadFromMemory( wholeFile ); + nodeEditor->editGraph(); nodeEditor->scene->setSceneName( renderer->getJsonFilePath().c_str() ); nodeEditor->setWindowTitle( std::string( "RenderGraph Node Editor - " + renderer->getRendererName() + @@ -155,7 +137,6 @@ buildNodeGraphControllerGui( NodeBasedRenderer* renderer, } } } - nodeEditor->resize( 800, 600 ); nodeEditor->show(); } diff --git a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.cpp b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.cpp index 52c5bd360e1ec65bfe8b083813088d31da472a64..a4573019ed50a9ae68d14b814f7ff3ade0367128 100644 --- a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.cpp +++ b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.cpp @@ -93,7 +93,7 @@ void QJsonEntryToNlohmannEntry( const QString& key, const QJsonValue& value, nlo } } -void NlohmannEntryQJsonEntry( const nlohmann::json& data, QJsonValue& value ) { +void NlohmannEntryToQJsonEntry( const nlohmann::json& data, QJsonValue& value ) { switch ( data.type() ) { case nlohmann::detail::value_t::boolean: { @@ -122,11 +122,10 @@ void NlohmannEntryQJsonEntry( const nlohmann::json& data, QJsonValue& value ) { } break; case nlohmann::detail::value_t::array: { - std::cerr << "Saving an array : \n\t" << data << std::endl; QJsonArray a; QJsonValue v; for( auto& x : data.items() ) { - NlohmannEntryQJsonEntry(x.value(), v); + NlohmannEntryToQJsonEntry( x.value(), v ); a.append( v ); } value = a; @@ -155,7 +154,6 @@ void QJsonObjectToNlohmannObject( const QJsonObject& p, nlohmann::json& data ) { void NlohmannObjectToQJsonObject(const nlohmann::json& data, QJsonObject& p) { for (const auto& [key, value] : data.items()) { - std::cout << key << " : " << value << "\n"; if ( value.is_object() ) { QJsonObject o; NlohmannObjectToQJsonObject( data[key], o); @@ -163,7 +161,7 @@ void NlohmannObjectToQJsonObject(const nlohmann::json& data, QJsonObject& p) { } else { QJsonValue v; - NlohmannEntryQJsonEntry(value, v); + NlohmannEntryToQJsonEntry( value, v ); p.insert(key.c_str(), v); } } diff --git a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.hpp b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.hpp index 2cf10da0ee14cc4a2b0a228b84226ae51418bea6..8eb83f20a2c67dac72fb0847491f97c7d8dd6d62 100644 --- a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.hpp +++ b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/NodeAdapterModel.hpp @@ -36,8 +36,17 @@ class NodeAdapterModel : public QtNodes::NodeDataModel m_renderGraph->m_recompile = true; } + void adapt(T* n) { + m_node = n; + m_inputsConnected.resize( m_node->getInputs().size() ); + m_widget = NodeDataModelTools::getWidget( m_node ); + NodeDataModelTools::updateWidget( m_node, m_widget ); + checkConnections(); + } + public: explicit NodeAdapterModel( RenderGraph* renderGraph ) : m_renderGraph( renderGraph ) { init(); } + explicit NodeAdapterModel( RenderGraph* renderGraph, T* n ) : m_renderGraph( renderGraph ) { adapt(n); } NodeAdapterModel() = delete; NodeAdapterModel( const NodeAdapterModel& ) = delete; NodeAdapterModel( NodeAdapterModel&& ) = default; @@ -58,6 +67,17 @@ class NodeAdapterModel : public QtNodes::NodeDataModel bool isDeletable() override { return m_node->isDeletable(); } + void updateState() override { + int i = 0; + for( const auto& in : m_node->getInputs() ) { + if( in->isLinked() ) { + m_inputsConnected[i] = true; + } + i++; + } + checkConnections(); + } + private: QtNodes::NodeDataType IOToDataType( size_t hashType, const std::string& ioName ) const { return QtNodes::NodeDataType{ std::to_string( hashType ).c_str(), ioName.c_str() }; diff --git a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/RenderGraphEditorView.cpp b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/RenderGraphEditorView.cpp index 48cdc9dedb539b8d45751df0342ba9b1dcac818c..26b17a316a744e8078a8e60889229e3fbb8981d3 100644 --- a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/RenderGraphEditorView.cpp +++ b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/RenderGraphEditorView.cpp @@ -111,28 +111,97 @@ void RenderGraphEditorView::connectAll() { } ) ); } + + void RenderGraphEditorView::setGraph( RenderGraph* rg) { currentGraph = rg; - auto editorRegistry = NodeGraphQtEditor::initializeNodeRegistry( currentGraph ); - scene->setRegistry( editorRegistry ); + // Replace this by a transformation of the currentGraph NodeSet (how to access ??) instead of a hard building of the registry + m_editorRegistry = NodeGraphQtEditor::initializeNodeRegistry( currentGraph ); + scene->setRegistry( m_editorRegistry ); + + } -#if 0 -// TODO : understand why this is problematic with gcc (and not with clang) -// Moved here from NodeAdapterModel.cpp -template <> -void NodeAdapterModel<DisplaySinkNode>::init() { - m_node = m_renderGraph->getDisplayNode(); - m_inputsConnected.resize( m_node->getInputs().size() ); - checkConnections(); +void RenderGraphEditorView::editGraph() { + // TODO, check if pointer are valid ? They have to ... + const auto& nodes = *(currentGraph->getNodes()); + // inserting nodes + for(const auto& n : nodes) { + scene->importNode( NodeGraphQtEditor::getAdaptedNode( n.get() ) ); + + } + // inserting connections + for(const auto& n : nodes) { + int numPort=0; + for( const auto & input : n->getInputs() ) { + if( input->isLinked() ) { + auto portOut = input->getLink(); + auto nodeOut = portOut->getNode(); + int outPortIndex = 0; + for( const auto& p : nodeOut->getOutputs() ) { + if ( p.get() == portOut ) { + break; + } + outPortIndex++; + } + scene->importConnection( nodeOut->getUuid().c_str(), outPortIndex, + n->getUuid().c_str(), numPort); + } + numPort++; + } + } } -template <> -void NodeAdapterModel<DisplaySinkNode>::destroy() {} -#endif namespace NodeGraphQtEditor { +/** NodeDataModelBuilder to convert an existing graph to its editor representation */ + +using DataModelAdapter = std::function<std::unique_ptr<QtNodes::NodeDataModel>(Node*)>; + +template <typename T> +class NodeDataModelAdapter +{ + public: + explicit NodeDataModelAdapter( RenderGraph* renderGraph ) : m_renderGraph( renderGraph ) {} + + std::unique_ptr<QtNodes::NodeDataModel> operator()(Node* n) { + return std::make_unique<NodeAdapterModel<T>>( m_renderGraph, static_cast<T*>(n) ); + } + + private: + RenderGraph* m_renderGraph; +}; + +using DataModelAdapters = std::unordered_map<std::string, DataModelAdapter>; +DataModelAdapters dataModelAdapters; + +void registerNodeModelAdapterInternal( std::string nodeType, + DataModelAdapter adapter) { + if ( dataModelAdapters.find( nodeType ) == dataModelAdapters.end() ) + { dataModelAdapters[nodeType] = std::move( adapter ); } + else + { + std::cerr << "registerNodeModelCreatorInternal: trying to add an already existing node adapter for type " + << nodeType << "." << std::endl; + } +} + +template <typename T> +void registerNodeModelAdapter( DataModelAdapter nodeAdapter ) { + registerNodeModelAdapterInternal( T::getTypename(), std::move( nodeAdapter ) ); +} + + +std::unique_ptr<QtNodes::NodeDataModel> getAdaptedNode( Node* n ) { + auto it = dataModelAdapters.find( n->getTypeName() ); + if ( it != dataModelAdapters.end() ) { + return it->second(n); + } + return nullptr; +} + +/** Editor registry associated to the editor so that it ca create a node */ template <typename T> class NodeCreator { @@ -148,8 +217,64 @@ class NodeCreator }; using namespace QtNodes; + +template<typename T> +void addNodeTypeToEditor( RenderGraph* renderGraph, + std::shared_ptr<DataModelRegistry>& creators, + /*DataModelAdapters& adapters, */ + std::string category ) { + + creators->registerModel<NodeAdapterModel<T>>( + NodeCreator<NodeAdapterModel<T>>( renderGraph ), "Data" ); + + registerNodeModelAdapter<T>( NodeDataModelAdapter<T>(renderGraph) ); +} + + std::shared_ptr<DataModelRegistry> initializeNodeRegistry( RenderGraph* renderGraph ) { auto ret = std::make_shared<DataModelRegistry>(); +#if 1 + addNodeTypeToEditor<DataNode<NodeTypeRenderObject>>(renderGraph, ret, "Data"); + addNodeTypeToEditor<DataNode<NodeTypeLight>>(renderGraph, ret, "Data"); + addNodeTypeToEditor<DataNode<NodeTypeCamera>>(renderGraph, ret, "Data"); + + addNodeTypeToEditor<DisplaySinkNode>(renderGraph, ret, "Sinks"); + + addNodeTypeToEditor<FilterROByTypeNode>(renderGraph, ret, "Filters"); + addNodeTypeToEditor<FilterROByNameNode>(renderGraph, ret, "Filters"); + + addNodeTypeToEditor<ClearColorNode>(renderGraph, ret, "RenderPasses"); + addNodeTypeToEditor<ZGeomPrepassNode>(renderGraph, ret, "RenderPasses"); + addNodeTypeToEditor<AccessibilityBufferNode>(renderGraph, ret, "RenderPasses"); + addNodeTypeToEditor<EnvLightNode>(renderGraph, ret, "RenderPasses"); + addNodeTypeToEditor<LocalLightNode>(renderGraph, ret, "RenderPasses"); + addNodeTypeToEditor<EmissivityNode>(renderGraph, ret, "RenderPasses"); + addNodeTypeToEditor<TransparencyNode>(renderGraph, ret, "RenderPasses"); + addNodeTypeToEditor<VolumeNode>(renderGraph, ret, "RenderPasses"); + addNodeTypeToEditor<VolumeVizualisationNode>(renderGraph, ret, "RenderPasses"); + addNodeTypeToEditor<UINode>(renderGraph, ret, "RenderPasses"); + addNodeTypeToEditor<WireframeNode>(renderGraph, ret, "RenderPasses"); + addNodeTypeToEditor<SimpleNode>(renderGraph, ret, "RenderPasses"); + + addNodeTypeToEditor<ColorSourceNode>(renderGraph, ret, "Sources"); + addNodeTypeToEditor<BooleanValueSource>(renderGraph, ret, "Sources"); + addNodeTypeToEditor<ScalarValueSource>(renderGraph, ret, "Sources"); + addNodeTypeToEditor<EnvMapTextureSource>(renderGraph, ret, "Sources"); + addNodeTypeToEditor<ColorTextureNode>(renderGraph, ret, "Sources"); + addNodeTypeToEditor<DepthTextureNode>(renderGraph, ret, "Sources"); + + addNodeTypeToEditor<DifferenceNode>(renderGraph, ret, "Compositing"); + addNodeTypeToEditor<SumNode>(renderGraph, ret, "Compositing"); + addNodeTypeToEditor<MultiplyNode>(renderGraph, ret, "Compositing"); + addNodeTypeToEditor<OneMinusNode>(renderGraph, ret, "Compositing"); + addNodeTypeToEditor<MaxNode>(renderGraph, ret, "Compositing"); + addNodeTypeToEditor<MinNode>(renderGraph, ret, "Compositing"); + addNodeTypeToEditor<MoreThanThresholdNode>(renderGraph, ret, "Compositing"); + addNodeTypeToEditor<LessThanThresholdNode>(renderGraph, ret, "Compositing"); + + addNodeTypeToEditor<FXAANode>(renderGraph, ret, "Anti Aliasing"); + +#else ret->registerModel<NodeAdapterModel<DataNode<NodeTypeRenderObject>>>( NodeCreator<NodeAdapterModel<DataNode<NodeTypeRenderObject>>>( renderGraph ), "Data" ); ret->registerModel<NodeAdapterModel<DataNode<NodeTypeLight>>>( @@ -223,7 +348,7 @@ std::shared_ptr<DataModelRegistry> initializeNodeRegistry( RenderGraph* renderGr ret->registerModel<NodeAdapterModel<FXAANode>>( NodeCreator<NodeAdapterModel<FXAANode>>( renderGraph ), "Anti Aliasing" ); - +#endif return ret; } } // namespace NodeGraphQtEditor diff --git a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/RenderGraphEditorView.hpp b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/RenderGraphEditorView.hpp index 4f859017d370dc701db011328e10fb38c73ff38a..7c4b28ee4edd9ca598ed099aa1ef5dbbe8914af3 100644 --- a/src/libRender/RadiumNBR/Gui/RenderGraphEditor/RenderGraphEditorView.hpp +++ b/src/libRender/RadiumNBR/Gui/RenderGraphEditor/RenderGraphEditorView.hpp @@ -14,9 +14,11 @@ class NodeBasedRenderer; // TODO, why is this class outside of any namespace ? class RenderGraph; +class Node; namespace NodeGraphQtEditor { std::shared_ptr<QtNodes::DataModelRegistry> initializeNodeRegistry( RenderGraph* renderGraph ); +std::unique_ptr<QtNodes::NodeDataModel> getAdaptedNode( Node* n ); } class NodeBasedRenderer_LIBRARY_API RenderGraphEditorView : public QWidget @@ -30,6 +32,8 @@ class NodeBasedRenderer_LIBRARY_API RenderGraphEditorView : public QWidget void setGraph( RenderGraph* rg); + void editGraph(); + public slots: bool eventFilter( QObject* object, QEvent* event ) { if ( event->type() == QEvent::MouseMove || event->type() == QEvent::KeyPress ) @@ -57,4 +61,6 @@ class NodeBasedRenderer_LIBRARY_API RenderGraphEditorView : public QWidget private: RenderGraph* currentGraph{ nullptr }; + + std::shared_ptr<QtNodes::DataModelRegistry> m_editorRegistry; }; diff --git a/src/libRender/RadiumNBR/NodeGraph/Node.hpp b/src/libRender/RadiumNBR/NodeGraph/Node.hpp index 2dfe18d787ce63fc5f8380d81cec7c9fd7287aa7..4cd36160d53005381bc2f25709f6f27e54d6f51e 100644 --- a/src/libRender/RadiumNBR/NodeGraph/Node.hpp +++ b/src/libRender/RadiumNBR/NodeGraph/Node.hpp @@ -243,4 +243,9 @@ class NodeBasedRenderer_LIBRARY_API Node static bool s_uuidGeneratorInitialized; static uuids::uuid_random_generator* s_uidGenerator; static void createUuidGenerator(); + + public: + static const std::string getTypename() { + return "Node"; + } }; diff --git a/src/libRender/RadiumNBR/NodeGraph/NodeFactory.hpp b/src/libRender/RadiumNBR/NodeGraph/NodeFactory.hpp index 53583f1abb691d2e89f220db5e7a29ddd01f0246..14be5f39eba88608f18463437e1aad82874b9534 100644 --- a/src/libRender/RadiumNBR/NodeGraph/NodeFactory.hpp +++ b/src/libRender/RadiumNBR/NodeGraph/NodeFactory.hpp @@ -6,12 +6,14 @@ #include <iostream> #include <unordered_map> +#include <any> + namespace NodeFactory { NodeBasedRenderer_LIBRARY_API Node* createNode( std::string& nodeType, const nlohmann::json& data ); NodeBasedRenderer_LIBRARY_API void registerNodeInternal( std::string nodeType, - std::function<Node*( const nlohmann::json& data )> nodeCreator ); + std::function<Node*( const nlohmann::json& data )> nodeCreator); template <typename T> void registerNode( std::function<Node*( const nlohmann::json& data )> nodeCreator ) { diff --git a/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp b/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp index 84706e514102db668e233e9e9f5241b7c9961034..1f143978524de04f9107f93ee6f9d5e2473a9909 100644 --- a/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp +++ b/src/libRender/RadiumNBR/NodeGraph/RenderGraph.cpp @@ -212,6 +212,7 @@ void RenderGraph::loadFromJson( const std::string& jsonFilePath ) { } void RenderGraph::saveToJson( const std::string& jsonFilePath ) { + std::cout << "RenderGraph::saveToJson : saving graph to " << jsonFilePath << "\n"; nlohmann::json nodes = nlohmann::json::array(); nlohmann::json connections = nlohmann::json::array(); for(const auto&n : m_nodes) { diff --git a/src/libRender/RadiumNBR/Renderer/NodeGraphController.cpp b/src/libRender/RadiumNBR/Renderer/NodeGraphController.cpp index fb9a4e2a5c6dd47ea32028fcf711daba440c3683..6cabb08f0ef46a051b47015d6de592fcd4b0d38f 100644 --- a/src/libRender/RadiumNBR/Renderer/NodeGraphController.cpp +++ b/src/libRender/RadiumNBR/Renderer/NodeGraphController.cpp @@ -40,128 +40,16 @@ void NodeGraphController::configure( RadiumNBR::NodeBasedRenderer* renderer, int LOG( Ra::Core::Utils::logERROR ) << "Unable to find resources for MultiPassRenderer!"; return; } - auto renderGraph = renderer->getRenderGraph(); auto resourcesPath{ *resourcesCheck }; auto shaderManager = Ra::Engine::RadiumEngine::getInstance()->getShaderProgramManager(); + //! [Caching some helpers and data from the Engine and the renderer] + //! [Access to the rendering node graph and parameterize it] + auto renderGraph = renderer->getRenderGraph(); renderGraph->setResourcesDir( resourcesPath ); renderGraph->setShaderProgramManager( shaderManager ); - //! [Caching some helpers and data from the Engine and the renderer] - - // Build render graph - - // renderer->loadFromJson(resourcesPath + "RenderGraphs/fullfeaturerenderer.flow"); - - /*Ra::Engine::Data::TextureParameters texParams; - texParams.width = w; - texParams.height = h; - texParams.target = gl45core::GL_TEXTURE_2D; - texParams.internalFormat = gl45core::GL_RGBA32F; - texParams.format = gl45core::GL_RGBA; - texParams.type = gl45core::GL_FLOAT; - texParams.minFilter = gl45core::GL_LINEAR; - texParams.magFilter = gl45core::GL_LINEAR; - texParams.name = "Linear RGB"; - - auto color = new TextureNode("swapchain", texParams); - renderGraph->addNode(color); - - auto clearColor = new ClearColorNode("clearColor"); - renderGraph->addNode(clearColor); - - auto clearColorColor = new SourceNode<NodeTypeColor>("clearColorColor", - NodeTypeColor::fromRGB(NodeTypeColor::Red().rgb())); renderGraph->addNode(clearColorColor); - - auto zGeomPrepass = new ZGeomPrepassNode("zGeomPrepass"); - renderGraph->addNode(zGeomPrepass); - - auto envLight = new EnvLightNode("envLight"); - renderGraph->addNode(envLight); - - auto AO = new AccessibilityBufferNode("aoPass"); - renderGraph->addNode(AO); - - auto emissivity = new EmissivityNode("emissivity"); - renderGraph->addNode(emissivity); - - auto localLight = new LocalLightNode("localLight"); - renderGraph->addNode(localLight); - - auto transparency = new TransparencyNode("transparency"); - renderGraph->addNode(transparency); - - auto filterROTransparent = new FilterNode<NodeTypeRenderObject>("filterTransparent", [] (const - NodeTypeRenderObject& ro) { return ro->isTransparent(); }); - renderGraph->addNode(filterROTransparent); - - auto volume = new VolumeNode("volume"); - renderGraph->addNode(volume); - - auto filterROVolume = new FilterNode<NodeTypeRenderObject>("filterVolume", [] (const - NodeTypeRenderObject& ro) { auto material = ro->getMaterial(); return material && - material->getMaterialAspect() == Ra::Engine::Data::Material::MaterialAspect::MAT_DENSITY; - }); - renderGraph->addNode(filterROVolume); - - auto wireframe = new WireframeNode("wireframe"); - renderGraph->addNode(wireframe); - - auto wireframeActivated = new SourceNode<bool>("wireframeActivated", false); - renderGraph->addNode(wireframeActivated); - - auto displayNode = new DisplaySinkNode("displayNode"); - renderGraph->addNode(displayNode); - - renderGraph->addLink(color, "to", clearColor, "inColor"); - renderGraph->addLink(clearColorColor, "to", clearColor, "inClearColor"); - renderGraph->addLink(wireframeActivated, "to", wireframe, "inActivate"); - renderGraph->addLink(clearColor, "outColor", emissivity, "inColor"); - renderGraph->addLink(renderGraph->getRenderObjectNode(), "outData", localLight, "inRO"); - renderGraph->addLink(renderGraph->getRenderObjectNode(), "outData", zGeomPrepass, "inRO"); - renderGraph->addLink(renderGraph->getRenderObjectNode(), "outData", emissivity, "inRO"); - renderGraph->addLink(renderGraph->getRenderObjectNode(), "outData", envLight, "inRO"); - renderGraph->addLink(renderGraph->getRenderObjectNode(), "outData", filterROTransparent, "in"); - renderGraph->addLink(renderGraph->getRenderObjectNode(), "outData", wireframe, "inRO"); - renderGraph->addLink(filterROTransparent, "out", transparency, "inRO"); - renderGraph->addLink(renderGraph->getRenderObjectNode(), "outData", filterROVolume, "in"); - renderGraph->addLink(filterROVolume, "out", volume, "inRO"); - renderGraph->addLink(renderGraph->getLightNode(), "outData", localLight, "inL"); - renderGraph->addLink(renderGraph->getLightNode(), "outData", transparency, "inL"); - renderGraph->addLink(renderGraph->getLightNode(), "outData", volume, "inL"); - renderGraph->addLink(renderGraph->getCameraNode(), "outData", localLight, "inC"); - renderGraph->addLink(renderGraph->getCameraNode(), "outData", zGeomPrepass, "inC"); - renderGraph->addLink(renderGraph->getCameraNode(), "outData", AO, "inC"); - renderGraph->addLink(renderGraph->getCameraNode(), "outData", emissivity, "inC"); - renderGraph->addLink(renderGraph->getCameraNode(), "outData", envLight, "inC"); - renderGraph->addLink(renderGraph->getCameraNode(), "outData", transparency, "inC"); - renderGraph->addLink(renderGraph->getCameraNode(), "outData", volume, "inC"); - renderGraph->addLink(renderGraph->getCameraNode(), "outData", wireframe, "inC"); - renderGraph->addLink(zGeomPrepass, "outDepth", localLight, "inDepth"); - renderGraph->addLink(zGeomPrepass, "outDepth", emissivity, "inDepth"); - renderGraph->addLink(zGeomPrepass, "outDepth", envLight, "inDepth"); - renderGraph->addLink(zGeomPrepass, "outDepth", transparency, "inDepth"); - renderGraph->addLink(zGeomPrepass, "outDepth", volume, "inDepth"); - renderGraph->addLink(zGeomPrepass, "outDepth", wireframe, "inDepth"); - renderGraph->addLink(zGeomPrepass, "outDepth", displayNode, "in4"); - renderGraph->addLink(zGeomPrepass, "outPosInWorld", AO, "inPos"); - renderGraph->addLink(zGeomPrepass, "outPosInWorld", displayNode, "in1"); - renderGraph->addLink(zGeomPrepass, "outNormalInWorld", AO, "inNormal"); - renderGraph->addLink(zGeomPrepass, "outNormalInWorld", displayNode, "in2"); - renderGraph->addLink(AO, "outAO", localLight, "inAO"); - renderGraph->addLink(AO, "outAO", emissivity, "inAO"); - renderGraph->addLink(AO, "outAO", envLight, "inAO"); - renderGraph->addLink(AO, "outAO", displayNode, "in3"); - renderGraph->addLink(emissivity, "outColor", envLight, "inColor"); - renderGraph->addLink(envLight, "outColor", localLight, "inColor"); - renderGraph->addLink(localLight, "outColor", transparency, "inColor"); - renderGraph->addLink(transparency, "outColor", volume, "inColor"); - renderGraph->addLink(volume, "outColor", wireframe, "inColor"); - renderGraph->addLink(wireframe, "outColor", displayNode, "in0"); - - renderGraph->init(); - - renderer->setDisplayNode(displayNode);*/ + //! [Access to the rendering node graph and parameterize it] } void NodeGraphController::update( const Ra::Engine::Data::ViewingParameters& ){