diff --git a/meshroom/core/graph.py b/meshroom/core/graph.py index 1a6b7dc6..566d60f7 100644 --- a/meshroom/core/graph.py +++ b/meshroom/core/graph.py @@ -1009,6 +1009,24 @@ class Graph(BaseObject): for node in self._nodes: node.updateStatisticsFromCache() + def updateNodesPerUid(self): + """ Update the duplicate nodes (sharing same uid) list of each node. """ + # First step is to construct a map uid/nodes + nodesPerUid = {} + for node in self.nodes: + uid = node._uids.get(0) + + # We try to add the node to the list corresponding to this uid + try: + nodesPerUid.get(uid).append(node) + # If it fails because the uid is not in the map, we add it + except AttributeError: + nodesPerUid.update({uid: [node]}) + + # Now, update each individual node + for node in self.nodes: + node.updateDuplicates(nodesPerUid) + def update(self): if not self._updateEnabled: # To do the update once for multiple changes @@ -1021,6 +1039,8 @@ class Graph(BaseObject): for node in self.nodes: node.dirty = False + self.updateNodesPerUid() + # Graph topology has changed if self.dirtyTopology: # update nodes topological data cache diff --git a/meshroom/core/node.py b/meshroom/core/node.py index 1f351184..543f5438 100644 --- a/meshroom/core/node.py +++ b/meshroom/core/node.py @@ -463,6 +463,7 @@ class BaseNode(BaseObject): self._attributes = DictModel(keyAttrName='name', parent=self) self.attributesPerUid = defaultdict(set) self._locked = False + self._duplicates = ListModel(parent=self) # list of nodes with the same uid self.globalStatusChanged.connect(self.updateLocked) @@ -865,6 +866,17 @@ class BaseNode(BaseObject): self.setLocked(False) + def updateDuplicates(self, nodesPerUid): + """ Update the list of duplicate nodes (sharing the same uid). """ + if not nodesPerUid: + self._duplicates.clear() + self.duplicatesChanged.emit() + return + + uid = self._uids.get(0) + self._duplicates.setObjectList([node for node in nodesPerUid.get(uid) if node != self]) + self.duplicatesChanged.emit() + name = Property(str, getName, constant=True) label = Property(str, getLabel, constant=True) nodeType = Property(str, nodeType.fget, constant=True) @@ -888,6 +900,8 @@ class BaseNode(BaseObject): isComputed = Property(bool, _isComputed, notify=globalStatusChanged) lockedChanged = Signal() locked = Property(bool, getLocked, setLocked, notify=lockedChanged) + duplicatesChanged = Signal() + duplicates = Property(Variant, lambda self: self._duplicates, notify=duplicatesChanged) class Node(BaseNode):