[ui] Support for imageList and sequence in SequencePlayer

This commit is contained in:
Aurore LAFAURIE 2024-05-14 17:58:59 +02:00
parent 7af0997a73
commit 4590868317
3 changed files with 39 additions and 22 deletions

View file

@ -144,4 +144,4 @@ class FilepathHelper(QObject):
"""
if extension is None:
extension = ".*"
return [self.removeExtension(FilepathHelper, self.basename(FilepathHelper, f)) for f in glob.glob(os.path.join(folderPath, f"*{extension}")) if os.path.isfile(f)]
return [self.basename(FilepathHelper, f) for f in glob.glob(os.path.join(folderPath, f"*{extension}")) if os.path.isfile(f)]

View file

@ -29,6 +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}
Settings {
id: settings_SequencePlayer
@ -52,17 +53,22 @@ FloatingPane {
onIsOutputSequenceChanged: {
if (!isOutputSequence) {
frameId = 0
frameId = frameRange.min
}
}
onSortedViewIdsChanged: {
frameSlider.from = frameRange.min
frameSlider.to = frameRange.max
}
// Sequence player model:
// - current frame
// - data related to automatic sequence playing
QtObject {
id: m
property int frame: 0
property int frame: frameRange.min
property bool syncFeaturesSelected: true
property bool sync3DSelected: true
property bool playing: false
@ -76,9 +82,8 @@ FloatingPane {
onPlayingChanged: {
if (!playing) {
updateReconstructionView();
}else if(playing && (frame + 1 >= sortedViewIds.length))
{
frame = 0;
} else if (playing && (frame + 1 >= frameRange + 1)) {
frame = frameRange.min;
}
viewer.playback(playing);
}
@ -113,9 +118,9 @@ FloatingPane {
return;
}
let nextIndex = m.frame + 1;
if (nextIndex == sortedViewIds.length) {
if (nextIndex == frameRange.max + 1) {
if (m.repeat) {
m.frame = 0;
m.frame = frameRange.min;
return;
}
else {
@ -173,7 +178,7 @@ FloatingPane {
ToolTip.text: "Previous Frame"
onClicked: {
if (m.frame > 0) {
if (m.frame > frameRange.min) {
m.frame -= 1;
}
}
@ -193,7 +198,7 @@ FloatingPane {
onEditingFinished: {
// We first assign the frame to the entered text even if it is an invalid frame number. We do it for extreme cases, for example without doing it, if we are at 0, and put a negative number, m.frame would be still 0 and nothing happens but we will still see the wrong number
m.frame = parseInt(text)
m.frame = Math.min((sortedViewIds.length - 1), Math.max(0, parseInt(text)));
m.frame = Math.min(frameRange.max, Math.max(frameRange.min, parseInt(text)));
focus = false;
}
}
@ -212,7 +217,7 @@ FloatingPane {
ToolTip.text: "Next Frame"
onClicked: {
if (m.frame < sortedViewIds.length - 1) {
if (m.frame < frameRange.max) {
m.frame += 1;
}
}
@ -251,8 +256,8 @@ FloatingPane {
snapMode: Slider.SnapAlways
live: true
from: 0
to: sortedViewIds.length - 1
from: frameRange.min
to: frameRange.max
onValueChanged: {
m.frame = value;
@ -289,7 +294,7 @@ FloatingPane {
id: cacheView
model: viewer ? viewer.cachedFrames : []
property real frameLength: sortedViewIds.length > 0 ? frameSlider.width / sortedViewIds.length : 0
property real frameLength: sortedViewIds.length > 0 ? frameSlider.width / (frameRange.max-frameRange.min+1) : 0
Rectangle {
x: modelData.x * cacheView.frameLength

View file

@ -32,6 +32,7 @@ FocusScope {
readonly property alias sync3DSelected: sequencePlayer.sync3DSelected
property var sequence: []
property alias currentFrame: sequencePlayer.frameId
property alias frameRange: sequencePlayer.frameRange
QtObject {
id: m
@ -228,6 +229,7 @@ FocusScope {
function getImageFile() {
// Entry point for getting the image file URL
let attr = getAttributeByName(displayedNode, outputAttribute.name)
if (useExternal) {
return sourceExternal
}
@ -238,8 +240,8 @@ FocusScope {
return Filepath.stringToUrl(path)
}
if (_reconstruction && displayedNode && displayedNode.hasSequenceOutput) {
var path = sequence[currentFrame]
if (_reconstruction && displayedNode && displayedNode.hasSequenceOutput && (attr.desc.semantic === "imageList" || attr.desc.semantic === "sequence")) {
var path = sequence[currentFrame-frameRange.min]
return Filepath.stringToUrl(path)
}
@ -259,12 +261,19 @@ FocusScope {
// ordered by path
let objs = []
let attr = getAttributeByName(displayedNode, outputAttribute.name)
if (displayedNode && displayedNode.hasSequenceOutput) {
currentFrame = 0
if (displayedNode && displayedNode.hasSequenceOutput && (attr.desc.semantic === "imageList" || attr.desc.semantic === "sequence")) {
objs = Filepath.resolve(path_template, null)
//order by path
objs.sort()
// reset current frame to 0 if it is imageList but not sequence
if (attr.desc.semantic === "imageList")
frameRange.min = 0
frameRange.max = objs.length-1
currentFrame = 0
if (attr.desc.semantic === "sequence")
currentFrame = frameRange.min
return objs
} else {
for (let i = 0; i < _reconstruction.viewpoints.count; i++) {
@ -311,7 +320,7 @@ FocusScope {
// store attr name for output attributes that represent images
for (var i = 0; i < displayedNode.attributes.count; i++) {
var attr = displayedNode.attributes.at(i)
if (attr.isOutput && (attr.desc.semantic === "image" || attr.desc.semantic === "sequence") && attr.enabled) {
if (attr.isOutput && (attr.desc.semantic === "image" || attr.desc.semantic === "sequence" || attr.desc.semantic === "imageList") && attr.enabled) {
names.push(attr.name)
}
}
@ -481,7 +490,10 @@ FocusScope {
'cropFisheye': false,
'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() { return (root.enableSequencePlayer && !useExternal && (_reconstruction || (root.displayedNode && root.displayedNode.hasSequenceOutput))) }),
'useSequence': Qt.binding(function() {
let attr = getAttributeByName(root.displayedNode, outputAttribute.name)
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 }),
'memoryLimit': Qt.binding(function() { return sequencePlayer.settings_SequencePlayer.maxCacheMemory }),
})