def __init__(self, nodeType, position=None, parent=None, **kwargs): """ Create a new Node instance based on the given node description. Any other keyword argument will be used to initialize this node's attributes. Args: nodeDesc (desc.Node): the node description for this node parent (BaseObject): this Node's parent **kwargs: attributes values """ super(BaseNode, self).__init__(parent) self._nodeType = nodeType self.nodeDesc = None # instantiate node description if nodeType is valid if nodeType in meshroom.core.nodesDesc: self.nodeDesc = meshroom.core.nodesDesc[nodeType]() self.packageName = self.packageVersion = "" self._internalFolder = "" self._name = None self.graph = None self.dirty = True # whether this node's outputs must be re-evaluated on next Graph update self._chunks = ListModel(parent=self) self._uids = dict() self._cmdVars = {} self._size = 0 self._position = position or Position() self._attributes = DictModel(keyAttrName='name', parent=self) self.attributesPerUid = defaultdict(set) self._alive = True # for QML side to know if the node can be used or is going to be deleted
def resetValue(self): self._value = ListModel(parent=self)
def __init__(self, node, attributeDesc, isOutput, root=None, parent=None): super(ListAttribute, self).__init__(node, attributeDesc, isOutput, root, parent) self._value = ListModel(parent=self)
class ListAttribute(Attribute): def __init__(self, node, attributeDesc, isOutput, root=None, parent=None): super(ListAttribute, self).__init__(node, attributeDesc, isOutput, root, parent) self._value = ListModel(parent=self) def __len__(self): return len(self._value) def getBaseType(self): return self.attributeDesc.elementDesc.__class__.__name__ def at(self, idx): """ Returns child attribute at index 'idx' """ # implement 'at' rather than '__getitem__' # since the later is called spuriously when object is used in QML return self._value.at(idx) def index(self, item): return self._value.indexOf(item) def resetValue(self): self._value = ListModel(parent=self) def _set_value(self, value): if self.node.graph: self.remove(0, len(self)) # Link to another attribute if isinstance(value, ListAttribute) or Attribute.isLinkExpression(value): self._value = value # New value else: newValue = self.desc.validateValue(value) self.extend(newValue) self.requestGraphUpdate() @raiseIfLink def append(self, value): self.extend([value]) @raiseIfLink def insert(self, index, value): values = value if isinstance(value, list) else [value] attrs = [ attributeFactory(self.attributeDesc.elementDesc, v, self.isOutput, self.node, self) for v in values ] self._value.insert(index, attrs) self.valueChanged.emit() self._applyExpr() self.requestGraphUpdate() @raiseIfLink def extend(self, values): self.insert(len(self._value), values) @raiseIfLink def remove(self, index, count=1): if self.node.graph: from meshroom.core.graph import GraphModification with GraphModification(self.node.graph): # remove potential links for i in range(index, index + count): attr = self._value.at(i) if attr.isLink: # delete edge if the attribute is linked self.node.graph.removeEdge(attr) self._value.removeAt(index, count) self.requestGraphUpdate() self.valueChanged.emit() def uid(self, uidIndex): if isinstance(self.value, ListModel): uids = [] for value in self.value: if uidIndex in value.desc.uid: uids.append(value.uid(uidIndex)) return hashValue(uids) return super(ListAttribute, self).uid(uidIndex) def _applyExpr(self): if not self.node.graph: return if isinstance(self._value, ListAttribute) or Attribute.isLinkExpression( self._value): super(ListAttribute, self)._applyExpr() else: for value in self._value: value._applyExpr() def getExportValue(self): if self.isLink: return self.getLinkParam().asLinkExpr() return [attr.getExportValue() for attr in self._value] def defaultValue(self): return [] def _isDefault(self): return len(self._value) == 0 def getPrimitiveValue(self, exportDefault=True): if exportDefault: return [ attr.getPrimitiveValue(exportDefault=exportDefault) for attr in self._value ] else: return [ attr.getPrimitiveValue(exportDefault=exportDefault) for attr in self._value if not attr.isDefault ] def getValueStr(self): if isinstance(self.value, ListModel): return self.attributeDesc.joinChar.join( [v.getValueStr() for v in self.value]) return super(ListAttribute, self).getValueStr() def updateInternals(self): super(ListAttribute, self).updateInternals() for attr in self._value: attr.updateInternals() # Override value property setter value = Property(Variant, Attribute._get_value, _set_value, notify=Attribute.valueChanged) isDefault = Property(bool, _isDefault, notify=Attribute.valueChanged) baseType = Property(str, getBaseType, constant=True)