diff --git a/meshroom/core/attribute.py b/meshroom/core/attribute.py index 0c9bb563c3..2e6059ff5b 100644 --- a/meshroom/core/attribute.py +++ b/meshroom/core/attribute.py @@ -196,6 +196,7 @@ def _set_value(self, value): self.requestNodeUpdate() self.valueChanged.emit() + self.validValueChanged.emit() def upgradeValue(self, exportedValue): self._set_value(exportedValue) diff --git a/meshroom/core/desc.py b/meshroom/core/desc.py index 05d9478a08..6d8cc2fa85 100644 --- a/meshroom/core/desc.py +++ b/meshroom/core/desc.py @@ -303,13 +303,15 @@ def checkValueTypes(self): class ChoiceParam(Param): """ """ - def __init__(self, name, label, description, value, values, exclusive, uid, group='allParams', joinChar=' ', advanced=False, semantic='', enabled=True): + def __init__(self, name, label, description, value, values, exclusive, uid, group='allParams', joinChar=' ', advanced=False, semantic='', + enabled=True, validValue=True, errorMessage=""): 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, semantic=semantic, enabled=enabled) + super(ChoiceParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, + semantic=semantic, enabled=enabled, validValue=validValue, errorMessage=errorMessage) def conformValue(self, val): """ Conform 'val' to the correct type and check for its validity """ diff --git a/meshroom/nodes/aliceVision/KeyframeSelection.py b/meshroom/nodes/aliceVision/KeyframeSelection.py index 6ae6fd4e02..b8270e87c3 100644 --- a/meshroom/nodes/aliceVision/KeyframeSelection.py +++ b/meshroom/nodes/aliceVision/KeyframeSelection.py @@ -3,6 +3,9 @@ import os from meshroom.core import desc +# List of supported video extensions (provided by OpenImageIO) +videoExts = [".avi", ".mov", ".mp4", ".m4a", ".m4v", ".3gp", ".3g2", ".mj2", ".m4v", ".mpg"] + class KeyframeSelectionNodeSize(desc.DynamicNodeSize): def computeSize(self, node): inputPathsSize = super(KeyframeSelectionNodeSize, self).computeSize(node) @@ -299,6 +302,8 @@ class KeyframeSelection(desc.AVCommandLineNode): value="none", values=["none", "exr", "jpg", "png"], exclusive=True, + validValue=lambda node: not (any(ext in input.value.lower() for ext in videoExts for input in node.inputPaths.value) and node.outputExtension.value == "none"), + errorMessage="A video input has been provided. The output extension should be different from 'none'.", uid=[0], ), desc.ChoiceParam(