If several nodes are described in the clipboard and are supposed to
be connected with each other, reconnect them together, but do not
attempt to reconnect them to the graph they were copied from, even if
it is the current graph.
Add an "Import Scene" (Ctrl+Shift+I) option in the File menu
that allows to select an existing .mg file and import it in the
current graph.
The imported scene will automatically be placed below the lowest
existing node along the Y axis.
When creating a node with a "paste" operation, place the node
on the mouse's position in the graph instead of default position (0,0).
If the mouse is placed on an existing node, the pasted node will be
placed on the mouse's position plus an offset so that the pasted node
does not directly overlap with the existing node.
Attempt to paste the clipboard's content in the graph when Ctrl+V is
pressed. If the clipboard contains a valid node description, add the
corresponding node to the graph.
Otherwise, do nothing.
Duplicates used to be stored in a dictionary with an entry being
"parent node": "duplicated node". On occasions where a single
parent node was duplicated more than once, the latest duplicated
node erased the previous one(s), and these older ones were
"lost": after being created, there was no trace left of their
existence in the duplication operation. Undoing that duplication
operation was thus leaving these duplicated nodes out and not
removing them.
Duplicated nodes are now stored as "parent node": [list of
duplicated nodes] to keep track of all the created nodes,
effectively removing them upon an "undo".
Adding new properties and updating the call to previous ones.
Properties are now :
* label : getLabel
* fullLabel : getFullLabel
* fullLabelToNode : getFullLabelToNode
* fullLabelToGraph : getFullLabelToGraph
Same for the name.
Computing: lock the undo stack at the current index to avoid going back too far and potentially alter computing process.
Submitting: clear the undo stack.
Handle nodes move and auto-layout on Python side by using GraphLayout and MoveNodeCommand.
* Node QML component relies on underlying core.Node object's position
* MoveNodeCommand is called after a Node has been dragged
* partial/full auto-layout for specific graph operations (Duplication, Augmentation...) are now part of those operations
* serialized position in node data allows to properly restore nodes coordinates on undo/redo
* remove all layout/node moving code from QML
handle this low-level operation engine side
* fix ListAttribute children links duplication
* handle CompatibilityNode duplication
* move corresponding unit test in test_graph.py
* [ui] add DuplicateNodeCommand
Improve node serialization/deserialization to be able to recreate the exact same node in the graph when loading a meshroom project, even if the corresponding node's description has changed or does not exist anymore. This allows to recover already computed data on disk, without being impacted by changed uids. CompatibilityNode also provides an on-demand upgrade system to turn into a Node that meets the current node description (if possible).
* new abstract class BaseNode, base class for Node and CompatibiliyNode
* Node: serialize everything needed to spawn a CompatibilityNode with precomputed outputs: inputs, uids, parallelization settings, unresolved internal folders and outputs
* node_factory: handles node deserialization and compatibility issues to create either a Node or a CompatibilityNode
* add compatibility unit tests
* parent Nodes, Edges and Attributes to their respective models
* use weakrefs for those objects to avoid cyclic references
* add 'root' property on Attribute for parenting to List/GroupAttribute (parent still exists for Qt-style parenting)
* UI: update commands to match those changes
Use "hybrid" property to simplify naming of properties. No matter the backend used (qt or core), the property is always accessible via its name, without differently named getter or setter methods.