mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-06-06 12:51:57 +02:00
[ui] improve check if plugins are available and fix load/unload of tracks/sfmData
This commit is contained in:
parent
48e73a3772
commit
5ed9de5e4e
3 changed files with 107 additions and 40 deletions
9
meshroom/ui/qml/Viewer/TestAliceVisionPlugin.qml
Normal file
9
meshroom/ui/qml/Viewer/TestAliceVisionPlugin.qml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import AliceVision 1.0
|
||||||
|
import QtQuick 2.7
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To evaluate if the QtAliceVision plugin is available.
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
}
|
10
meshroom/ui/qml/Viewer/TestOIIOPlugin.qml
Normal file
10
meshroom/ui/qml/Viewer/TestOIIOPlugin.qml
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import DepthMapEntity 2.1
|
||||||
|
import QtQuick 2.7
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To evaluate if the QtOIIO plugin is available.
|
||||||
|
* DepthMapEntity is in the same plugin than the imageformats plugin, that we cannot check from qml.
|
||||||
|
*/
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
}
|
|
@ -14,16 +14,35 @@ FocusScope {
|
||||||
property var viewIn3D
|
property var viewIn3D
|
||||||
|
|
||||||
property Component floatViewerComp: Qt.createComponent("FloatImage.qml")
|
property Component floatViewerComp: Qt.createComponent("FloatImage.qml")
|
||||||
readonly property bool floatViewerAvailable: floatViewerComp.status === Component.Ready
|
|
||||||
property alias useFloatImageViewer: displayHDR.checked
|
property alias useFloatImageViewer: displayHDR.checked
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: aliceVisionPluginLoader
|
||||||
|
active: true
|
||||||
|
source: "TestAliceVisionPlugin.qml"
|
||||||
|
}
|
||||||
|
Loader {
|
||||||
|
id: oiioPluginLoader
|
||||||
|
active: true
|
||||||
|
source: "TestOIIOPlugin.qml"
|
||||||
|
}
|
||||||
|
readonly property bool aliceVisionPluginAvailable: aliceVisionPluginLoader.status === Component.Ready
|
||||||
|
readonly property bool oiioPluginAvailable: oiioPluginLoader.status === Component.Ready
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if(!aliceVisionPluginAvailable)
|
||||||
|
console.warn("Missing plugin qtAliceVision.")
|
||||||
|
if(!oiioPluginAvailable)
|
||||||
|
console.warn("Missing plugin qtOIIO.")
|
||||||
|
}
|
||||||
|
|
||||||
property string loadingModules: {
|
property string loadingModules: {
|
||||||
if(!imgContainer.image)
|
if(!imgContainer.image)
|
||||||
return "";
|
return "";
|
||||||
var res = "";
|
var res = "";
|
||||||
if(imgContainer.image.status === Image.Loading)
|
if(imgContainer.image.status === Image.Loading)
|
||||||
res += " Image";
|
res += " Image";
|
||||||
if(featuresViewerLoader.status === Loader.Ready)
|
if(featuresViewerLoader.status === Loader.Ready && featuresViewerLoader.item)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < featuresViewerLoader.item.count; ++i) {
|
for (var i = 0; i < featuresViewerLoader.item.count; ++i) {
|
||||||
if(featuresViewerLoader.item.itemAt(i).loadingFeatures)
|
if(featuresViewerLoader.item.itemAt(i).loadingFeatures)
|
||||||
|
@ -33,6 +52,11 @@ FocusScope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(mtracksLoader.status === Loader.Ready)
|
||||||
|
{
|
||||||
|
if(mtracksLoader.item.status === MTracks.Loading)
|
||||||
|
res += " Tracks";
|
||||||
|
}
|
||||||
if(msfmDataLoader.status === Loader.Ready)
|
if(msfmDataLoader.status === Loader.Ready)
|
||||||
{
|
{
|
||||||
if(msfmDataLoader.item.status === MSfMData.Loading)
|
if(msfmDataLoader.item.status === MSfMData.Loading)
|
||||||
|
@ -40,11 +64,6 @@ FocusScope {
|
||||||
res += " SfMData";
|
res += " SfMData";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(mtracksLoader.status === Loader.Ready)
|
|
||||||
{
|
|
||||||
if(mtracksLoader.item.status === MTracks.Loading)
|
|
||||||
res += " Tracks";
|
|
||||||
}
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,7 +198,7 @@ FocusScope {
|
||||||
// qtAliceVision Image Viewer
|
// qtAliceVision Image Viewer
|
||||||
Loader {
|
Loader {
|
||||||
id: floatImageViewerLoader
|
id: floatImageViewerLoader
|
||||||
active: root.useFloatImageViewer
|
active: root.aliceVisionPluginAvailable && root.useFloatImageViewer
|
||||||
visible: (floatImageViewerLoader.status === Loader.Ready)
|
visible: (floatImageViewerLoader.status === Loader.Ready)
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|
||||||
|
@ -204,7 +223,7 @@ FocusScope {
|
||||||
// Simple QML Image Viewer (using Qt or qtOIIO to load images)
|
// Simple QML Image Viewer (using Qt or qtOIIO to load images)
|
||||||
Loader {
|
Loader {
|
||||||
id: qtImageViewerLoader
|
id: qtImageViewerLoader
|
||||||
active: (!root.useFloatImageViewer) || (floatImageViewerLoader.status === Loader.Error)
|
active: !floatImageViewerLoader.active
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
sourceComponent: Image {
|
sourceComponent: Image {
|
||||||
id: qtImageViewer
|
id: qtImageViewer
|
||||||
|
@ -354,9 +373,9 @@ FocusScope {
|
||||||
// show which depthmap node is active
|
// show which depthmap node is active
|
||||||
Label {
|
Label {
|
||||||
id: depthMapNodeName
|
id: depthMapNodeName
|
||||||
property var activeNode: _reconstruction.activeNodes.get("allDepthMap").node
|
property var activeNode: root.oiioPluginAvailable ? _reconstruction.activeNodes.get("allDepthMap").node : null
|
||||||
visible: (activeNode != undefined) && (imageType.type != "image")
|
visible: (imageType.type != "image") && activeNode
|
||||||
text: (activeNode != undefined ? activeNode.label : "")
|
text: activeNode ? activeNode.label : ""
|
||||||
font.pointSize: 8
|
font.pointSize: 8
|
||||||
|
|
||||||
horizontalAlignment: TextInput.AlignLeft
|
horizontalAlignment: TextInput.AlignLeft
|
||||||
|
@ -387,77 +406,105 @@ FocusScope {
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: msfmDataLoader
|
id: msfmDataLoader
|
||||||
// active: _reconstruction.sfm && _reconstruction.sfm.isComputed
|
|
||||||
|
|
||||||
property bool isUsed: displayFeatures.checked || displaySfmStatsView.checked || displaySfmDataGlobalStats.checked
|
property bool isUsed: displayFeatures.checked || displaySfmStatsView.checked || displaySfmDataGlobalStats.checked
|
||||||
property var activeNode: _reconstruction.sfm
|
property var activeNode: root.aliceVisionPluginAvailable ? _reconstruction.activeNodes.get('sfm').node : null
|
||||||
property bool isComputed: activeNode && activeNode.isComputed
|
property bool isComputed: activeNode && activeNode.isComputed
|
||||||
|
property string filepath: Filepath.stringToUrl(isComputed ? activeNode.attribute("output").value : "")
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
// It takes time to load tracks, so keep them looaded, if we may use it again.
|
// It takes time to load tracks, so keep them looaded, if we may use it again.
|
||||||
// If we load another node, we can trash them (to eventually load the new node data).
|
// If we load another node, we can trash them (to eventually load the new node data).
|
||||||
onIsUsedChanged: {
|
onIsUsedChanged: {
|
||||||
if(!active && isUsed && isComputed)
|
if(!active && isUsed && isComputed)
|
||||||
|
{
|
||||||
active = true;
|
active = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onIsComputedChanged: {
|
onIsComputedChanged: {
|
||||||
if(!isComputed)
|
if(!isComputed)
|
||||||
|
{
|
||||||
active = false;
|
active = false;
|
||||||
if(!active && isUsed)
|
}
|
||||||
|
else if(!active && isUsed)
|
||||||
|
{
|
||||||
active = true;
|
active = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onActiveNodeChanged: {
|
onActiveNodeChanged: {
|
||||||
if(!isUsed)
|
if(!isUsed)
|
||||||
|
{
|
||||||
active = false;
|
active = false;
|
||||||
|
}
|
||||||
else if(!isComputed)
|
else if(!isComputed)
|
||||||
|
{
|
||||||
active = false;
|
active = false;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
active = true;
|
active = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
onActiveChanged: {
|
||||||
// instantiate and initialize a SfmStatsView component dynamically using Loader.setSource
|
if(active) {
|
||||||
// so it can fail safely if the c++ plugin is not available
|
// instantiate and initialize a SfmStatsView component dynamically using Loader.setSource
|
||||||
setSource("MSfMData.qml", {
|
// so it can fail safely if the c++ plugin is not available
|
||||||
'sfmDataPath': Qt.binding(function() { return Filepath.stringToUrl(isComputed ? activeNode.attribute("output").value : ""); }),
|
setSource("MSfMData.qml", {
|
||||||
})
|
'sfmDataPath': Qt.binding(function() { return filepath; }),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Force the unload (instead of using Component.onCompleted to load it once and for all) is necessary since Qt 5.14
|
||||||
|
setSource("", {})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loader {
|
Loader {
|
||||||
id: mtracksLoader
|
id: mtracksLoader
|
||||||
|
|
||||||
property bool isUsed: displayFeatures.checked || displaySfmStatsView.checked || displaySfmDataGlobalStats.checked
|
property bool isUsed: displayFeatures.checked || displaySfmStatsView.checked || displaySfmDataGlobalStats.checked
|
||||||
property var activeNode: _reconstruction.activeNodes.get('FeatureMatching').node
|
property var activeNode: root.aliceVisionPluginAvailable ? _reconstruction.activeNodes.get('FeatureMatching').node : null
|
||||||
property bool isComputed: activeNode && activeNode.isComputed
|
property bool isComputed: activeNode && activeNode.isComputed
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
// It takes time to load tracks, so keep them looaded, if we may use it again.
|
// It takes time to load tracks, so keep them looaded, if we may use it again.
|
||||||
// If we load another node, we can trash them (to eventually load the new node data).
|
// If we load another node, we can trash them (to eventually load the new node data).
|
||||||
onIsUsedChanged: {
|
onIsUsedChanged: {
|
||||||
if(!active && isUsed && isComputed)
|
if(!active && isUsed && isComputed) {
|
||||||
active = true;
|
active = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onIsComputedChanged: {
|
onIsComputedChanged: {
|
||||||
if(!isComputed)
|
if(!isComputed) {
|
||||||
active = false;
|
active = false;
|
||||||
if(!active && isUsed)
|
}
|
||||||
|
else if(!active && isUsed) {
|
||||||
active = true;
|
active = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onActiveNodeChanged: {
|
onActiveNodeChanged: {
|
||||||
if(!isUsed)
|
if(!isUsed) {
|
||||||
active = false;
|
active = false;
|
||||||
else if(!isComputed)
|
}
|
||||||
|
else if(!isComputed) {
|
||||||
active = false;
|
active = false;
|
||||||
else
|
}
|
||||||
|
else {
|
||||||
active = true;
|
active = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
onActiveChanged: {
|
||||||
// instantiate and initialize a SfmStatsView component dynamically using Loader.setSource
|
if(active) {
|
||||||
// so it can fail safely if the c++ plugin is not available
|
// instantiate and initialize a SfmStatsView component dynamically using Loader.setSource
|
||||||
setSource("MTracks.qml", {
|
// so it can fail safely if the c++ plugin is not available
|
||||||
'matchingFolder': Qt.binding(function() { return Filepath.stringToUrl(isComputed ? activeNode.attribute("output").value : ""); }),
|
setSource("MTracks.qml", {
|
||||||
})
|
'matchingFolder': Qt.binding(function() { return Filepath.stringToUrl(isComputed ? activeNode.attribute("output").value : ""); }),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Force the unload (instead of using Component.onCompleted to load it once and for all) is necessary since Qt 5.14
|
||||||
|
setSource("", {})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loader {
|
Loader {
|
||||||
|
@ -497,7 +544,7 @@ FocusScope {
|
||||||
left: parent.left
|
left: parent.left
|
||||||
margins: 2
|
margins: 2
|
||||||
}
|
}
|
||||||
active: displayFeatures.checked && featuresViewerLoader.status === Loader.Ready
|
active: root.aliceVisionPluginAvailable && displayFeatures.checked && featuresViewerLoader.status === Loader.Ready
|
||||||
|
|
||||||
sourceComponent: FeaturesInfoOverlay {
|
sourceComponent: FeaturesInfoOverlay {
|
||||||
featureExtractionNode: _reconstruction.activeNodes.get('FeatureExtraction').node
|
featureExtractionNode: _reconstruction.activeNodes.get('FeatureExtraction').node
|
||||||
|
@ -555,7 +602,7 @@ FocusScope {
|
||||||
Layout.minimumWidth: 0
|
Layout.minimumWidth: 0
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: false
|
checked: false
|
||||||
enabled: root.floatViewerAvailable
|
enabled: root.aliceVisionPluginAvailable
|
||||||
}
|
}
|
||||||
MaterialToolButton {
|
MaterialToolButton {
|
||||||
id: displayFeatures
|
id: displayFeatures
|
||||||
|
@ -565,6 +612,7 @@ FocusScope {
|
||||||
Layout.minimumWidth: 0
|
Layout.minimumWidth: 0
|
||||||
checkable: true
|
checkable: true
|
||||||
checked: false
|
checked: false
|
||||||
|
enabled: root.aliceVisionPluginAvailable
|
||||||
}
|
}
|
||||||
MaterialToolButton {
|
MaterialToolButton {
|
||||||
id: displayFisheyeCircleLoader
|
id: displayFisheyeCircleLoader
|
||||||
|
@ -591,7 +639,7 @@ FocusScope {
|
||||||
|
|
||||||
ComboBox {
|
ComboBox {
|
||||||
id: imageType
|
id: imageType
|
||||||
property var activeNode: _reconstruction.activeNodes.get('allDepthMap').node
|
property var activeNode: root.oiioPluginAvailable ? _reconstruction.activeNodes.get('allDepthMap').node : null
|
||||||
// set min size to 5 characters + one margin for the combobox
|
// set min size to 5 characters + one margin for the combobox
|
||||||
clip: true
|
clip: true
|
||||||
Layout.minimumWidth: 0
|
Layout.minimumWidth: 0
|
||||||
|
@ -606,7 +654,7 @@ FocusScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialToolButton {
|
MaterialToolButton {
|
||||||
property var activeNode: _reconstruction.activeNodes.get('allDepthMap').node
|
property var activeNode: root.oiioPluginAvailable ? _reconstruction.activeNodes.get('allDepthMap').node : null
|
||||||
enabled: activeNode
|
enabled: activeNode
|
||||||
ToolTip.text: "View Depth Map in 3D (" + (activeNode ? activeNode.label : "No DepthMap Node Selected") + ")"
|
ToolTip.text: "View Depth Map in 3D (" + (activeNode ? activeNode.label : "No DepthMap Node Selected") + ")"
|
||||||
text: MaterialIcons.input
|
text: MaterialIcons.input
|
||||||
|
@ -620,7 +668,7 @@ FocusScope {
|
||||||
|
|
||||||
MaterialToolButton {
|
MaterialToolButton {
|
||||||
id: displaySfmStatsView
|
id: displaySfmStatsView
|
||||||
property var activeNode: _reconstruction.activeNodes.get('sfm').node
|
property var activeNode: root.aliceVisionPluginAvailable ? _reconstruction.activeNodes.get('sfm').node : null
|
||||||
|
|
||||||
font.family: MaterialIcons.fontFamily
|
font.family: MaterialIcons.fontFamily
|
||||||
text: MaterialIcons.assessment
|
text: MaterialIcons.assessment
|
||||||
|
@ -644,7 +692,7 @@ FocusScope {
|
||||||
|
|
||||||
MaterialToolButton {
|
MaterialToolButton {
|
||||||
id: displaySfmDataGlobalStats
|
id: displaySfmDataGlobalStats
|
||||||
property var activeNode: _reconstruction.activeNodes.get('sfm').node
|
property var activeNode: root.aliceVisionPluginAvailable ? _reconstruction.activeNodes.get('sfm').node : null
|
||||||
|
|
||||||
font.family: MaterialIcons.fontFamily
|
font.family: MaterialIcons.fontFamily
|
||||||
text: MaterialIcons.language
|
text: MaterialIcons.language
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue