mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-04-28 17:57:16 +02:00
[qt6][Viewer3D] MediaLibrary: Fix loading medias from attributes
Additionally harmonize comments and explicitly declare parameters for slots that need them.
This commit is contained in:
parent
2a7844480b
commit
e1ef8acadc
1 changed files with 39 additions and 45 deletions
|
@ -93,17 +93,18 @@ Entity {
|
|||
console.warn("Media Error: File " + pathStr + " does not exist.")
|
||||
return
|
||||
}
|
||||
// file already loaded, return
|
||||
// File already loaded, return
|
||||
if (m.sourceToEntity[pathStr]) {
|
||||
ensureVisible(pathStr)
|
||||
return
|
||||
}
|
||||
|
||||
// add file to the internal ListModel
|
||||
m.mediaModel.append(makeElement({
|
||||
"source": pathStr,
|
||||
"label": label ? label : Filepath.basename(pathStr),
|
||||
"section": "External"
|
||||
// Add file to the internal ListModel
|
||||
m.mediaModel.append(
|
||||
makeElement({
|
||||
"source": pathStr,
|
||||
"label": label ? label : Filepath.basename(pathStr),
|
||||
"section": "External"
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -115,16 +116,17 @@ Entity {
|
|||
|
||||
var attrLabel = attribute.isOutput ? "" : attribute.fullName.replace(attribute.node.name, "")
|
||||
var section = attribute.node.label
|
||||
// add file to the internal ListModel
|
||||
m.mediaModel.append(makeElement({
|
||||
// Add file to the internal ListModel
|
||||
m.mediaModel.append(
|
||||
makeElement({
|
||||
"label": section + attrLabel,
|
||||
"section": section,
|
||||
"attribute": attribute,
|
||||
"attribute": attribute
|
||||
}))
|
||||
}
|
||||
|
||||
function remove(index) {
|
||||
// remove corresponding entry from model
|
||||
// Remove corresponding entry from model
|
||||
m.mediaModel.remove(index)
|
||||
}
|
||||
|
||||
|
@ -189,7 +191,7 @@ Entity {
|
|||
MediaLoader {
|
||||
id: mediaLoader
|
||||
|
||||
// whether MediaLoader has been fully instantiated by the NodeInstantiator
|
||||
// Whether MediaLoader has been fully instantiated by the NodeInstantiator
|
||||
property bool fullyInstantiated: false
|
||||
|
||||
// explicitly store some attached model properties for outside use and ease binding
|
||||
|
@ -198,23 +200,23 @@ Entity {
|
|||
readonly property var modelSource: attribute || model.source
|
||||
readonly property bool visible: model.visible
|
||||
|
||||
// multi-step binding to ensure MediaLoader source is properly
|
||||
// Multi-step binding to ensure MediaLoader source is properly
|
||||
// updated when needed, whether raw source is valid or not
|
||||
|
||||
// raw source path
|
||||
// Raw source path
|
||||
property string rawSource: attribute ? attribute.value : model.source
|
||||
// whether dependencies are statified (applies for output/connected input attributes only)
|
||||
// Whether dependencies are statified (applies for output/connected input attributes only)
|
||||
readonly property bool dependencyReady: {
|
||||
if (attribute) {
|
||||
const rootAttribute = attribute.isLink ? attribute.rootLinkParam : attribute
|
||||
if (rootAttribute.isOutput)
|
||||
return rootAttribute.node.globalStatus === "SUCCESS"
|
||||
}
|
||||
return true // is an input param without link (so no dependency) or an external file
|
||||
return true // Is an input param without link (so no dependency) or an external file
|
||||
}
|
||||
// source based on raw source + dependency status
|
||||
// Source based on raw source + dependency status
|
||||
property string currentSource: dependencyReady ? rawSource : ""
|
||||
// source based on currentSource + "requested" property
|
||||
// Source based on currentSource + "requested" property
|
||||
property string finalSource: model.requested ? currentSource : ""
|
||||
|
||||
// To use only if we want to draw the input source and not the current node output (Warning: to use with caution)
|
||||
|
@ -229,14 +231,6 @@ Entity {
|
|||
renderMode: root.renderMode
|
||||
enabled: visible
|
||||
|
||||
// QObject.destroyed signal is not accessible
|
||||
// Use the object as NodeInstantiator model to be notified of its deletion
|
||||
NodeInstantiator {
|
||||
model: attribute
|
||||
delegate: Entity { objectName: "DestructionWatcher [" + model.toString() + "]" }
|
||||
onObjectRemoved: remove(index)
|
||||
}
|
||||
|
||||
property bool alive: attribute ? attribute.node.alive : false
|
||||
onAliveChanged: {
|
||||
if (!alive && index >= 0)
|
||||
|
@ -245,19 +239,19 @@ Entity {
|
|||
|
||||
// 'visible' property drives media loading request
|
||||
onVisibleChanged: {
|
||||
// always request media loading if visible
|
||||
// Always request media loading if visible
|
||||
if (model.visible)
|
||||
model.requested = true
|
||||
// only cancel loading request if media is not valid
|
||||
// Only cancel loading request if media is not valid
|
||||
// (a media won't be unloaded if already loaded, only hidden)
|
||||
else if (!model.valid)
|
||||
model.requested = false
|
||||
}
|
||||
|
||||
function updateCacheAndModel(forceRequest) {
|
||||
// don't cache explicitly unloaded media
|
||||
// Don't cache explicitly unloaded media
|
||||
if (model.requested && object && dependencyReady) {
|
||||
// cache current object
|
||||
// Cache current object
|
||||
if (cache.add(Filepath.urlToString(mediaLoader.source), object))
|
||||
object = null
|
||||
}
|
||||
|
@ -265,21 +259,21 @@ Entity {
|
|||
}
|
||||
|
||||
function updateModel(forceRequest) {
|
||||
// update model's source path if input is an attribute
|
||||
// Update model's source path if input is an attribute
|
||||
if (attribute) {
|
||||
model.source = rawSource
|
||||
}
|
||||
// auto-restore entity if raw source is in cache
|
||||
// Auto-restore entity if raw source is in cache
|
||||
model.requested = forceRequest || (!model.valid && model.requested) || cache.contains(rawSource)
|
||||
model.valid = Filepath.exists(rawSource) && dependencyReady
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
// keep 'source' -> 'entity' reference
|
||||
// Keep 'source' -> 'entity' reference
|
||||
m.sourceToEntity[modelSource] = instantiatedEntity
|
||||
// always request media loading when delegate has been created
|
||||
// Always request media loading when delegate has been created
|
||||
updateModel(true)
|
||||
// if external media failed to open, remove element from model
|
||||
// If external media failed to open, remove element from model
|
||||
if (!attribute && !object)
|
||||
remove(index)
|
||||
}
|
||||
|
@ -293,7 +287,7 @@ Entity {
|
|||
}
|
||||
|
||||
onFinalSourceChanged: {
|
||||
// update media visibility
|
||||
// Update media visibility
|
||||
// (useful if media was explicitly unloaded or hidden but loaded back from cache)
|
||||
model.visible = model.requested
|
||||
|
||||
|
@ -301,7 +295,7 @@ Entity {
|
|||
cached = cachedObject !== undefined
|
||||
if (cached) {
|
||||
object = cachedObject
|
||||
// only change cached object parent if mediaLoader has been fully instantiated
|
||||
// Only change cached object parent if mediaLoader has been fully instantiated
|
||||
// by the NodeInstantiator; otherwise re-parenting will fail silently and the object will disappear...
|
||||
// see "onFullyInstantiatedChanged" and parent NodeInstantiator's "onObjectAdded"
|
||||
if (fullyInstantiated) {
|
||||
|
@ -310,28 +304,28 @@ Entity {
|
|||
}
|
||||
mediaLoader.source = Filepath.stringToUrl(finalSource)
|
||||
if (object) {
|
||||
// bind media info to corresponding model roles
|
||||
// Bind media info to corresponding model roles
|
||||
// (test for object validity to avoid error messages right after object has been deleted)
|
||||
var boundProperties = ["vertexCount", "faceCount", "cameraCount", "textureCount", "resectionIdCount", "resectionId", "resectionGroups"]
|
||||
boundProperties.forEach(function(prop) {
|
||||
model[prop] = Qt.binding(function() { return object ? object[prop] : 0 })
|
||||
})
|
||||
} else if (finalSource && status === Component.Ready) {
|
||||
// source was valid but no loader was created, remove element
|
||||
// check if component is ready to avoid removing element from the model before adding instance to the node
|
||||
// Source was valid but no loader was created, remove element
|
||||
// Check if component is ready to avoid removing element from the model before adding instance to the node
|
||||
remove(index)
|
||||
}
|
||||
}
|
||||
|
||||
onFullyInstantiatedChanged: {
|
||||
// delayed reparenting of object coming from the cache
|
||||
// Delayed reparenting of object coming from the cache
|
||||
if (object)
|
||||
object.parent = mediaLoader
|
||||
}
|
||||
|
||||
onStatusChanged: {
|
||||
model.status = status
|
||||
// remove model entry for external media that failed to load
|
||||
// Remove model entry for external media that failed to load
|
||||
if (status === SceneLoader.Error && !model.attribute)
|
||||
remove(index)
|
||||
}
|
||||
|
@ -340,7 +334,7 @@ Entity {
|
|||
ObjectPicker {
|
||||
enabled: mediaLoader.enabled && pickingEnabled
|
||||
hoverEnabled: false
|
||||
onPressed: root.pressed(pick)
|
||||
onPressed: function(pick) { root.pressed(pick) }
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -384,12 +378,12 @@ Entity {
|
|||
}
|
||||
}
|
||||
|
||||
onObjectAdded: {
|
||||
// notify object that it is now fully instantiated
|
||||
onObjectAdded: function(index, object) {
|
||||
// Notify object that it is now fully instantiated
|
||||
object.fullyInstantiated = true
|
||||
}
|
||||
|
||||
onObjectRemoved: {
|
||||
onObjectRemoved: function(index, object) {
|
||||
if (m.sourceToEntity[object.modelSource])
|
||||
delete m.sourceToEntity[object.modelSource]
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue