Merge branch 'dev_processGraph' of https://github.com/alicevision/meshroom into dev_processGraph

This commit is contained in:
Fabien Castan 2017-10-19 12:30:48 +02:00
commit 48e3e4cfa1
2 changed files with 35 additions and 18 deletions

View file

@ -12,6 +12,7 @@ import uuid
from collections import defaultdict from collections import defaultdict
from enum import Enum # available by default in python3. For python2: "pip install enum34" from enum import Enum # available by default in python3. For python2: "pip install enum34"
from pprint import pprint from pprint import pprint
import logging
from . import stats from . import stats
from . import desc from . import desc
@ -450,19 +451,18 @@ class Node(BaseObject):
self.status.returnCode = self._subprocess.returncode self.status.returnCode = self._subprocess.returncode
if self._subprocess.returncode != 0: if self._subprocess.returncode != 0:
logContent = ''
with open(self.logFile(), 'r') as logF: with open(self.logFile(), 'r') as logF:
logContent = ''.join(logF.readlines()) logContent = ''.join(logF.readlines())
self.upgradeStatusTo(Status.ERROR) self.upgradeStatusTo(Status.ERROR)
raise RuntimeError('Error on node "{}":\nLog:\n{}'.format(self.name, logContent)) raise RuntimeError('Error on node "{}":\nLog:\n{}'.format(self.name, logContent))
except: except Exception:
self.upgradeStatusTo(Status.ERROR) self.upgradeStatusTo(Status.ERROR)
raise raise
finally: finally:
elapsedTime = time.time() - startTime elapsedTime = time.time() - startTime
print(' - elapsed time:', elapsedTime) print(' - elapsed time:', elapsedTime)
self._subprocess = None self._subprocess = None
# ask and wait for the stats thread to terminate # ask and wait for the stats thread to stop
statThread.stopRequest() statThread.stopRequest()
statThread.join() statThread.join()
@ -594,20 +594,25 @@ class Graph(BaseObject):
return [edge for edge in self.edges if edge.src == attribute] return [edge for edge in self.edges if edge.src == attribute]
def removeNode(self, nodeName): def removeNode(self, nodeName):
"""
Remove the node identified by 'nodeName' from the graph
and return in and out edges removed by this operation in two dicts {dstAttr.fullName(), srcAttr.fullName()}
"""
node = self.node(nodeName) node = self.node(nodeName)
self._nodes.pop(nodeName) self._nodes.pop(nodeName)
edges = {} inEdges = {}
outEdges = {}
for attr in node._attributes: for attr in node._attributes:
for edge in self.outEdges(attr): for edge in self.outEdges(attr):
self.edges.remove(edge) self.edges.remove(edge)
edges[edge.dst.fullName()] = edge.src.fullName() outEdges[edge.dst.fullName()] = edge.src.fullName()
if attr in self.edges.keys(): if attr in self.edges.keys():
edge = self.edges.pop(attr) edge = self.edges.pop(attr)
edges[edge.dst.fullName()] = edge.src.fullName() inEdges[edge.dst.fullName()] = edge.src.fullName()
self.updateInternals() self.updateInternals()
return edges return inEdges, outEdges
@Slot(str, result=Node) @Slot(str, result=Node)
def addNewNode(self, nodeType, **kwargs): def addNewNode(self, nodeType, **kwargs):
@ -793,6 +798,14 @@ class Graph(BaseObject):
""" Request graph execution to be stopped """ """ Request graph execution to be stopped """
self.stopExecutionRequested.emit() self.stopExecutionRequested.emit()
def submittedNodes(self):
""" Return the list of submitted nodes inside this Graph """
return [node for node in self.nodes if node.isAlreadySubmitted()]
def clearSubmittedNodes(self):
""" Reset the status of already submitted nodes to Status.NONE """
[node.upgradeStatusTo(Status.NONE) for node in self.submittedNodes()]
@property @property
def nodes(self): def nodes(self):
return self._nodes return self._nodes
@ -848,8 +861,13 @@ def execute(graph, toNodes=None, force=False):
node.beginSequence() node.beginSequence()
for i, node in enumerate(nodes): for i, node in enumerate(nodes):
print('\n[{i}/{N}] {nodeName}'.format(i=i+1, N=len(nodes), nodeName=node.nodeType())) try:
node.process() print('\n[{i}/{N}] {nodeName}'.format(i=i + 1, N=len(nodes), nodeName=node.nodeType))
node.process()
except Exception as e:
logging.error("Error on node computation: {}".format(e))
graph.clearSubmittedNodes()
return
for node in nodes: for node in nodes:
node.endSequence() node.endSequence()

View file

@ -90,24 +90,23 @@ class AddNodeCommand(GraphCommand):
class RemoveNodeCommand(GraphCommand): class RemoveNodeCommand(GraphCommand):
def __init__(self, graph, node, parent=None): def __init__(self, graph, node, parent=None):
super(RemoveNodeCommand, self).__init__(graph, parent) super(RemoveNodeCommand, self).__init__(graph, parent)
self.nodeDesc = node.toDict() self.nodeDict = node.toDict()
self.nodeName = node.getName() self.nodeName = node.getName()
self.setText("Remove Node {}".format(self.nodeName)) self.setText("Remove Node {}".format(self.nodeName))
self.edges = {} self.outEdges = {}
def redoImpl(self): def redoImpl(self):
self.edges = self.graph.removeNode(self.nodeName) # only keep outEdges since inEdges are serialized in nodeDict
inEdges, self.outEdges = self.graph.removeNode(self.nodeName)
return True return True
def undoImpl(self): def undoImpl(self):
node = self.graph.addNode(Node(nodeDesc=self.nodeDesc["nodeType"], node = self.graph.addNode(Node(nodeDesc=self.nodeDict["nodeType"],
parent=self.graph, **self.nodeDesc["attributes"] parent=self.graph, **self.nodeDict["attributes"]
), self.nodeName) ), self.nodeName)
assert (node.getName() == self.nodeName) assert (node.getName() == self.nodeName)
# recreate edges deleted on node removal # recreate out edges deleted on node removal
# edges having this node as destination could be retrieved from node description for key, value in self.outEdges.items():
# but we're missing edges starting from this node
for key, value in self.edges.items():
dstNode, dstAttr = key.split(".") dstNode, dstAttr = key.split(".")
srcNode, srcAttr = value.split(".") srcNode, srcAttr = value.split(".")
self.graph.addEdge(self.graph.node(srcNode).attribute(srcAttr), self.graph.addEdge(self.graph.node(srcNode).attribute(srcAttr),