Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Nodes] Add a new 'enabled' property to node's attributes #1007

Merged
merged 8 commits into from
Jul 29, 2020
33 changes: 33 additions & 0 deletions meshroom/core/attribute.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def __init__(self, node, attributeDesc, isOutput, root=None, parent=None):
self._isOutput = isOutput
self._value = copy.copy(attributeDesc.value)
self._label = attributeDesc.label
self._enabled = True

# invalidation value for output attributes
self._invalidationValue = ""
Expand Down Expand Up @@ -95,6 +96,21 @@ def getType(self):
def getLabel(self):
return self._label

def getEnabled(self):
if isinstance(self.desc.enabled, types.FunctionType):
try:
return self.desc.enabled(self.node)
except:
# Node implementation may fail due to version mismatch
return True
return self.attributeDesc.enabled

def setEnabled(self, v):
if self._enabled == v:
return
self._enabled = v
self.enabledChanged.emit()

def _get_value(self):
return self.getLinkParam().value if self.isLink else self._value

Expand Down Expand Up @@ -224,6 +240,11 @@ def _isDefault(self):
def getPrimitiveValue(self, exportDefault=True):
return self._value

def updateInternals(self):
# Emit if the enable status has changed
self.setEnabled(self.getEnabled())


name = Property(str, getName, constant=True)
fullName = Property(str, getFullName, constant=True)
label = Property(str, getLabel, constant=True)
Expand All @@ -237,6 +258,8 @@ def getPrimitiveValue(self, exportDefault=True):
isDefault = Property(bool, _isDefault, notify=valueChanged)
linkParam = Property(BaseObject, getLinkParam, notify=isLinkChanged)
node = Property(BaseObject, node.fget, constant=True)
enabledChanged = Signal()
enabled = Property(bool, getEnabled, setEnabled, notify=enabledChanged)


def raiseIfLink(func):
Expand Down Expand Up @@ -353,6 +376,11 @@ def getValueStr(self):
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)
Expand Down Expand Up @@ -434,6 +462,11 @@ def getValueStr(self):
sortedSubValues = [self._value.get(attr.name).getValueStr() for attr in self.attributeDesc.groupDesc]
return self.attributeDesc.joinChar.join(sortedSubValues)

def updateInternals(self):
super(GroupAttribute, self).updateInternals()
for attr in self._value:
attr.updateInternals()

# Override value property
value = Property(Variant, Attribute._get_value, _set_value, notify=Attribute.valueChanged)
isDefault = Property(bool, _isDefault, notify=Attribute.valueChanged)
40 changes: 21 additions & 19 deletions meshroom/core/desc.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Attribute(BaseObject):
"""
"""

def __init__(self, name, label, description, value, advanced, uid, group):
def __init__(self, name, label, description, value, advanced, uid, group, enabled):
super(Attribute, self).__init__()
self._name = name
self._label = label
Expand All @@ -19,6 +19,7 @@ def __init__(self, name, label, description, value, advanced, uid, group):
self._uid = uid
self._group = group
self._advanced = advanced
self._enabled = enabled

name = Property(str, lambda self: self._name, constant=True)
label = Property(str, lambda self: self._label, constant=True)
Expand All @@ -27,6 +28,7 @@ def __init__(self, name, label, description, value, advanced, uid, group):
uid = Property(Variant, lambda self: self._uid, constant=True)
group = Property(str, lambda self: self._group, constant=True)
advanced = Property(bool, lambda self: self._advanced, constant=True)
enabled = Property(Variant, lambda self: self._enabled, constant=True)
type = Property(str, lambda self: self.__class__.__name__, constant=True)

def validateValue(self, value):
Expand All @@ -53,13 +55,13 @@ def matchDescription(self, value, conform=False):

class ListAttribute(Attribute):
""" A list of Attributes """
def __init__(self, elementDesc, name, label, description, group='allParams', advanced=False, joinChar=' '):
def __init__(self, elementDesc, name, label, description, group='allParams', advanced=False, enabled=True, joinChar=' '):
"""
:param elementDesc: the Attribute description of elements to store in that list
"""
self._elementDesc = elementDesc
self._joinChar = joinChar
super(ListAttribute, self).__init__(name=name, label=label, description=description, value=[], uid=(), group=group, advanced=advanced)
super(ListAttribute, self).__init__(name=name, label=label, description=description, value=[], uid=(), group=group, advanced=advanced, enabled=enabled)

elementDesc = Property(Attribute, lambda self: self._elementDesc, constant=True)
uid = Property(Variant, lambda self: self.elementDesc.uid, constant=True)
Expand All @@ -82,13 +84,13 @@ def matchDescription(self, value, conform=False):

class GroupAttribute(Attribute):
""" A macro Attribute composed of several Attributes """
def __init__(self, groupDesc, name, label, description, group='allParams', advanced=False, joinChar=' '):
def __init__(self, groupDesc, name, label, description, group='allParams', advanced=False, enabled=True, joinChar=' '):
"""
:param groupDesc: the description of the Attributes composing this group
"""
self._groupDesc = groupDesc
self._joinChar = joinChar
super(GroupAttribute, self).__init__(name=name, label=label, description=description, value={}, uid=(), group=group, advanced=advanced)
super(GroupAttribute, self).__init__(name=name, label=label, description=description, value={}, uid=(), group=group, advanced=advanced, enabled=enabled)

groupDesc = Property(Variant, lambda self: self._groupDesc, constant=True)

Expand Down Expand Up @@ -143,15 +145,15 @@ def retrieveChildrenUids(self):
class Param(Attribute):
"""
"""
def __init__(self, name, label, description, value, uid, group, advanced):
super(Param, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
def __init__(self, name, label, description, value, uid, group, advanced, enabled):
super(Param, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)


class File(Attribute):
"""
"""
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False):
super(File, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False, enabled=True):
super(File, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)

def validateValue(self, value):
if not isinstance(value, pyCompatibility.basestring):
Expand All @@ -162,8 +164,8 @@ def validateValue(self, value):
class BoolParam(Param):
"""
"""
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False):
super(BoolParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False, enabled=True):
super(BoolParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)

def validateValue(self, value):
try:
Expand All @@ -175,9 +177,9 @@ def validateValue(self, value):
class IntParam(Param):
"""
"""
def __init__(self, name, label, description, value, range, uid, group='allParams', advanced=False):
def __init__(self, name, label, description, value, range, uid, group='allParams', advanced=False, enabled=True):
self._range = range
super(IntParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
super(IntParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)

def validateValue(self, value):
# handle unsigned int values that are translated to int by shiboken and may overflow
Expand All @@ -194,9 +196,9 @@ def validateValue(self, value):
class FloatParam(Param):
"""
"""
def __init__(self, name, label, description, value, range, uid, group='allParams', advanced=False):
def __init__(self, name, label, description, value, range, uid, group='allParams', advanced=False, enabled=True):
self._range = range
super(FloatParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
super(FloatParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)

def validateValue(self, value):
try:
Expand All @@ -210,13 +212,13 @@ def validateValue(self, value):
class ChoiceParam(Param):
"""
"""
def __init__(self, name, label, description, value, values, exclusive, uid, group='allParams', joinChar=' ', advanced=False):
def __init__(self, name, label, description, value, values, exclusive, uid, group='allParams', joinChar=' ', advanced=False, enabled=True):
assert values
self._values = values
self._exclusive = exclusive
self._joinChar = joinChar
self._valueType = type(self._values[0]) # cast to value type
super(ChoiceParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
super(ChoiceParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)

def conformValue(self, val):
""" Conform 'val' to the correct type and check for its validity """
Expand All @@ -241,8 +243,8 @@ def validateValue(self, value):
class StringParam(Param):
"""
"""
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False):
super(StringParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced)
def __init__(self, name, label, description, value, uid, group='allParams', advanced=False, enabled=True):
super(StringParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, enabled=enabled)

def validateValue(self, value):
if not isinstance(value, pyCompatibility.basestring):
Expand Down
37 changes: 21 additions & 16 deletions meshroom/core/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -541,27 +541,28 @@ def _computeUids(self):
""" Compute node uids by combining associated attributes' uids. """
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]
uidAttributes = [(a.getName(), a.uid(uidIndex)) for a in associatedAttributes if a.enabled]
uidAttributes.sort()
self._uids[uidIndex] = hashValue(uidAttributes)

def _buildCmdVars(self):
def _buildAttributeCmdVars(cmdVars, name, attr):
if attr.attributeDesc.group is not None:
# if there is a valid command line "group"
v = attr.getValueStr()
cmdVars[name] = '--{name} {value}'.format(name=name, value=v)
cmdVars[name + 'Value'] = str(v)

if v:
cmdVars[attr.attributeDesc.group] = cmdVars.get(attr.attributeDesc.group, '') + \
' ' + cmdVars[name]
elif isinstance(attr, GroupAttribute):
assert isinstance(attr.value, DictModel)
# if the GroupAttribute is not set in a single command line argument,
# the sub-attributes may need to be exposed individually
for v in attr._value:
_buildAttributeCmdVars(cmdVars, v.name, v)
if attr.enabled:
if attr.attributeDesc.group is not None:
# if there is a valid command line "group"
v = attr.getValueStr()
cmdVars[name] = '--{name} {value}'.format(name=name, value=v)
cmdVars[name + 'Value'] = str(v)

if v:
cmdVars[attr.attributeDesc.group] = cmdVars.get(attr.attributeDesc.group, '') + \
' ' + cmdVars[name]
elif isinstance(attr, GroupAttribute):
assert isinstance(attr.value, DictModel)
# if the GroupAttribute is not set in a single command line argument,
# the sub-attributes may need to be exposed individually
for v in attr._value:
_buildAttributeCmdVars(cmdVars, v.name, v)

""" Generate command variables using input attributes and resolved output attributes names and values. """
for uidIndex, value in self._uids.items():
Expand Down Expand Up @@ -678,6 +679,10 @@ def updateInternals(self, cacheDir=None):
"""
if self.nodeDesc:
self.nodeDesc.update(self)

for attr in self._attributes:
attr.updateInternals()

# Update chunks splitting
self._updateChunks()
# Retrieve current internal folder (if possible)
Expand Down
14 changes: 8 additions & 6 deletions meshroom/nodes/aliceVision/CameraInit.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "2.0"
__version__ = "3.0"

import os
import json
Expand Down Expand Up @@ -159,7 +159,8 @@ class CameraInit(desc.CommandLineNode):
description='Empirical value for the field of view in degree.',
value=45.0,
range=(0, 180.0, 1),
uid=[0],
uid=[],
advanced=True,
),
desc.ChoiceParam(
name='groupCameraFallback',
Expand All @@ -173,7 +174,7 @@ class CameraInit(desc.CommandLineNode):
values=['global', 'folder', 'image'],
value='folder',
exclusive=True,
uid=[0],
uid=[],
advanced=True,
),
desc.ChoiceParam(
Expand All @@ -183,7 +184,7 @@ class CameraInit(desc.CommandLineNode):
value=['pinhole', 'radial1', 'radial3', 'brown', 'fisheye4', 'fisheye1'],
values=['pinhole', 'radial1', 'radial3', 'brown', 'fisheye4', 'fisheye1'],
exclusive=False,
uid=[0],
uid=[],
joinChar=',',
advanced=True,
),
Expand All @@ -196,7 +197,7 @@ class CameraInit(desc.CommandLineNode):
value='metadata',
values=['metadata', 'filename'],
exclusive=True,
uid=[0],
uid=[],
advanced=True,
),
desc.StringParam(
Expand All @@ -208,8 +209,9 @@ class CameraInit(desc.CommandLineNode):
' - Match the longest number at the end of filename (default value): ".*?(\d+)"\n'
' - Match the first number found in filename : "(\d+).*"\n',
value='.*?(\d+)',
uid=[0],
uid=[],
advanced=True,
enabled=lambda node: node.viewIdMethod.value == 'filename',
),
desc.ChoiceParam(
name='verboseLevel',
Expand Down
8 changes: 7 additions & 1 deletion meshroom/nodes/aliceVision/ImageMatching.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "1.1"
__version__ = "2.0"

import os
from meshroom.core import desc
Expand Down Expand Up @@ -75,6 +75,7 @@ class ImageMatching(desc.CommandLineNode):
description='Input name for the vocabulary tree file.',
value=os.environ.get('ALICEVISION_VOCTREE', ''),
uid=[],
enabled=lambda node: 'VocabularyTree' in node.method.value,
),
desc.File(
name='weights',
Expand All @@ -83,6 +84,7 @@ class ImageMatching(desc.CommandLineNode):
value='',
uid=[0],
advanced=True,
enabled=lambda node: 'VocabularyTree' in node.method.value,
),
desc.IntParam(
name='minNbImages',
Expand All @@ -92,6 +94,7 @@ class ImageMatching(desc.CommandLineNode):
range=(0, 500, 1),
uid=[0],
advanced=True,
enabled=lambda node: 'VocabularyTree' in node.method.value,
),
desc.IntParam(
name='maxDescriptors',
Expand All @@ -101,6 +104,7 @@ class ImageMatching(desc.CommandLineNode):
range=(0, 100000, 1),
uid=[0],
advanced=True,
enabled=lambda node: 'VocabularyTree' in node.method.value,
),
desc.IntParam(
name='nbMatches',
Expand All @@ -110,6 +114,7 @@ class ImageMatching(desc.CommandLineNode):
range=(0, 1000, 1),
uid=[0],
advanced=True,
enabled=lambda node: 'VocabularyTree' in node.method.value,
),
desc.IntParam(
name='nbNeighbors',
Expand All @@ -119,6 +124,7 @@ class ImageMatching(desc.CommandLineNode):
range=(0, 1000, 1),
uid=[0],
advanced=True,
enabled=lambda node: 'Sequential' in node.method.value,
),
desc.ChoiceParam(
name='verboseLevel',
Expand Down
Loading