From dbcfce7c90b8b4ec99ccbbd4b51d35f0dbe682e1 Mon Sep 17 00:00:00 2001 From: Fabien Castan Date: Wed, 18 Sep 2019 18:29:13 +0200 Subject: [PATCH] [ui] WorkspaceView: open images in the 2D Viewer from the Graph/NodeEditor Double click on a node or an attribute with an image file to display it in the 2D viewer. --- meshroom/ui/components/filepath.py | 11 ++++++++ meshroom/ui/qml/WorkspaceView.qml | 2 +- meshroom/ui/qml/main.qml | 45 +++++++++++++++++++++++++++--- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/meshroom/ui/components/filepath.py b/meshroom/ui/components/filepath.py index 9e9a0475..f15d9700 100644 --- a/meshroom/ui/components/filepath.py +++ b/meshroom/ui/components/filepath.py @@ -78,3 +78,14 @@ class FilepathHelper(QObject): def normpath(self, path): """ Returns native normalized path """ return os.path.normpath(self.asStr(path)) + + @Slot(str, result=str) + @Slot(QUrl, result=str) + def globFirst(self, path): + """ Returns the first from a list of paths matching a pathname pattern. """ + import glob + fileList = glob.glob(self.asStr(path)) + fileList.sort() + if fileList: + return fileList[0] + return "" diff --git a/meshroom/ui/qml/WorkspaceView.qml b/meshroom/ui/qml/WorkspaceView.qml index e68a36d5..4a8264e1 100644 --- a/meshroom/ui/qml/WorkspaceView.qml +++ b/meshroom/ui/qml/WorkspaceView.qml @@ -23,7 +23,7 @@ Item { readonly property variant cameraInits: _reconstruction.cameraInits property bool readOnly: false readonly property Viewer3D viewer3D: viewer3D - + readonly property Viewer2D viewer2D: viewer2D implicitWidth: 300 implicitHeight: 400 diff --git a/meshroom/ui/qml/main.qml b/meshroom/ui/qml/main.qml index 48e89ebb..046112ce 100755 --- a/meshroom/ui/qml/main.qml +++ b/meshroom/ui/qml/main.qml @@ -531,6 +531,28 @@ ApplicationWindow { viewer3D.solo(attribute); return loaded; } + function viewIn2D(attribute) { + var imageExts = ['.exr', '.jpg', '.tif', '.png']; + var ext = Filepath.extension(attribute.value); + if(imageExts.indexOf(ext) == -1) + { + return false; + } + + if(attribute.value.includes('*')) + { + // For now, the viewer only supports a single image. + var firstFile = Filepath.globFirst(attribute.value) + viewer2D.source = Filepath.stringToUrl(firstFile); + } + else + { + viewer2D.source = Filepath.stringToUrl(attribute.value); + return true; + } + + return false; + } } } @@ -598,10 +620,16 @@ ApplicationWindow { for(var i=0; i < node.attributes.count; ++i) { var attr = node.attributes.at(i) - if(attr.isOutput - && workspaceView.viewIn3D(attr, mouse)) + if(attr.isOutput) { - break; + if(workspaceView.viewIn2D(attr)) + { + break; + } + if(workspaceView.viewIn3D(attr, mouse)) + { + break; + } } } } @@ -615,7 +643,16 @@ ApplicationWindow { node: _reconstruction.selectedNode // Make NodeEditor readOnly when computing readOnly: graphLocked - onAttributeDoubleClicked: workspaceView.viewIn3D(attribute, mouse) + onAttributeDoubleClicked: { + if(workspaceView.viewIn2D(attribute)) + { + return; + } + if(workspaceView.viewIn3D(attribute, mouse)) + { + return; + } + } onUpgradeRequest: { var n = _reconstruction.upgradeNode(node); _reconstruction.selectedNode = n;