mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-04-30 10:47:34 +02:00
[ui] Viewer2D: notion of feature/match provider nodes for features viewer
This commit is contained in:
parent
8d68f17410
commit
2bf1a5f809
3 changed files with 70 additions and 29 deletions
|
@ -22,6 +22,11 @@ FloatingPane {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
// Header
|
// Header
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
// Node used to read features
|
||||||
|
Label {
|
||||||
|
text: _reconstruction ? _reconstruction.activeNodes.get("featureProvider").node.label : ""
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
// Settings menu
|
// Settings menu
|
||||||
Loader {
|
Loader {
|
||||||
active: root.pluginStatus === Loader.Ready
|
active: root.pluginStatus === Loader.Ready
|
||||||
|
|
|
@ -699,7 +699,12 @@ FocusScope {
|
||||||
id: mfeaturesLoader
|
id: mfeaturesLoader
|
||||||
|
|
||||||
property bool isUsed: displayFeatures.checked
|
property bool isUsed: displayFeatures.checked
|
||||||
property var activeNode: root.aliceVisionPluginAvailable && _reconstruction ? _reconstruction.activeNodes.get("FeatureExtraction").node : null
|
property var activeNode: {
|
||||||
|
if (!root.aliceVisionPluginAvailable) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return _reconstruction ? _reconstruction.activeNodes.get("featureProvider").node : null;
|
||||||
|
}
|
||||||
property bool isComputed: activeNode && activeNode.isComputed
|
property bool isComputed: activeNode && activeNode.isComputed
|
||||||
active: false
|
active: false
|
||||||
|
|
||||||
|
@ -718,8 +723,23 @@ FocusScope {
|
||||||
// instantiate and initialize a MFeatures component dynamically using Loader.setSource
|
// instantiate and initialize a MFeatures component dynamically using Loader.setSource
|
||||||
// so it can fail safely if the c++ plugin is not available
|
// so it can fail safely if the c++ plugin is not available
|
||||||
setSource("MFeatures.qml", {
|
setSource("MFeatures.qml", {
|
||||||
'describerTypes': Qt.binding(function() { return activeNode ? activeNode.attribute("describerTypes").value : {}; }),
|
'describerTypes': Qt.binding(function() {
|
||||||
'featureFolder': Qt.binding(function() { return activeNode ? Filepath.stringToUrl(activeNode.attribute("output").value) : ""; }),
|
return activeNode ? activeNode.attribute("describerTypes").value : {};
|
||||||
|
}),
|
||||||
|
'featureFolders': Qt.binding(function() {
|
||||||
|
let result = [];
|
||||||
|
if (activeNode) {
|
||||||
|
if (activeNode.nodeType == "FeatureExtraction" && isComputed) {
|
||||||
|
result.push(activeNode.attribute("output").value);
|
||||||
|
} else {
|
||||||
|
for (let i = 0; i < activeNode.attribute("featuresFolders").value.count; i++) {
|
||||||
|
let attr = activeNode.attribute("featuresFolders").value.at(i);
|
||||||
|
result.push(attr.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}),
|
||||||
'viewIds': Qt.binding(function() {
|
'viewIds': Qt.binding(function() {
|
||||||
if (_reconstruction) {
|
if (_reconstruction) {
|
||||||
let result = [];
|
let result = [];
|
||||||
|
@ -742,39 +762,33 @@ FocusScope {
|
||||||
Loader {
|
Loader {
|
||||||
id: msfmDataLoader
|
id: msfmDataLoader
|
||||||
|
|
||||||
property bool isUsed: displayFeatures.checked || displaySfmStatsView.checked || displaySfmDataGlobalStats.checked
|
property bool isUsed: displayFeatures.checked || displaySfmStatsView.checked || displaySfmDataGlobalStats.checked || displayPanoramaViewer.checked || displayLensDistortionViewer.checked
|
||||||
|| displayPanoramaViewer.checked || displayLensDistortionViewer.checked
|
|
||||||
property var activeNode: {
|
property var activeNode: {
|
||||||
if(!root.aliceVisionPluginAvailable){
|
if(!root.aliceVisionPluginAvailable){
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
// For lens distortion viewer: use all nodes creating a sfmData file
|
var nodeType = "sfm";
|
||||||
var nodeType = displayLensDistortionViewer.checked ? 'sfmData' : 'sfm'
|
if (displayLensDistortionViewer.checked) {
|
||||||
var sfmNode = _reconstruction ? _reconstruction.activeNodes.get(nodeType).node : null
|
nodeType = "sfmData";
|
||||||
|
}
|
||||||
|
var sfmNode = _reconstruction ? _reconstruction.activeNodes.get(nodeType).node : null;
|
||||||
if(sfmNode === null){
|
if(sfmNode === null){
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
if(displayPanoramaViewer.checked){
|
if(displayPanoramaViewer.checked){
|
||||||
sfmNode = _reconstruction.activeNodes.get('SfMTransform').node
|
sfmNode = _reconstruction.activeNodes.get('SfMTransform').node;
|
||||||
var previousNode = sfmNode.attribute("input").rootLinkParam.node
|
var previousNode = sfmNode.attribute("input").rootLinkParam.node;
|
||||||
return previousNode
|
return previousNode;
|
||||||
}
|
|
||||||
else{
|
|
||||||
return sfmNode
|
|
||||||
}
|
}
|
||||||
|
return sfmNode;
|
||||||
}
|
}
|
||||||
property bool isComputed: activeNode && activeNode.isComputed
|
property bool isComputed: activeNode && activeNode.isComputed
|
||||||
property string filepath: {
|
property string filepath: {
|
||||||
var sfmValue = ""
|
var sfmValue = "";
|
||||||
if(!isComputed){
|
if (isComputed && activeNode.hasAttribute("output")) {
|
||||||
return Filepath.stringToUrl(sfmValue)
|
sfmValue = activeNode.attribute("output").value;
|
||||||
}
|
|
||||||
else{
|
|
||||||
if(activeNode.hasAttribute("output")){
|
|
||||||
sfmValue = activeNode.attribute("output").value
|
|
||||||
}
|
|
||||||
return Filepath.stringToUrl(sfmValue)
|
|
||||||
}
|
}
|
||||||
|
return Filepath.stringToUrl(sfmValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
active: false
|
active: false
|
||||||
|
@ -828,11 +842,16 @@ FocusScope {
|
||||||
id: mtracksLoader
|
id: mtracksLoader
|
||||||
|
|
||||||
property bool isUsed: displayFeatures.checked || displaySfmStatsView.checked || displaySfmDataGlobalStats.checked || displayPanoramaViewer.checked
|
property bool isUsed: displayFeatures.checked || displaySfmStatsView.checked || displaySfmDataGlobalStats.checked || displayPanoramaViewer.checked
|
||||||
property var activeNode: root.aliceVisionPluginAvailable && _reconstruction ? _reconstruction.activeNodes.get('FeatureMatching').node : null
|
property var activeNode: {
|
||||||
|
if (!root.aliceVisionPluginAvailable) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return _reconstruction ? _reconstruction.activeNodes.get("matchProvider").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 loaded, 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) {
|
||||||
|
@ -864,7 +883,20 @@ FocusScope {
|
||||||
// instantiate and initialize a SfmStatsView component dynamically using Loader.setSource
|
// instantiate and initialize a SfmStatsView component dynamically using Loader.setSource
|
||||||
// so it can fail safely if the c++ plugin is not available
|
// so it can fail safely if the c++ plugin is not available
|
||||||
setSource("MTracks.qml", {
|
setSource("MTracks.qml", {
|
||||||
'matchingFolder': Qt.binding(function() { return Filepath.stringToUrl(isComputed ? activeNode.attribute("output").value : ""); }),
|
'matchingFolders': Qt.binding(function() {
|
||||||
|
let result = [];
|
||||||
|
if (activeNode) {
|
||||||
|
if (activeNode.nodeType == "FeatureMatching" && isComputed) {
|
||||||
|
result.push(activeNode.attribute("output").value);
|
||||||
|
} else {
|
||||||
|
for (let i = 0; i < activeNode.attribute("matchesFolders").value.count; i++) {
|
||||||
|
let attr = activeNode.attribute("matchesFolders").value.at(i);
|
||||||
|
result.push(attr.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
// Force the unload (instead of using Component.onCompleted to load it once and for all) is necessary since Qt 5.14
|
// Force the unload (instead of using Component.onCompleted to load it once and for all) is necessary since Qt 5.14
|
||||||
|
|
|
@ -408,6 +408,10 @@ class Reconstruction(UIGraph):
|
||||||
"SfMAlignment"],
|
"SfMAlignment"],
|
||||||
# All nodes generating depth map files
|
# All nodes generating depth map files
|
||||||
"allDepthMap": ["DepthMap", "DepthMapFilter"],
|
"allDepthMap": ["DepthMap", "DepthMapFilter"],
|
||||||
|
# Nodes that can be used to provide features folders to the UI
|
||||||
|
"featureProvider": ["FeatureExtraction", "FeatureMatching", "StructureFromMotion"],
|
||||||
|
# Nodes that can be used to provide matches folders to the UI
|
||||||
|
"matchProvider": ["FeatureMatching", "StructureFromMotion"]
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, undoStack, taskManager, defaultPipeline='', parent=None):
|
def __init__(self, undoStack, taskManager, defaultPipeline='', parent=None):
|
||||||
|
|
Loading…
Add table
Reference in a new issue