Only perform uid check when we have both a serialized and a computed
UID.
If the node has not been serialized with a UID, it means that it does not
expect to match a specific value on deserialization.
Add a new serializer class to manage partial graph serialization logic,
ensuring to remove link expressions on attributes refering to nodes
that are not in the subset of nodes to serialize.
Move the serialization logic to dedicated serializer classes.
Implement both `GraphSerializer` and `TemplateGraphSerializer`
to cover for the existing serialization use-cases.
Move Graph.IO internal class to its own module, and rename it to `GraphIO`.
This avoid nested classes within the core Graph class, and starts decoupling
the management of graph's IO from the logic of the graph itself.
When creating a compatibility description for an unknown attribute, do not
consider a link expression as the default value for a File attribute.
This is breaking how the link expression solving system works, as it's resetting
the attribute to its default value after applying the link.
If that expression is kept as the default value, it can be re-evaluated several
times incorrectly.
Added a test case that was failing before that change to illustrate the issue.
Extract the logic of importing the content of a graph within a graph instance from
the graph loading logic.
Add `Graph.importGraphContent` and `Graph.importGraphContentFromFile`
methods.
Use the deserialization API to load the content in another temporary graph instance,
to handle the renaming of nodes using the Graph API, rather than manipulating
entries in a raw dictionnary.
* API
Instead of having a single `load` function that exposes in its API
some elements only applicable to initializing a graph from a templates,
split it into 2 distinct functions: `load` and `initFromTemplate`.
Apply those changes to users of the API (UI, CLI), and simplify Graph
wrapper classes to better align with those concepts.
* Deserialization
Reduce the cognitive complexity of the deserizalization process
by splitting it into more atomic functions, while maintaining the
current behavior.
Connecting the valueChanged signal to a lambda causes performance
issues with a large number of attributes when using the Pyside backend.
Connecting that signal to an intermediate Slot part of the Attribute class
improves performance dramatically.
Note: This has no comparable impact on the standalone backend.
With Qt6 the geometryChanged method was updated to be called as geometryChange and with that update QQuickItem was not getting internal updateShape to get invoked upon updates
In some cases, like when opening the most recent file from the command
line, switching the color palette or hot reloading, the intrinsics
might be parsed and ready to populate the intrinsics' `TableModel` while
the model itself is being instantiated.
To prevent crashes, we forbid operations on the `TableModel` until it has
been fully instantiated.
There is no need to read the QSettings again as the content of
`self._recentProjectFiles` reflects their content accurately and they
do not store any thumbnail-related information.
QSettings will now only be read once, upon Meshroom's start.
Instead of doing it directly within the `_getRecentProjectFiles` method,
add a function that attempts to retrieve a thumbnail corresponding to
an input project file path.
When the list of recent project files is updated, there is no attempt
to retrieve its thumbnail as the update is said to be "minimal".
This minimal update is justified by the lack of use for the thumbnails
in the Application part of Meshroom. Thumbnails are only useful when
displaying the Homepage, hence their retrieval during Meshroom's
initialization. There is only a need to update them once we want to
display the Homepage again.
The Homepage thus requests an update of the thumbnails before setting
its model. If there have been some updates to the list of recent project
files, the reading of the QSettings is performed again and thumbnails
are retrieved whenever it is possible. Otherwise, nothing happens to
prevent useless readings.
The property itself only accesses a list instead of reading the QSettings
every single time it is called.
It is set once during the application's launch with a full reading, and
is then updated without performing extra reading operations every time
a file is added to or removed from the list.
Propagate attribute value changes downstream using `valueChanged` signal
emission, instead of calling `_onAttributeChanged` directly.
This does not change the current core behavior, but it triggers the
property notification signal when in UI mode.
This makes changes happening upstream properly reflected in downstream nodes.
Pressing F or invoking GraphEditor.fit() now considers the selected nodes and fits/focusses on the overall selection if present, else fits/focusses all of available nodes