NodeEditor is conceived as a general-purpose Qt-based library aimed at graph-controlled data processing

Overview

Purpose

NodeEditor is conceived as a general-purpose Qt-based library aimed at graph-controlled data processing. Nodes represent algorithms with certain inputs and outputs. Connections transfer data from the output (source) of the first node to the input (sink) of the second one.

NodeEditor framework is a Visual Dataflow Programming tool. A library client defines models and registers them in the data model registry. Further work is driven by events taking place in DataModels and Nodes. The model computing is triggered upon arriving of any new input data. The computed result is propagated to the output connections. Each new connection fetches available data and propagates is further.

Each change in the source node is immediately propagated through all the connections updating the whole graph.

Platforms

  • OSX (Apple Clang - LLVM 3.6), Linux (x64, gcc-7.0, clang-7): Build Status
  • Windows (Win32, x64, msvc2017, MinGW 5.3): Build status

Dependencies

  • Qt >5.2
  • CMake 3.2
  • Catch2

Current state

  • Model-based nodes
  • Automatic data propagation
  • Datatype-aware connections
  • Embedded Qt widgets
  • One-output to many-input connections
  • JSON-based interface styles
  • Saving scenes to JSON files

Building

Linux

git clone [email protected]:paceholder/nodeeditor.git
cd nodeeditor
mkdir build
cd build
cmake ..
make -j && make install

Qt Creator

  1. Open CMakeLists.txt as project.
  2. If you don't have the Catch2 library installed, go to Build Settings, disable the checkbox BUILD_TESTING.
  3. Build -> Run CMake
  4. Build -> Build All
  5. Click the button Run

Roadmap

  1. Extend set of examples
  2. GUI: fix scrolling for scene view window scrolling
  3. Implement grouping nodes
  4. Split graph and GUI parts
  5. Build data propagation on top of the graph code

Citing

Dmitry Pinaev et al, Qt5 Node Editor, (2017), GitHub repository, https://github.com/paceholder/nodeeditor

BibTeX

@misc{Pinaev2017,
  author = {Dmitry Pinaev et al},
  title = {Qt5 Node Editor},
  year = {2017},
  publisher = {GitHub},
  journal = {GitHub repository},
  howpublished = {\url{https://github.com/paceholder/nodeeditor}},
  commit = {1d1757d09b03cea0e4921bc19659465fe6e65b9b}
}

Youtube video:

Youtube demonstration

Now with styles

Styles

Buy me a beer

Donate

Showcase

Chigraph

Chigraph is a programming language for beginners that is unique in that it is an intuitive flow graph:

chigraph screenshot

It features easy bindings to C/C++, package management, and a cool interface.

Spkgen particle engine editor

spkgen screenshot

Spkgen is an editor for the SPARK particles engine using a node-based interface to create particles effects for games.

Issues
  • Update to use modelview philosophy

    Update to use modelview philosophy

    For a while, @paceholder and I have been talking about having a separation between the node rendering and the logic of a data flow framework. This brings that.

    Use case: When you already have a data structure representing a flow scene, you can easily map an interface to it without keeping two data structures in sync.

    Abstract: This is inspired by Qt's model view infrastructure where there is a index for a particular item, a model (an abstract class) and a view (that takes in a pointer to a model).

    New/Totally refactored classes: NodeIndex: This is similar to a QModelIndex, but more specific to nodes. It holds nothing but an ID (QUuid), an internal pointer, and a pointer to the model.

    FlowSceneModel: This is the abstract model class. It defines a bunch of functions for reading and manipulating flow scenes.

    DataFlowScene: This roughly replaces FlowScene, and is actually a drop-in replacement. It subclasses from FlowScene and adds an implementation of FlowSceneModel that does exactly what this library used to do (data flow, with propagating data etc)

    ConnectionGraphicsObject: This class has kinda been merged with Connection, and it now does the functionality for both. Basically, it handles all the backend scene stuff for rendering connections.

    Connection: This is now entirely broken away from the rendering part of the library. It is now just part of the DataFlowScene.

    NodeGraphicsObject/Node: Same deal as connections

    ConnectionID: Just a way to identify connections in a map.

    Among plenty of other changes, but most users should just be able to change FlowScene to DataFlowScene and it'll work exactly as before.

    it's kinda a complex pull request. Sorry :/

    opened by russelltg 70
  • How To For Windows + QT Creator

    How To For Windows + QT Creator

    Hi Folks,

    Completely new to CPP, QT and this project. I'm wanting to build a visual scripting editor for go/python. I'm wondering if you have somewhere or someone that can point me in the direction of how to get setup for windows, qt creator.

    I currently have VS2017 installed with the Windows 10 SDK and C++ tooks as well as a manually installed CMake. I tried building using the command line tooling provided with qt creator but it can't find Clang2 (or whatever the name of the 3rd undocumented dependency is).

    Thanks in advance!

    opened by jaitaiwan 24
  • How do you install this?

    How do you install this?

    I know this is probably a stupid question to those who know what they are doing....

    How do I actually install and use this library. I've downloaded it and ran CMAKE but it gives me an error about not knowing where Qt is. When I give it the directory it still complains about a missing cmake file. Is there an example of this file or should it already be in one of the sub directories.

    Should the Qt Directory be the root of Qt or the root of the specific version that I want to use (inside the Qt dir)?

    Sorry for the dumb issue but we all start somewhere... :)

    opened by crener 18
  • Add ConnectionPolicy to NodeDataModel

    Add ConnectionPolicy to NodeDataModel

    Currently, it's hardcoded that input connections can have 1 connection and input can have as many as they want. This changes this, (keeping that as the default) but adds a nodeConnectionPolicy virtual function to NodeDataModel so NodeDataModel instances can choose that on a per-dock basis.

    I might have missed a few places that need to use this refactor.

    opened by russelltg 15
  • moc: Cannot open options file specified with @

    moc: Cannot open options file specified with @

    Hi all I am trying to build the library and examples under Qt Designer 4.5.1 against Qt 5.10.0 MinGw32 Cmake is Cmake 3.11 for Windows installed in C:\Program Files\CMake\bin\cmake.exe cmake run fine but the compilation is aborted with this error:

    12:30:56: Running steps for project NodeEditor...
    12:30:56: Persisting CMake state...
    12:31:06: Starting: "C:\Program Files\CMake\bin\cmake.exe" --build . --target all
    Scanning dependencies of target nodes_autogen
    [  1%] Automatic MOC for target nodes
    [  1%] Built target nodes_autogen
    [  2%] Generating include/nodes/internal/moc_make_unique.cpp
    moc: Cannot open options file specified with @
    make[2]: *** [include/nodes/internal/moc_make_unique.cpp] Error 1
    make[1]: *** [CMakeFiles/nodes.dir/all] Error 2
    make: *** [all] Error 2
    12:31:08: The process "C:\Program Files\CMake\bin\cmake.exe" exited with code 2.
    Error while building/deploying project NodeEditor (kit: Desktop Qt 5.10.0 MinGW 32bit - Cmake)
    When executing step "CMake Build"
    

    source code is located in C:\nodeeditor\nodeeditor and the build directory is C:\nodeeditor\buildnodeeditor

    The mentioned error usually is caused when the source code or target directory contain spaces but it is not the case now (unless also the cmake.exe path plays a role here) Bye

    opened by Menion2k 12
  • Removed NodeDataModel::clone()

    Removed NodeDataModel::clone()

    Hi,

    this is the follow up of #135 .

    About this comment from @Quincunx271 :

    I thought about this a bit more, and I think it might be beneficial to use our own Factory type rather than std::function. The strongest benefit that I can see is that it makes it possible in the future for us to add things to this "factory", stuff that are static per NodeDataModel subclass. This is similar to the class model in Java, where there's a single Class object that represents the type of all objects of that class. Or in C++, it'd be a lot like static member functions of a type.

    I am not sure I understood your suggestion.

    For me DataModelRegistry is a Factory. What you probably mean is the Builder Design Pattern, am I right?

    From my point of view, a lambda or a function pointer are so easy to write for the user that creating a Factory/Builder just seems an overkill.

    About allowing the access to static methods: a strong candidate would be NodeDataModel::name(), since it is supposed to be unique and constant. Is there any other method that you believe should be static?

    Remember that a static can not be virtual, nor pure virtual. But there are other way to force the user to implement them ;)

    In the past I managed to solve the "static vs virtual" problem using the Curiously Recursive template Pattern.

    opened by facontidavide 11
  • Runtime validation and error reporting

    Runtime validation and error reporting

    Extension to the library to provide a way to handle internal node errors in a more visible way. Nodes now have a chance to implement a kind of self validation mechanism, and report to the scene if the operation they representing is not possible on the data they contain. (Example in the calculator sample, if the division node gets a 0 value on the divisor port, that now results in a validation error.) In case of an error, the reported error message if displayed on the invalid node. errormsg Additionally there's a minor modification to create an easy way to iterate through all the existing nodes in the scene.


    This change is Reviewable

    opened by LandonJerre 11
  • Diffenent colors for different NodeDataTypes

    Diffenent colors for different NodeDataTypes

    So a useful feature to me would be diffenent colors for different NodeDataTypes to make different types easily differentiated.

    This kind of goes against the styling you recently implemented, but there are a few ways around that.

    Approach 1

    Have a QColor member in NodeDataType and just use that for rendering. It might be nice to have different colors for hover, select etc or just they are made lighter for hover etc.

    Approach 2

    A style theme defines a bunch of possible colors that could be used for connections, based on the color scheme they are going for, then they are assigned to be different for different data types.

    Conclusion

    I personally like approach 2 better because it follows color schemes and doesn't need each NodeDataType to define all their own custom colors, it just works and it looks good but you can't like assign red to a specific data type (which isn't really a loss IMHO because that would break color scheming anyways).

    I'm willing to write the code for it :).

    --- Want to back this issue? **[Post a bounty on it!](https://www.bountysource.com/issues/39601225-diffenent-colors-for-different-nodedatatypes?utm_campaign=plugin&utm_content=tracker%2F34672389&utm_medium=issues&utm_source=github)** We accept bounties via [Bountysource](https://www.bountysource.com/?utm_campaign=plugin&utm_content=tracker%2F34672389&utm_medium=issues&utm_source=github). enhancement 
    opened by russelltg 11
  • Output duplication

    Output duplication

    From the examples, it seems that there cannot be two outbound edges coming from the same port of a node. Is this a hard limitation on the library or could it be easily lifted ? (Or I just couldn't manage to do it).

    Thanks !

    opened by jcelerier 11
  • Multiple windows build errors

    Multiple windows build errors

    Hi. I'm trying to compile nodes in VS 2015, but I'm getting dozens of compiler errors "error syntax ::" .

    I have no idea what is wrong as it seems correct. Any Idea what it may be?

    bug 
    opened by MigFerreira 11
  • Automatic insertion of typecast nodes

    Automatic insertion of typecast nodes

    Modification of the system to handle the concept of typecasting nodes, and insert them automatically when a connection is made between two node with different types that are convertible. (The idea comes from UE4's blueprint system.) Typecast nodes are regular nodes with exactly one input and output ports, with differing types. If a nodes fullfills these criterias, and registered with an extra true bool parameter like this ret->registerModel<IntegerToDecimalModel, true>();, the system will start to insert it automatically when a conversion is needed. This is a bigger chunk of code, especially the examples, so thorough reviewing is needed. example


    This change is Reviewable

    opened by LandonJerre 10
  • [v3alpha] An issue with the working of draft connection

    [v3alpha] An issue with the working of draft connection

    In ConnectionGraphicsObject on mouseMove event you transfer self to hovered node for reaction: ngo->reactToConnection(this); This connection is using in NodePainter::drawConnectionPoints for painting ports. And you reset this pointer at the end of this method. But sometimes mouseRelease event of ConnectionGraphicsObject and corresponding destroying of draft connection happens before NodePainter::drawConnectionPoints call. So sometimes NodePainter accesses the destroyed pointer.

    I think you need to let the scene set reaction connection to nodes and tracks for it destruction.

    opened by velorom 0
  • Unable to disable connection drugging from node

    Unable to disable connection drugging from node

    We are using nodeeditor for graph visualisation, but we need to disable editing of connections after creating them initially. Lock(true) method of ConnectionGraphicsObject method does not provide that functionality, and disabling mouse events on ConnectionGraphicsObject is fixing the connection drugging issue, but we are having some rendering issues on the connection object.

    Could you please let us know is it possible to achieve non modifiable connections via your native implementation?

    Thanks in advance.

    opened by RazmikKarapetyan 0
  • Change amount of ports after a widget is created

    Change amount of ports after a widget is created

    Hello guys, thank you for the great project! I've already figured out how to change the port datatype after a node widget is created. Now I would like to make the amount of ports customizeable on a new node widget. But just changing the way a registered model is behaving, doesn't seem to be enough so my widget always stays "portless" since I'm creating it with 0 ports and changing the amount of ports in the restore() method. Do you see any chance how I could accomplish this?

    Here's how I'm tyring to handle my model right now:

    QJsonObject QuestDBEffectModel::save() const
     {
        QJsonObject json;
        json["name"] = name();
    
        auto info = _widget->getPortInfo();
        QJsonObject ports;
    
        for (int x = 0; x < info.size(); ++x)
        {
            QJsonObject port;
            port["portName"] = info[x].first();
            port["portDataType"] = info[x].last();
            ports[QString::number(x)] = port;
        }
    
        json["ports"] = ports;
    
        return json;
    }
    
    void QuestDBEffectModel::restore(const QJsonObject &json)
    {
        _json = json;
    
        QJsonObject ports = _json["ports"].toObject();
        _data.resize(ports.keys().count());
    
        for (int x = 0; x < _data.size(); ++x)
        {
            auto pdt = ports[QString::number(x)].toObject()["portDataType"].toString();
            ProMeFeMethods::castNodeDataPtrFromString(_data[x], ports[QString::number(x+1)].toObject()["portDataType"].toString());
            _widget->addPort(
                        ports[QString::number(x)].toObject()["portName"].toString(),
                        ports[QString::number(x)].toObject()["portDataType"].toString());
        }
    }
    
    unsigned int QuestDBEffectModel::nPorts(QtNodes::PortType portType) const
    {
        return portType == PortType::In ? _data.size() : 0;
    }
    
    NodeDataType QuestDBEffectModel::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
    {
        return _data.at(portIndex).get()->type();
    }
    
    opened by oddcitizenape 0
  • Leave Qt version up to users

    Leave Qt version up to users

    Currently CMakeLists.txt tries to find Qt6 and eventually falls back to Qt5.13 in case 6 isn't available.

    # Find the QtWidgets library
    find_package(Qt6
      COMPONENTS
       Core
       Widgets
       Gui
       OpenGL
    )
    
    if (NOT Qt6_FOUND)
      find_package(Qt5 5.13
        COMPONENTS
         Core
         Widgets
         Gui
         OpenGL
      )
    endif()
    

    This is an issue on machines were both, Qt6 and 5, are installed. There is no way to force nodeeditor to link against Qt5 if Qt6 is also found on the system. Maybe it would be a good idea to first check if Qt6 or Qt5 has already been added as dependency?

    # Find the QtWidgets library
    macro(find_qt6)
      find_package(Qt6 COMPONENTS Core Widgets Gui OpenGL)
    endmacro()
    macro(find_qt5)
      find_package(Qt5 5.13 COMPONENTS  Core Widgets Gui OpenGL)
    endmacro()
    
    if(Qt6_FOUND)
      find_qt6()
    elseif(Qt5_FOUND)
      find_qt5()
    elseif(NOT Qt6_FOUND AND NOT Qt5_FOUND)
      find_qt6()
      if(NOT Qt6_FOUND)
        find_qt5()
      endif()
    endif()
    
    opened by higaski 0
  • When a node connects multiple child nodes, all child nodes will execute repeatedly

    When a node connects multiple child nodes, all child nodes will execute repeatedly

    Suppose I have a node A, and A have a out port connected to child nodes B1,B2,B3,B4.

    If I disconnect and reconnect A and B1 (or add a child node and connect to A), node A will triggered the onDataUpdated() event, then all child nodes who connect to A will all be executed, even I just reconnect A and B1, but B2,B3,B4 will all be executed too.

    If I restore from .flow file, B1 will execute one time, B2 will execute two times, B3 will execute 3 times, B4 will execute 4 times! Normally, B1~B4 will all execute just one time!

    opened by liupeiqiHN 0
Owner
Dmitry Pinaev
I am doing computational science & CFD at my primary job and various Qt-based stuff as hobby.
Dmitry Pinaev
This is a complet GUI between a Raspberry device with a Slave microcontroller to set camera data acquisition

#PYDOME Python Lib for Domes features control, this package allows users to build, evaluate and make tasks based on Raspberry OS Table of Contents Ins

null 1 Nov 2, 2021
Pure Data as a plugin, with a new GUI

PlugData Pure Data as a plugin, with a new GUI PlugData a plugin wrapper for PureData, featuring a new GUI made with JUCE. Currently not very stable!

Timothy Schoen 234 Jun 24, 2022
Library for writing text-based user interfaces

Termbox for RT-Thread 中文说明文档 This repository forks from nullgemm/termbox_next Getting started Termbox's interface only consists of 12 functions: tb_in

Meco Jianting Man 5 May 25, 2022
ImTui: Immediate Mode Text-based User Interface C++ Library

ImTui is an immediate mode text-based user interface library. Supports 256 ANSI colors and mouse/keyboard input.

Georgi Gerganov 1.9k Jun 24, 2022
Fishui - CutefishOS GUI library, based on Qt Quick.

FishUI FishUI is a GUI library based on QQC2 (Qt Quick Controls 2), every Cutefish application uses it. Features Light and Dark Mode Borderless window

CutefishOS 184 Jun 27, 2022
WebKitGTK adblock extension with Brave's Rust-based adblock engine for backend.

BlocKit WebKitGTK adblock extension with Brave's Rust-based adblock engine for backend. Features Network and cosmetic filtering Supports Adblock Plus

Samuel Dudík 45 Jun 17, 2022
[WIP] Demo of a minimal but functional Dawn-based WebGPU client and server

dawn client-server example The goal of this demo is to create a minimal but functional Dawn-based WebGPU client and server with the following traits:

Rasmus 15 Nov 20, 2021
Modern Window Sitter for X11 based Desktop Environments

Modern Window Sitter for X11 based Desktop Environments (Coming to Wayland, Windows and Mac soon-ish). But using with a terminal emulator is recommended.

Antony Jr 33 May 7, 2022
HoI4 Modding Tool That Does It All! Now with a QT based GUI, all your work wil be easier!

Kadaif - HoI4 Modding Tool Kadaif is a cross-platform tool meant to help you make mods for Hearts of Iron IV. With VSCode and all it's extensions, man

null 1 Dec 28, 2021
QDirStat - Qt-based directory statistics (KDirStat without any KDE - from the original KDirStat author)

QDirStat - Qt-based directory statistics (KDirStat without any KDE - from the original KDirStat author)

Stefan Hundhammer 1.1k Jun 23, 2022
My color picker in GTK, based very heavily on the MS Powertoys color picker

My color picker in GTK, based very heavily on the MS Powertoys color picker

contribuewwt 10 Apr 25, 2022
Latte is a dock based on plasma frameworks that provides an elegant and intuitive experience for your tasks and plasmoids.

Latte is a dock based on plasma frameworks that provides an elegant and intuitive experience for your tasks and plasmoids. It animates its contents by using parabolic zoom effect and trys to be there only when it is needed.

KDE GitHub Mirror 1.2k Jun 23, 2022
Window and GUI system based on Dear ImGui from OCornut

ImWindow Window and GUI system based on ImGui from OCornut. Include docking/floating window, multi window and multi render support. Platform Actually

Thibault Hennequin 681 Jun 20, 2022
Immediate mode 3D gizmo for scene editing and other controls based on Dear Imgui

ImGuizmo Latest stable tagged version is 1.83. Current master version is 1.84 WIP. What started with the gizmo is now a collection of dear imgui widge

Cedric Guillemet 2k Jun 27, 2022
Skia-based C++ UI framework

UI framework that uses Skia as a low-level drawing toolkit. It uses the newest features of the C++ Standard library (currently targetting C++17).

null 307 Jun 23, 2022
Elements C++ GUI library

Elements C++ GUI library Introduction Elements is a lightweight, fine-grained, resolution independent, modular GUI library. Elements is designed with

Cycfi Research 2.3k Jun 25, 2022
Simple and portable (but not inflexible) GUI library in C that uses the native GUI technologies of each platform it supports.

libui: a portable GUI library for C This README is being written. Status It has come to my attention that I have not been particularly clear about how

Pietro Gagliardi 10.3k Jun 19, 2022
Minimalistic C++/Python GUI library for OpenGL, GLES2/3, Metal, and WebAssembly/WebGL

NanoGUI NanoGUI is a minimalistic cross-platform widget library for OpenGL 3+, GLES 2/3, and Metal. It supports automatic layout generation, stateful

Mitsuba Physically Based Renderer 1k Jun 27, 2022
A single-header ANSI C immediate mode cross-platform GUI library

Nuklear This is a minimal-state, immediate-mode graphical user interface toolkit written in ANSI C and licensed under public domain. It was designed a

Immediate Mode UIs, Nuklear, etc. 5.7k Jun 20, 2022