Skip to content

Commit bcabb5b

Browse files
[ui] GroupAttribute: Connection validation responsability has been transfered to Attribute.
It let the opportunity to override it in specific Attribute
1 parent e81a096 commit bcabb5b

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

meshroom/core/attribute.py

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,20 @@ def _is2D(self) -> bool:
508508
return False
509509

510510
return next((imageSemantic for imageSemantic in Attribute.VALID_IMAGE_SEMANTICS if self.desc.semantic == imageSemantic), None) is not None
511+
512+
@Slot(BaseObject, result=bool)
513+
def validateConnectionFrom(self, otherAttribute: "Attribute") -> bool:
514+
""" Check if the given attribute can be conected to the current Attribute
515+
"""
516+
return self._validateConnectionFrom(otherAttribute)
517+
518+
def _validateConnectionFrom(self, otherAttribute: "Attribute") -> bool:
519+
""" Implementation of the connection validation
520+
521+
.. note:
522+
Override this method to use custom connection validation logic
523+
"""
524+
return self.baseType == otherAttribute.baseType
511525

512526
name = Property(str, getName, constant=True)
513527
fullName = Property(str, getFullName, constant=True)
@@ -861,6 +875,19 @@ def __getattr__(self, key):
861875
except KeyError:
862876
raise AttributeError(key)
863877

878+
def _get_value(self):
879+
linkedParam = self.getLinkParam()
880+
881+
if not linkedParam:
882+
return self._value
883+
884+
# If linked, the driver attributes values are copied to the current attribute
885+
for i, attrDesc in enumerate(self.desc._groupDesc):
886+
linkedAttrDesc = linkedParam.desc._groupDesc[i]
887+
self._value.get(attrDesc.name).value = linkedParam._value.get(linkedAttrDesc.name).value
888+
889+
return self._value
890+
864891
def _set_value(self, exportedValue):
865892
if self._handleLinkValue(exportedValue):
866893
return
@@ -992,6 +1019,28 @@ def updateInternals(self):
9921019
def matchText(self, text: str) -> bool:
9931020
return super().matchText(text) or any(c.matchText(text) for c in self._value)
9941021

1022+
def _validateConnectionFrom(self, otherAttribute:"Attribute") -> bool:
1023+
1024+
isValid = super()._validateConnectionFrom(otherAttribute=otherAttribute)
1025+
1026+
if not isValid:
1027+
return False
1028+
1029+
return self._haveSameStructure(otherAttribute)
1030+
1031+
def _haveSameStructure(self, otherAttribute: "Attribute") -> bool:
1032+
""" Does the given attribute have the same number of attributes, and all ordered attributes have the same baseType
1033+
"""
1034+
1035+
if isinstance(otherAttribute._value, Iterable) and len(otherAttribute._value) != len(self._value):
1036+
return False
1037+
1038+
for i, attr in enumerate(self._value):
1039+
if attr.baseType != otherAttribute._value[i].baseType:
1040+
return False
1041+
1042+
return True
1043+
9951044
# Override value property
996-
value = Property(Variant, Attribute._get_value, _set_value, notify=Attribute.valueChanged)
1045+
value = Property(Variant, _get_value, _set_value, notify=Attribute.valueChanged)
9971046
isDefault = Property(bool, _isDefault, notify=Attribute.valueChanged)

meshroom/ui/commands.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,8 @@ def __init__(self, graph, src, dst, parent=None):
314314
self.dstAttr = dst.getFullNameToNode()
315315
self.setText(f"Connect '{self.srcAttr}'->'{self.dstAttr}'")
316316

317-
if src.baseType != dst.baseType:
318-
raise ValueError(f"Attribute types are not compatible and cannot be connected: '{self.srcAttr}'({src.baseType})->'{self.dstAttr}'({dst.baseType})")
317+
if not dst.validateConnectionFrom(src):
318+
raise ValueError(f"Attribute are not compatible and cannot be connected: '{self.srcAttr}'({src.baseType})->'{self.dstAttr}'({dst.baseType})")
319319

320320
def redoImpl(self):
321321
self.graph.addEdge(self.graph.attribute(self.srcAttr), self.graph.attribute(self.dstAttr))

meshroom/ui/qml/GraphEditor/AttributePin.qml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ RowLayout {
106106
// Check if attributes are compatible to create a valid connection
107107
if (root.readOnly // Cannot connect on a read-only attribute
108108
|| drag.source.objectName != inputDragTarget.objectName // Not an edge connector
109-
|| drag.source.baseType !== inputDragTarget.baseType // Not the same base type
109+
|| !inputDragTarget.attribute.validateConnectionFrom(drag.source.attribute) //
110110
|| drag.source.nodeItem === inputDragTarget.nodeItem // Connection between attributes of the same node
111111
|| (drag.source.isList && childrenRepeater.count) // Source/target are lists but target already has children
112112
|| drag.source.connectorType === "input" // Refuse to connect an "input pin" on another one (input attr can be connected to input attr, but not the graphical pin)
@@ -256,7 +256,7 @@ RowLayout {
256256
onEntered: function(drag) {
257257
// Check if attributes are compatible to create a valid connection
258258
if (drag.source.objectName != outputDragTarget.objectName // Not an edge connector
259-
|| drag.source.baseType !== outputDragTarget.baseType // Not the same base type
259+
|| !outputDragTarget.attribute.validateConnectionFrom(drag.source.attribute) //
260260
|| drag.source.nodeItem === outputDragTarget.nodeItem // Connection between attributes of the same node
261261
|| (!drag.source.isList && outputDragTarget.isList) // Connection between a list and a simple attribute
262262
|| (drag.source.isList && childrenRepeater.count) // Source/target are lists but target already has children

0 commit comments

Comments
 (0)