From 2d953d73194a1901e1a021d45bbadb2d26ff4408 Mon Sep 17 00:00:00 2001 From: Julien-Haudegond <44610840+Julien-Haudegond@users.noreply.github.com> Date: Fri, 24 Jul 2020 17:36:17 +0200 Subject: [PATCH 1/8] [core] add enabled property on attributes The new property "enabled" allows to define a lambda to dynamically enable/disable parameters. Disabled parameters are not used in the uid, not exported to the command line and not visible in the interface. --- meshroom/core/attribute.py | 18 +++++++++ meshroom/core/desc.py | 40 ++++++++++--------- meshroom/core/node.py | 23 ++++++----- .../ui/qml/GraphEditor/AttributeEditor.qml | 2 +- 4 files changed, 54 insertions(+), 29 deletions(-) mode change 100755 => 100644 meshroom/core/desc.py diff --git a/meshroom/core/attribute.py b/meshroom/core/attribute.py index dd28c9b684..b661fe4322 100644 --- a/meshroom/core/attribute.py +++ b/meshroom/core/attribute.py @@ -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 = "" @@ -95,6 +96,15 @@ def getType(self): def getLabel(self): return self._label + def getEnabled(self): + return self._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 @@ -224,6 +234,12 @@ def _isDefault(self): def getPrimitiveValue(self, exportDefault=True): return self._value + def updateInternals(self): + if isinstance(self.desc.enabled, types.FunctionType): + self.setEnabled(self.desc.enabled(self.node)) + else: + self.setEnabled(self.attributeDesc.enabled) + name = Property(str, getName, constant=True) fullName = Property(str, getFullName, constant=True) label = Property(str, getLabel, constant=True) @@ -237,6 +253,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): diff --git a/meshroom/core/desc.py b/meshroom/core/desc.py old mode 100755 new mode 100644 index 202b5f86f7..4cf348cc6c --- a/meshroom/core/desc.py +++ b/meshroom/core/desc.py @@ -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 @@ -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) @@ -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): @@ -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) @@ -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) @@ -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): @@ -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: @@ -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 @@ -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: @@ -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 """ @@ -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): diff --git a/meshroom/core/node.py b/meshroom/core/node.py index a59e4b1cd2..6e8cc5b1e3 100644 --- a/meshroom/core/node.py +++ b/meshroom/core/node.py @@ -541,21 +541,22 @@ 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] + if attr.enabled: + # 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, @@ -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) diff --git a/meshroom/ui/qml/GraphEditor/AttributeEditor.qml b/meshroom/ui/qml/GraphEditor/AttributeEditor.qml index 62a6b2f2a2..c1d6011929 100644 --- a/meshroom/ui/qml/GraphEditor/AttributeEditor.qml +++ b/meshroom/ui/qml/GraphEditor/AttributeEditor.qml @@ -26,7 +26,7 @@ ListView { model: attributes delegate: Loader { - active: !object.desc.advanced || GraphEditorSettings.showAdvancedAttributes + active: object.enabled && (!object.desc.advanced || GraphEditorSettings.showAdvancedAttributes) visible: active height: item ? item.implicitHeight : -spacing // compensate for spacing if item is hidden From 524a4ab629038f99016e91a74a4018c185077fff Mon Sep 17 00:00:00 2001 From: Julien-Haudegond <44610840+Julien-Haudegond@users.noreply.github.com> Date: Wed, 29 Jul 2020 11:32:52 +0200 Subject: [PATCH 2/8] [core] fix enabled parameter inside group and list --- meshroom/core/attribute.py | 21 ++++++++++++++++----- meshroom/core/node.py | 16 ++++++++-------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/meshroom/core/attribute.py b/meshroom/core/attribute.py index b661fe4322..f07bd4fb2e 100644 --- a/meshroom/core/attribute.py +++ b/meshroom/core/attribute.py @@ -97,7 +97,9 @@ def getLabel(self): return self._label def getEnabled(self): - return self._enabled + if isinstance(self.desc.enabled, types.FunctionType): + return self.desc.enabled(self.node) + return self.attributeDesc.enabled def setEnabled(self, v): if self._enabled == v: @@ -235,10 +237,9 @@ def getPrimitiveValue(self, exportDefault=True): return self._value def updateInternals(self): - if isinstance(self.desc.enabled, types.FunctionType): - self.setEnabled(self.desc.enabled(self.node)) - else: - self.setEnabled(self.attributeDesc.enabled) + # Emit if the enable status has changed + self.setEnabled(self.getEnabled()) + name = Property(str, getName, constant=True) fullName = Property(str, getFullName, constant=True) @@ -371,6 +372,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) @@ -452,6 +458,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) diff --git a/meshroom/core/node.py b/meshroom/core/node.py index 6e8cc5b1e3..302c5a31a3 100644 --- a/meshroom/core/node.py +++ b/meshroom/core/node.py @@ -547,8 +547,8 @@ def _computeUids(self): def _buildCmdVars(self): def _buildAttributeCmdVars(cmdVars, name, attr): - if attr.attributeDesc.group is not None: - if attr.enabled: + 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) @@ -557,12 +557,12 @@ def _buildAttributeCmdVars(cmdVars, name, attr): 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) + 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(): From a5407fc8c78131cdab64b6e56711165f080f42b7 Mon Sep 17 00:00:00 2001 From: Julien-Haudegond <44610840+Julien-Haudegond@users.noreply.github.com> Date: Wed, 29 Jul 2020 11:34:45 +0200 Subject: [PATCH 3/8] [ui] Graph Editor: remove useless attributes property --- meshroom/ui/qml/GraphEditor/AttributeEditor.qml | 3 --- meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml | 2 +- meshroom/ui/qml/GraphEditor/NodeEditor.qml | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/meshroom/ui/qml/GraphEditor/AttributeEditor.qml b/meshroom/ui/qml/GraphEditor/AttributeEditor.qml index c1d6011929..6baeca39e1 100644 --- a/meshroom/ui/qml/GraphEditor/AttributeEditor.qml +++ b/meshroom/ui/qml/GraphEditor/AttributeEditor.qml @@ -10,7 +10,6 @@ import Utils 1.0 ListView { id: root - property variant attributes: null property bool readOnly: false property int labelWidth: 180 @@ -23,8 +22,6 @@ ListView { clip: true ScrollBar.vertical: ScrollBar { id: scrollBar } - model: attributes - delegate: Loader { active: object.enabled && (!object.desc.advanced || GraphEditorSettings.showAdvancedAttributes) visible: active diff --git a/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml b/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml index 5aee77bd6e..7c918196f9 100644 --- a/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml +++ b/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml @@ -370,7 +370,7 @@ RowLayout { Component.onCompleted: { var cpt = Qt.createComponent("AttributeEditor.qml"); var obj = cpt.createObject(groupItem, - {'attributes': Qt.binding(function() { return attribute.value }), + {'model': Qt.binding(function() { return attribute.value }), 'readOnly': Qt.binding(function() { return root.readOnly }), 'labelWidth': 100, // reduce label width for children (space gain) }) diff --git a/meshroom/ui/qml/GraphEditor/NodeEditor.qml b/meshroom/ui/qml/GraphEditor/NodeEditor.qml index 4cc96ae6d9..ba3e33bf61 100644 --- a/meshroom/ui/qml/GraphEditor/NodeEditor.qml +++ b/meshroom/ui/qml/GraphEditor/NodeEditor.qml @@ -122,7 +122,7 @@ Panel { currentIndex: tabBar.currentIndex AttributeEditor { - attributes: root.node.attributes + model: root.node.attributes readOnly: root.readOnly || root.isCompatibilityNode onAttributeDoubleClicked: root.attributeDoubleClicked(mouse, attribute) onUpgradeRequest: root.upgradeRequest() From d1756ca650d10cb26333faa342eed5c8dbd8fddb Mon Sep 17 00:00:00 2001 From: Julien-Haudegond <44610840+Julien-Haudegond@users.noreply.github.com> Date: Wed, 29 Jul 2020 11:38:13 +0200 Subject: [PATCH 4/8] [nodes] update several nodes with enabled parameter --- meshroom/nodes/aliceVision/CameraInit.py | 1 + meshroom/nodes/aliceVision/ImageMatching.py | 6 ++++++ meshroom/nodes/aliceVision/ImageProcessing.py | 14 +++++++++++++- meshroom/nodes/aliceVision/Meshing.py | 2 ++ meshroom/nodes/aliceVision/PanoramaInit.py | 7 +++++-- 5 files changed, 27 insertions(+), 3 deletions(-) diff --git a/meshroom/nodes/aliceVision/CameraInit.py b/meshroom/nodes/aliceVision/CameraInit.py index 1d632a3ddf..53671443a9 100644 --- a/meshroom/nodes/aliceVision/CameraInit.py +++ b/meshroom/nodes/aliceVision/CameraInit.py @@ -210,6 +210,7 @@ class CameraInit(desc.CommandLineNode): value='.*?(\d+)', uid=[0], advanced=True, + enabled=lambda node: node.viewIdMethod.value == 'filename', ), desc.ChoiceParam( name='verboseLevel', diff --git a/meshroom/nodes/aliceVision/ImageMatching.py b/meshroom/nodes/aliceVision/ImageMatching.py index c117548b1f..795afae13d 100644 --- a/meshroom/nodes/aliceVision/ImageMatching.py +++ b/meshroom/nodes/aliceVision/ImageMatching.py @@ -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', @@ -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', @@ -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', @@ -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', @@ -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', @@ -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', diff --git a/meshroom/nodes/aliceVision/ImageProcessing.py b/meshroom/nodes/aliceVision/ImageProcessing.py index fda72c712a..c86b038669 100644 --- a/meshroom/nodes/aliceVision/ImageProcessing.py +++ b/meshroom/nodes/aliceVision/ImageProcessing.py @@ -126,7 +126,7 @@ class ImageProcessing(desc.CommandLineNode): ), desc.GroupAttribute(name="sharpenFilter", label="Sharpen Filter", description="Sharpen Filtering Parameters.", joinChar=":", groupDesc=[ desc.BoolParam( - name='enabled', + name='sharpenFilterEnabled', label='Enable', description='Use sharpen.', value=False, @@ -139,6 +139,7 @@ class ImageProcessing(desc.CommandLineNode): value=3, range=(1, 9, 2), uid=[0], + enabled=lambda node: node.sharpenFilter.sharpenFilterEnabled.value, ), desc.FloatParam( name='contrast', @@ -147,6 +148,7 @@ class ImageProcessing(desc.CommandLineNode): value=1.0, range=(0.0, 100.0, 0.1), uid=[0], + enabled=lambda node: node.sharpenFilter.sharpenFilterEnabled.value, ), desc.FloatParam( name='threshold', @@ -155,6 +157,7 @@ class ImageProcessing(desc.CommandLineNode): value=0.0, range=(0.0, 1.0, 0.01), uid=[0], + enabled=lambda node: node.sharpenFilter.sharpenFilterEnabled.value, ), ]), desc.GroupAttribute(name="bilateralFilter", label="Bilateral Filter", description="Bilateral Filtering Parameters.", joinChar=":", groupDesc=[ @@ -172,6 +175,7 @@ class ImageProcessing(desc.CommandLineNode): value=0, range=(0, 9, 1), uid=[0], + enabled=lambda node: node.bilateralFilter.bilateralFilterEnabled.value, ), desc.FloatParam( name='bilateralFilterSigmaSpace', @@ -180,6 +184,7 @@ class ImageProcessing(desc.CommandLineNode): value=0.0, range=(0.0, 150.0, 0.01), uid=[0], + enabled=lambda node: node.bilateralFilter.bilateralFilterEnabled.value, ), desc.FloatParam( name='bilateralFilterSigmaColor', @@ -188,6 +193,7 @@ class ImageProcessing(desc.CommandLineNode): value=0.0, range=(0.0, 150.0, 0.01), uid=[0], + enabled=lambda node: node.bilateralFilter.bilateralFilterEnabled.value, ), ]), desc.GroupAttribute(name="claheFilter", label="Clahe Filter", description="Clahe Filtering Parameters.", joinChar=":", groupDesc=[ @@ -205,6 +211,7 @@ class ImageProcessing(desc.CommandLineNode): value=4.0, range=(0.0, 8.0, 1.0), uid=[0], + enabled=lambda node: node.claheFilter.claheEnabled.value, ), desc.IntParam( name='claheTileGridSize', @@ -213,6 +220,7 @@ class ImageProcessing(desc.CommandLineNode): value=8, range=(4, 64, 4), uid=[0], + enabled=lambda node: node.claheFilter.claheEnabled.value, ), ]), desc.GroupAttribute(name="noiseFilter", label="Noise Filter", description="Noise Filtering Parameters.", joinChar=":", groupDesc=[ @@ -234,6 +242,7 @@ class ImageProcessing(desc.CommandLineNode): values=['uniform', 'gaussian', 'salt'], exclusive=True, uid=[0], + enabled=lambda node: node.noiseFilter.noiseEnabled.value, ), desc.FloatParam( name='noiseA', @@ -242,6 +251,7 @@ class ImageProcessing(desc.CommandLineNode): value=0.0, range=(0.0, 1.0, 0.0001), uid=[0], + enabled=lambda node: node.noiseFilter.noiseEnabled.value, ), desc.FloatParam( name='noiseB', @@ -250,6 +260,7 @@ class ImageProcessing(desc.CommandLineNode): value=1.0, range=(0.0, 1.0, 0.0001), uid=[0], + enabled=lambda node: node.noiseFilter.noiseEnabled.value, ), desc.BoolParam( name='noiseMono', @@ -257,6 +268,7 @@ class ImageProcessing(desc.CommandLineNode): description='If is Checked, a single noise value will be applied to all channels otherwise a separate noise value will be computed for each channel.', value=True, uid=[0], + enabled=lambda node: node.noiseFilter.noiseEnabled.value, ), ]), desc.ChoiceParam( diff --git a/meshroom/nodes/aliceVision/Meshing.py b/meshroom/nodes/aliceVision/Meshing.py index e46bffbf29..f48b71b1f3 100644 --- a/meshroom/nodes/aliceVision/Meshing.py +++ b/meshroom/nodes/aliceVision/Meshing.py @@ -51,6 +51,7 @@ class Meshing(desc.CommandLineNode): range=(0, 100, 1), uid=[0], advanced=True, + enabled=lambda node: node.estimateSpaceFromSfM.value, ), desc.FloatParam( name='estimateSpaceMinObservationAngle', @@ -59,6 +60,7 @@ class Meshing(desc.CommandLineNode): value=10, range=(0, 120, 1), uid=[0], + enabled=lambda node: node.estimateSpaceFromSfM.value, ), desc.IntParam( name='maxInputPoints', diff --git a/meshroom/nodes/aliceVision/PanoramaInit.py b/meshroom/nodes/aliceVision/PanoramaInit.py index 9abcdcd871..fcbb479444 100644 --- a/meshroom/nodes/aliceVision/PanoramaInit.py +++ b/meshroom/nodes/aliceVision/PanoramaInit.py @@ -45,7 +45,7 @@ class PanoramaInit(desc.CommandLineNode): name='dependency', label='Dependency', description="Folder(s) in which computed features are stored. (WORKAROUND for valid Tractor graph submission)", - group='forDependencyOnly', # not a command line argument + group='forDependencyOnly', # not a command line argument ), desc.BoolParam( name='useFisheye', @@ -60,6 +60,7 @@ class PanoramaInit(desc.CommandLineNode): description='Automatically estimate the Fisheye Circle center and radius instead of using user values.', value=True, uid=[0], + enabled=lambda node: node.useFisheye.value, ), desc.GroupAttribute( name="fisheyeCenterOffset", @@ -77,7 +78,8 @@ class PanoramaInit(desc.CommandLineNode): uid=[0], range=(-1000.0, 10000.0, 1.0)), ], - group=None, # skip group from command line + group=None, # skip group from command line + enabled=lambda node: node.useFisheye.value and not node.estimateFisheyeCircle.value, ), desc.FloatParam( name='fisheyeRadius', @@ -86,6 +88,7 @@ class PanoramaInit(desc.CommandLineNode): value=96.0, range=(0.0, 150.0, 0.01), uid=[0], + enabled=lambda node: node.useFisheye.value and not node.estimateFisheyeCircle.value, ), desc.ChoiceParam( name='verboseLevel', From 4e20286ac0d84e407940a1490c39dcea5103d1af Mon Sep 17 00:00:00 2001 From: Julien-Haudegond <44610840+Julien-Haudegond@users.noreply.github.com> Date: Wed, 29 Jul 2020 14:39:38 +0200 Subject: [PATCH 5/8] [nodes] increment nodes version --- meshroom/nodes/aliceVision/CameraInit.py | 2 +- meshroom/nodes/aliceVision/ImageMatching.py | 2 +- meshroom/nodes/aliceVision/ImageProcessing.py | 2 +- meshroom/nodes/aliceVision/Meshing.py | 2 +- meshroom/nodes/aliceVision/PanoramaInit.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/meshroom/nodes/aliceVision/CameraInit.py b/meshroom/nodes/aliceVision/CameraInit.py index 53671443a9..391c80b5b1 100644 --- a/meshroom/nodes/aliceVision/CameraInit.py +++ b/meshroom/nodes/aliceVision/CameraInit.py @@ -1,4 +1,4 @@ -__version__ = "2.0" +__version__ = "3.0" import os import json diff --git a/meshroom/nodes/aliceVision/ImageMatching.py b/meshroom/nodes/aliceVision/ImageMatching.py index 795afae13d..6560afbb34 100644 --- a/meshroom/nodes/aliceVision/ImageMatching.py +++ b/meshroom/nodes/aliceVision/ImageMatching.py @@ -1,4 +1,4 @@ -__version__ = "1.1" +__version__ = "2.0" import os from meshroom.core import desc diff --git a/meshroom/nodes/aliceVision/ImageProcessing.py b/meshroom/nodes/aliceVision/ImageProcessing.py index c86b038669..f97c8ab4c3 100644 --- a/meshroom/nodes/aliceVision/ImageProcessing.py +++ b/meshroom/nodes/aliceVision/ImageProcessing.py @@ -1,4 +1,4 @@ -__version__ = "2.0" +__version__ = "3.0" from meshroom.core import desc diff --git a/meshroom/nodes/aliceVision/Meshing.py b/meshroom/nodes/aliceVision/Meshing.py index f48b71b1f3..0c7b19e894 100644 --- a/meshroom/nodes/aliceVision/Meshing.py +++ b/meshroom/nodes/aliceVision/Meshing.py @@ -1,4 +1,4 @@ -__version__ = "4.0" +__version__ = "5.0" from meshroom.core import desc diff --git a/meshroom/nodes/aliceVision/PanoramaInit.py b/meshroom/nodes/aliceVision/PanoramaInit.py index fcbb479444..068faea436 100644 --- a/meshroom/nodes/aliceVision/PanoramaInit.py +++ b/meshroom/nodes/aliceVision/PanoramaInit.py @@ -1,4 +1,4 @@ -__version__ = "1.0" +__version__ = "2.0" from meshroom.core import desc From f1af5586039cbea767f53dee30a8412b34c3604c Mon Sep 17 00:00:00 2001 From: Julien-Haudegond <44610840+Julien-Haudegond@users.noreply.github.com> Date: Wed, 29 Jul 2020 16:04:41 +0200 Subject: [PATCH 6/8] [nodes] update LdrToHdr nodes with enabled parameter --- meshroom/nodes/aliceVision/LdrToHdrMerge.py | 51 ++++++++++--------- .../nodes/aliceVision/LdrToHdrSampling.py | 12 +++-- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/meshroom/nodes/aliceVision/LdrToHdrMerge.py b/meshroom/nodes/aliceVision/LdrToHdrMerge.py index 3304670ba0..0b8811ce2f 100644 --- a/meshroom/nodes/aliceVision/LdrToHdrMerge.py +++ b/meshroom/nodes/aliceVision/LdrToHdrMerge.py @@ -1,4 +1,4 @@ -__version__ = "2.0" +__version__ = "3.0" import json @@ -47,26 +47,6 @@ class LdrToHdrMerge(desc.CommandLineNode): value='', uid=[0], ), - desc.IntParam( - name='offsetRefBracketIndex', - label='Offset Ref Bracket Index', - description='Zero to use the center bracket. +N to use a more exposed bracket or -N to use a less exposed backet.', - value=1, - range=(-4, 4, 1), - uid=[0], - ), - desc.ChoiceParam( - name='fusionWeight', - label='Fusion Weight', - description="Weight function used to fuse all LDR images together:\n" - " * gaussian \n" - " * triangle \n" - " * plateau", - value='gaussian', - values=['gaussian', 'triangle', 'plateau'], - exclusive=True, - uid=[0], - ), desc.IntParam( name='userNbBrackets', label='Number of Brackets', @@ -84,13 +64,35 @@ class LdrToHdrMerge(desc.CommandLineNode): range=(0, 10, 1), uid=[], ), + desc.IntParam( + name='offsetRefBracketIndex', + label='Offset Ref Bracket Index', + description='Zero to use the center bracket. +N to use a more exposed bracket or -N to use a less exposed backet.', + value=1, + range=(-4, 4, 1), + uid=[0], + enabled= lambda node: node.nbBrackets.value != 1, + ), desc.BoolParam( name='byPass', - label='bypass convert', + label='Bypass', description="Bypass HDR creation and use the medium bracket as the source for the next steps.", value=False, uid=[0], - advanced=True, + enabled= lambda node: node.nbBrackets.value != 1, + ), + desc.ChoiceParam( + name='fusionWeight', + label='Fusion Weight', + description="Weight function used to fuse all LDR images together:\n" + " * gaussian \n" + " * triangle \n" + " * plateau", + value='gaussian', + values=['gaussian', 'triangle', 'plateau'], + exclusive=True, + uid=[0], + enabled= lambda node: node.byPass.enabled and not node.byPass.value, ), desc.IntParam( name='channelQuantizationPower', @@ -100,6 +102,7 @@ class LdrToHdrMerge(desc.CommandLineNode): range=(8, 14, 1), uid=[0], advanced=True, + enabled= lambda node: node.byPass.enabled and not node.byPass.value, ), desc.FloatParam( name='highlightCorrectionFactor', @@ -112,6 +115,7 @@ class LdrToHdrMerge(desc.CommandLineNode): value=1.0, range=(0.0, 1.0, 0.01), uid=[0], + enabled= lambda node: node.byPass.enabled and not node.byPass.value, ), desc.FloatParam( name='highlightTargetLux', @@ -134,6 +138,7 @@ class LdrToHdrMerge(desc.CommandLineNode): value=120000.0, range=(1000.0, 150000.0, 1.0), uid=[0], + enabled= lambda node: node.byPass.enabled and not node.byPass.value and node.highlightCorrectionFactor.value != 0, ), desc.ChoiceParam( name='verboseLevel', diff --git a/meshroom/nodes/aliceVision/LdrToHdrSampling.py b/meshroom/nodes/aliceVision/LdrToHdrSampling.py index 5db4adf1b6..eeb27aaab7 100644 --- a/meshroom/nodes/aliceVision/LdrToHdrSampling.py +++ b/meshroom/nodes/aliceVision/LdrToHdrSampling.py @@ -1,4 +1,4 @@ -__version__ = "2.0" +__version__ = "3.0" import json @@ -76,11 +76,12 @@ class LdrToHdrSampling(desc.CommandLineNode): ), desc.BoolParam( name='byPass', - label='bypass convert', + label='Bypass', description="Bypass HDR creation and use the medium bracket as the source for the next steps", value=False, uid=[0], group='internal', + enabled= lambda node: node.nbBrackets.value != 1, ), desc.IntParam( name='channelQuantizationPower', @@ -90,6 +91,7 @@ class LdrToHdrSampling(desc.CommandLineNode): range=(8, 14, 1), uid=[0], advanced=True, + enabled= lambda node: node.byPass.enabled and not node.byPass.value, ), desc.IntParam( name='blockSize', @@ -99,6 +101,7 @@ class LdrToHdrSampling(desc.CommandLineNode): range=(8, 1024, 1), uid=[0], advanced=True, + enabled= lambda node: node.byPass.enabled and not node.byPass.value, ), desc.IntParam( name='radius', @@ -108,6 +111,7 @@ class LdrToHdrSampling(desc.CommandLineNode): range=(0, 10, 1), uid=[0], advanced=True, + enabled= lambda node: node.byPass.enabled and not node.byPass.value, ), desc.IntParam( name='maxCountSample', @@ -117,6 +121,7 @@ class LdrToHdrSampling(desc.CommandLineNode): range=(10, 1000, 10), uid=[0], advanced=True, + enabled= lambda node: node.byPass.enabled and not node.byPass.value, ), desc.BoolParam( name='debug', @@ -124,6 +129,7 @@ class LdrToHdrSampling(desc.CommandLineNode): description="Export debug files to analyze the sampling strategy.", value=False, uid=[], + enabled= lambda node: node.byPass.enabled and not node.byPass.value, ), desc.ChoiceParam( name='verboseLevel', @@ -147,7 +153,7 @@ class LdrToHdrSampling(desc.CommandLineNode): ] def processChunk(self, chunk): - if chunk.node.byPass.value: + if chunk.node.nbBrackets.value == 1 or chunk.node.byPass.value: return super(LdrToHdrSampling, self).processChunk(chunk) From 9e6c137ea20a65ed81e06a0036d31e023d8cec5d Mon Sep 17 00:00:00 2001 From: Julien-Haudegond <44610840+Julien-Haudegond@users.noreply.github.com> Date: Wed, 29 Jul 2020 17:02:16 +0200 Subject: [PATCH 7/8] [core] fix enabled issue when version mismatch --- meshroom/core/attribute.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/meshroom/core/attribute.py b/meshroom/core/attribute.py index f07bd4fb2e..cb253923d6 100644 --- a/meshroom/core/attribute.py +++ b/meshroom/core/attribute.py @@ -98,7 +98,11 @@ def getLabel(self): def getEnabled(self): if isinstance(self.desc.enabled, types.FunctionType): - return self.desc.enabled(self.node) + 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): From 7b1a2aac0b99e063a99d890f78b1487a41840eb7 Mon Sep 17 00:00:00 2001 From: Fabien Castan Date: Wed, 29 Jul 2020 18:33:39 +0200 Subject: [PATCH 8/8] [nodes] CameraInit: no more params invalidation Params are only used on drag&drop and do not invalidate the node computation. Only Viewpoints and Intrinsics are now used in the invalidation. --- meshroom/nodes/aliceVision/CameraInit.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/meshroom/nodes/aliceVision/CameraInit.py b/meshroom/nodes/aliceVision/CameraInit.py index 391c80b5b1..4d72b8a999 100644 --- a/meshroom/nodes/aliceVision/CameraInit.py +++ b/meshroom/nodes/aliceVision/CameraInit.py @@ -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', @@ -173,7 +174,7 @@ class CameraInit(desc.CommandLineNode): values=['global', 'folder', 'image'], value='folder', exclusive=True, - uid=[0], + uid=[], advanced=True, ), desc.ChoiceParam( @@ -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, ), @@ -196,7 +197,7 @@ class CameraInit(desc.CommandLineNode): value='metadata', values=['metadata', 'filename'], exclusive=True, - uid=[0], + uid=[], advanced=True, ), desc.StringParam( @@ -208,7 +209,7 @@ 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', ),