From 887844541c6b51bc8c3a8888426daa66df58dd99 Mon Sep 17 00:00:00 2001 From: Aurore LAFAURIE Date: Fri, 5 Jul 2024 15:28:10 +0200 Subject: [PATCH] Compute or Submit selected nodes --- meshroom/core/taskManager.py | 3 ++ meshroom/ui/graph.py | 12 +++--- meshroom/ui/qml/GraphEditor/GraphEditor.qml | 42 ++++++++++++++++++++- meshroom/ui/qml/main.qml | 18 ++++----- 4 files changed, 59 insertions(+), 16 deletions(-) diff --git a/meshroom/core/taskManager.py b/meshroom/core/taskManager.py index 89909959..e902c62b 100644 --- a/meshroom/core/taskManager.py +++ b/meshroom/core/taskManager.py @@ -201,6 +201,9 @@ class TaskManager(BaseObject): self.checkDuplicates(nodes, "COMPUTATION") # name of the context is important for QML nodes = [node for node in nodes if not self.contains(node)] # be sure to avoid non-real conflicts + nodes = list(set(nodes)) + nodes = sorted(nodes, key=lambda x: x.depth) + chunksInConflict = self.getAlreadySubmittedChunks(nodes) if chunksInConflict: diff --git a/meshroom/ui/graph.py b/meshroom/ui/graph.py index f84d8bb6..457308f6 100644 --- a/meshroom/ui/graph.py +++ b/meshroom/ui/graph.py @@ -495,9 +495,10 @@ class UIGraph(QObject): else: self._undoStack.unlock() + @Slot(QObjectListModel) @Slot(Node) - def execute(self, node=None): - nodes = [node] if node else None + def execute(self, nodes=None): + nodes = [nodes] if not isinstance(nodes, Iterable) and nodes else nodes self._taskManager.compute(self._graph, nodes) self.updateLockedUndoStack() # explicitly call the update while it is already computing @@ -532,8 +533,9 @@ class UIGraph(QObject): n.clearSubmittedChunks() self._taskManager.removeNode(n, displayList=True, processList=True) + @Slot(QObjectListModel) @Slot(Node) - def submit(self, node=None): + def submit(self, nodes=None): """ Submit the graph to the default Submitter. If a node is specified, submit this node and its uncomputed predecessors. Otherwise, submit the whole @@ -543,8 +545,8 @@ class UIGraph(QObject): """ self.save() # graph must be saved before being submitted self._undoStack.clear() # the undo stack must be cleared - node = [node] if node else None - self._taskManager.submit(self._graph, os.environ.get('MESHROOM_DEFAULT_SUBMITTER', ''), node, submitLabel=self.submitLabel) + nodes = [nodes] if not isinstance(nodes, Iterable) and nodes else nodes + self._taskManager.submit(self._graph, os.environ.get('MESHROOM_DEFAULT_SUBMITTER', ''), nodes, submitLabel=self.submitLabel) def updateGraphComputingStatus(self): # update graph computing status diff --git a/meshroom/ui/qml/GraphEditor/GraphEditor.qml b/meshroom/ui/qml/GraphEditor/GraphEditor.qml index cca1829d..63bdfb81 100755 --- a/meshroom/ui/qml/GraphEditor/GraphEditor.qml +++ b/meshroom/ui/qml/GraphEditor/GraphEditor.qml @@ -26,8 +26,8 @@ Item { signal workspaceClicked() signal nodeDoubleClicked(var mouse, var node) - signal computeRequest(var node) - signal submitRequest(var node) + signal computeRequest(var nodes) + signal submitRequest(var nodes) property int nbMeshroomScenes: 0 property int nbDraggedFiles: 0 @@ -455,6 +455,25 @@ Item { computeRequest(nodeMenu.currentNode) } } + MenuItem { + text: "Compute Selected Node(s)" + visible: uigraph.selectedNodes.count > 0 + height: visible ? implicitHeight : 0 + + enabled: { + var canCompute = false + for (var i = 0; i < uigraph.selectedNodes.count; ++i) { + if (uigraph.graph.canCompute(uigraph.selectedNodes.at(i)) && uigraph.graph.canSubmitOrCompute(uigraph.selectedNodes.at(i))%2 == 1){ + canCompute = true + } + } + return canCompute + } + + onTriggered: { + computeRequest(uigraph.selectedNodes) + } + } MenuItem { text: "Submit" enabled: nodeMenu.canComputeNode && nodeMenu.canSubmitOrCompute > 1 @@ -462,6 +481,25 @@ Item { height: visible ? implicitHeight : 0 onTriggered: submitRequest(nodeMenu.currentNode) } + MenuItem { + text: "Submit Selected Node(s)" + visible: uigraph.selectedNodes.count > 0 + height: visible ? implicitHeight : 0 + + enabled: { + var canSubmit = false + for (var i = 0; i < uigraph.selectedNodes.count; ++i) { + if (uigraph.graph.canCompute(uigraph.selectedNodes.at(i)) && uigraph.graph.canSubmitOrCompute(uigraph.selectedNodes.at(i)) > 1){ + canSubmit = true + } + } + return canSubmit + } + + onTriggered: { + submitRequest(uigraph.selectedNodes) + } + } MenuItem { text: "Stop Computation" enabled: nodeMenu.currentNode ? nodeMenu.currentNode.canBeStopped() : false diff --git a/meshroom/ui/qml/main.qml b/meshroom/ui/qml/main.qml index 9590bae3..263fa650 100644 --- a/meshroom/ui/qml/main.qml +++ b/meshroom/ui/qml/main.qml @@ -216,35 +216,35 @@ ApplicationWindow { && _reconstruction.graph.filepath : // graph is saved on disk false - function compute(node, force) { + function compute(nodes, force) { if (!force && warnIfUnsaved && !_reconstruction.graph.filepath) { - unsavedComputeDialog.currentNode = node; + unsavedComputeDialog.currentNode = nodes[0]; unsavedComputeDialog.open(); } else { try { - _reconstruction.execute(node) + _reconstruction.execute(nodes) } catch (error) { const data = ErrorHandler.analyseError(error) if (data.context === "COMPUTATION") - computeSubmitErrorDialog.openError(data.type, data.msg, node) + computeSubmitErrorDialog.openError(data.type, data.msg, nodes) } } } - function submit(node) { + function submit(nodes) { if (!canSubmit) { unsavedSubmitDialog.open() } else { try { - _reconstruction.submit(node) + _reconstruction.submit(nodes) } catch (error) { const data = ErrorHandler.analyseError(error) if (data.context === "SUBMITTING") - computeSubmitErrorDialog.openError(data.type, data.msg, node) + computeSubmitErrorDialog.openError(data.type, data.msg, nodes) } } } @@ -1245,11 +1245,11 @@ ApplicationWindow { } onComputeRequest: { _reconstruction.forceNodesStatusUpdate(); - computeManager.compute(node) + computeManager.compute(nodes) } onSubmitRequest: { _reconstruction.forceNodesStatusUpdate(); - computeManager.submit(node) + computeManager.submit(nodes) } onFilesDropped: { var filesByType = _reconstruction.getFilesByTypeFromDrop(drop.urls)