From 1168ccaacbd079e0f841cb6ada535303447e91a5 Mon Sep 17 00:00:00 2001 From: Aurore LAFAURIE Date: Tue, 21 May 2024 17:20:24 +0200 Subject: [PATCH] [ui] Resolve Sequence and ImageList on Python side --- meshroom/ui/components/filepath.py | 25 ++++++++++++++++++- meshroom/ui/qml/Viewer/SequencePlayer.qml | 2 +- meshroom/ui/qml/Viewer/Viewer2D.qml | 30 ++++++++++++++++------- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/meshroom/ui/components/filepath.py b/meshroom/ui/components/filepath.py index 1512c73f..524afddb 100644 --- a/meshroom/ui/components/filepath.py +++ b/meshroom/ui/components/filepath.py @@ -5,6 +5,7 @@ from PySide2.QtCore import QObject, Slot import os import glob +import re class FilepathHelper(QObject): @@ -144,4 +145,26 @@ class FilepathHelper(QObject): """ if extension is None: extension = ".*" - return [self.basename(FilepathHelper, f) for f in glob.glob(os.path.join(folderPath, f"*{extension}")) if os.path.isfile(f)] + return [self.basename(f) for f in glob.glob(os.path.join(folderPath, f"*{extension}")) if os.path.isfile(f)] + + @Slot(str, result="QVariantList") + def resolveSequence(self, path): + """ + Get id of each file in the sequence. + """ + replacements = self.getFilenamesFromFolder(self.dirname(path), self.extension(path)) + + ids = [] + for i in replacements: + # convert basename to regex + splitBefore = self.basename(path).split("(") + splitAfter = splitBefore[1].split(")") + id = re.search("["+splitBefore[0]+"]("+splitAfter[0]+")["+splitAfter[1]+"]", i) + if id: + # put id in replacements as key of replacements[i] + ids.append(id[1]) + + ids.sort() + + resolved = [path.replace(self.basename(path), replacement) for replacement in replacements] + return ids, resolved diff --git a/meshroom/ui/qml/Viewer/SequencePlayer.qml b/meshroom/ui/qml/Viewer/SequencePlayer.qml index 111abb57..234f90b6 100644 --- a/meshroom/ui/qml/Viewer/SequencePlayer.qml +++ b/meshroom/ui/qml/Viewer/SequencePlayer.qml @@ -29,7 +29,7 @@ FloatingPane { property bool loading: fetchButton.checked || m.playing property alias settings_SequencePlayer: settings_SequencePlayer property alias frameId: m.frame - property var frameRange: {"min" : 0, "max" : sortedViewIds.length - 1} + property var frameRange: {"min" : 0, "max" : 0} Settings { id: settings_SequencePlayer diff --git a/meshroom/ui/qml/Viewer/Viewer2D.qml b/meshroom/ui/qml/Viewer/Viewer2D.qml index adfa2186..88309159 100644 --- a/meshroom/ui/qml/Viewer/Viewer2D.qml +++ b/meshroom/ui/qml/Viewer/Viewer2D.qml @@ -229,7 +229,7 @@ FocusScope { function getImageFile() { // Entry point for getting the image file URL - let attr = getAttributeByName(displayedNode, outputAttribute.name) + let attr = displayedNode ? getAttributeByName(displayedNode, outputAttribute.name) : undefined if (useExternal) { return sourceExternal } @@ -261,20 +261,28 @@ FocusScope { // ordered by path let objs = [] - let attr = getAttributeByName(displayedNode, outputAttribute.name) + let attr = displayedNode ? getAttributeByName(displayedNode, outputAttribute.name) : undefined if (displayedNode && displayedNode.hasSequenceOutput && (attr.desc.semantic === "imageList" || attr.desc.semantic === "sequence")) { - objs = Filepath.resolve(path_template, null) + let sequence = Filepath.resolveSequence(path_template) + let ids = sequence[0] + let resolved = sequence[1] + //order by path - objs.sort() + resolved.sort() // reset current frame to 0 if it is imageList but not sequence - if (attr.desc.semantic === "imageList") + if (attr.desc.semantic === "imageList") { frameRange.min = 0 - frameRange.max = objs.length-1 + frameRange.max = resolved.length-1 currentFrame = 0 - if (attr.desc.semantic === "sequence") + } + + if (attr.desc.semantic === "sequence") { + frameRange.min = ids[0] + frameRange.max = ids[ids.length-1] currentFrame = frameRange.min - return objs + } + return resolved } else { for (let i = 0; i < _reconstruction.viewpoints.count; i++) { objs.push(_reconstruction.viewpoints.at(i)) @@ -285,6 +293,10 @@ FocusScope { seq.push(Filepath.resolve(path_template, objs[i])) } + frameRange.min = 0 + frameRange.max = seq.length-1 + currentFrame = 0 + return seq } } @@ -491,7 +503,7 @@ FocusScope { 'sequence': Qt.binding(function() { return ((root.enableSequencePlayer && (_reconstruction || (root.displayedNode && root.displayedNode.hasSequenceOutput))) ? getSequence() : []) }), 'targetSize': Qt.binding(function() { return floatImageViewerLoader.targetSize }), 'useSequence': Qt.binding(function() { - let attr = getAttributeByName(root.displayedNode, outputAttribute.name) + let attr = root.displayedNode ? getAttributeByName(root.displayedNode, outputAttribute.name) : undefined return (root.enableSequencePlayer && !useExternal && (_reconstruction || (root.displayedNode && root.displayedNode.hasSequenceOutput)) && (attr.desc.semantic === "imageList" || attr.desc.semantic === "sequence")) }), 'fetchingSequence': Qt.binding(function() { return sequencePlayer.loading }),