Skip to content

Commit

Permalink
[core] Add a property to ignore an attribute during the UID computation
Browse files Browse the repository at this point in the history
By default, an attribute that belongs to the UID group 0 is taken into
the node's UID computation independently from its value, as long as it is
enabled.

When such an attribute is added to a node's list of attributes, it
automatically invalidates all computations made for this node prior to
its addition.

This commits adds a new attribute property, "uidIgnoreValue". This property
determines whether the attribute must be taken into consideration during
the node's UID computation: if the value of the attribute is the same as
"uidIgnoreValue", then it should be ignored; otherwise, it should be taken
into account. By default, "uidIgnoreValue" is set to "None", meaning that
any attribute that may be considered during the UID computation will be
taken into account.

In the context of the internal attributes, "uidIgnoreValue" is set to empty
string, so the "invalidation" attribute will not automatically
invalidate 100% of the nodes from existing graphs until its value is set
to a non-empty string.
  • Loading branch information
cbentejac committed Feb 15, 2023
1 parent 1299660 commit d601e4a
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 16 deletions.
6 changes: 6 additions & 0 deletions meshroom/core/attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ def __init__(self, node, attributeDesc, isOutput, root=None, parent=None):
self._value = copy.copy(attributeDesc.value)
self._label = attributeDesc.label
self._enabled = True
self._uidIgnoreValue = attributeDesc.uidIgnoreValue

# invalidation value for output attributes
self._invalidationValue = ""
Expand Down Expand Up @@ -143,6 +144,10 @@ def setEnabled(self, v):
self._enabled = v
self.enabledChanged.emit()

def getUidIgnoreValue(self):
""" Value for which the attribute should be ignored during the UID computation. """
return self._uidIgnoreValue

def _get_value(self):
if self.isLink:
return self.getLinkParam().value
Expand Down Expand Up @@ -333,6 +338,7 @@ def updateInternals(self):
node = Property(BaseObject, node.fget, constant=True)
enabledChanged = Signal()
enabled = Property(bool, getEnabled, setEnabled, notify=enabledChanged)
uidIgnoreValue = Property(Variant, getUidIgnoreValue, constant=True)


def raiseIfLink(func):
Expand Down
17 changes: 11 additions & 6 deletions meshroom/core/desc.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Attribute(BaseObject):
"""
"""

def __init__(self, name, label, description, value, advanced, semantic, uid, group, enabled):
def __init__(self, name, label, description, value, advanced, semantic, uid, group, enabled, uidIgnoreValue=None):
super(Attribute, self).__init__()
self._name = name
self._label = label
Expand All @@ -25,6 +25,7 @@ def __init__(self, name, label, description, value, advanced, semantic, uid, gro
self._advanced = advanced
self._enabled = enabled
self._semantic = semantic
self._uidIgnoreValue = uidIgnoreValue

name = Property(str, lambda self: self._name, constant=True)
label = Property(str, lambda self: self._label, constant=True)
Expand All @@ -35,6 +36,7 @@ def __init__(self, name, label, description, value, advanced, semantic, uid, gro
advanced = Property(bool, lambda self: self._advanced, constant=True)
enabled = Property(Variant, lambda self: self._enabled, constant=True)
semantic = Property(str, lambda self: self._semantic, constant=True)
uidIgnoreValue = Property(Variant, lambda self: self._uidIgnoreValue, constant=True)
type = Property(str, lambda self: self.__class__.__name__, constant=True)

def validateValue(self, value):
Expand Down Expand Up @@ -201,8 +203,9 @@ def retrieveChildrenUids(self):
class Param(Attribute):
"""
"""
def __init__(self, name, label, description, value, uid, group, advanced, semantic, enabled):
super(Param, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, semantic=semantic, enabled=enabled)
def __init__(self, name, label, description, value, uid, group, advanced, semantic, enabled, uidIgnoreValue=None):
super(Param, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, semantic=semantic, enabled=enabled,
uidIgnoreValue=uidIgnoreValue)


class File(Attribute):
Expand Down Expand Up @@ -329,8 +332,9 @@ def checkValueTypes(self):
class StringParam(Param):
"""
"""
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False, semantic='', enabled=True):
super(StringParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, semantic=semantic, enabled=enabled)
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False, semantic='', enabled=True, uidIgnoreValue=None):
super(StringParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, semantic=semantic, enabled=enabled,
uidIgnoreValue=uidIgnoreValue)

def validateValue(self, value):
if not isinstance(value, str):
Expand Down Expand Up @@ -507,8 +511,9 @@ class Node(object):
"It is displayed in bold font in the invalidation/comment messages tooltip.",
value="",
semantic="multiline",
uid=[-1], # specific uid group: the attribute will be taken into account in the final UID computation if its value is not empty
uid=[0],
advanced=True,
uidIgnoreValue=""
),
StringParam(
name="comment",
Expand Down
15 changes: 5 additions & 10 deletions meshroom/core/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -689,16 +689,11 @@ def toDict(self):

def _computeUids(self):
""" Compute node uids by combining associated attributes' uids. """
conditionalUids = [] # uids that are taken into account in the final computation only if their attribute's value is not empty; their UID group is -1

for uidIndex, associatedAttributes in sorted(self.attributesPerUid.items()): # sort the dictionary to ensure the group of index -1 is always parsed first
if uidIndex == -1:
conditionalUids = [(a.getName(), a.uid(uidIndex)) for a in associatedAttributes if a.enabled and a.value != ""]
else:
# uid is computed by hashing the sorted list of tuple (name, value) of all attributes impacting this uid
uidAttributes = [(a.getName(), a.uid(uidIndex)) for a in associatedAttributes if a.enabled] + conditionalUids
uidAttributes.sort()
self._uids[uidIndex] = hashValue(uidAttributes)
for uidIndex, associatedAttributes in self.attributesPerUid.items():
# uid is computed by hashing the sorted list of tuple (name, value) of all attributes impacting this uid
uidAttributes = [(a.getName(), a.uid(uidIndex)) for a in associatedAttributes if a.enabled and a.value != a.uidIgnoreValue]
uidAttributes.sort()
self._uids[uidIndex] = hashValue(uidAttributes)

def _buildCmdVars(self):
def _buildAttributeCmdVars(cmdVars, name, attr):
Expand Down

0 comments on commit d601e4a

Please sign in to comment.