From b5c985b3fb4e41a104f77d589759032a7ca61c85 Mon Sep 17 00:00:00 2001 From: Yann Lanthony Date: Mon, 7 Jan 2019 15:25:06 +0100 Subject: [PATCH] [ui] GraphEditor: solo 3D media with Double Click + Control modifier * allow to solo a 3D media from the GraphEditor by double clicking on a node or an attribute with the Control modifier pressed * consistent with Viewer3D.MediaLibrary behavior (solo on Ctrl+Click on visibility button) * handle supported file extensions in Viewer3DSettings --- .../ui/qml/GraphEditor/AttributeEditor.qml | 4 +-- .../qml/GraphEditor/AttributeItemDelegate.qml | 4 +-- meshroom/ui/qml/GraphEditor/GraphEditor.qml | 4 +-- meshroom/ui/qml/GraphEditor/NodeEditor.qml | 4 +-- meshroom/ui/qml/Viewer3D/Viewer3D.qml | 15 ++++++++++- meshroom/ui/qml/Viewer3D/Viewer3DSettings.qml | 10 +++++++ meshroom/ui/qml/WorkspaceView.qml | 9 +++---- meshroom/ui/qml/main.qml | 26 ++++++++----------- 8 files changed, 46 insertions(+), 30 deletions(-) diff --git a/meshroom/ui/qml/GraphEditor/AttributeEditor.qml b/meshroom/ui/qml/GraphEditor/AttributeEditor.qml index 7b5e8998..bd7dcbbe 100644 --- a/meshroom/ui/qml/GraphEditor/AttributeEditor.qml +++ b/meshroom/ui/qml/GraphEditor/AttributeEditor.qml @@ -15,7 +15,7 @@ ListView { property int labelWidth: 180 signal upgradeRequest() - signal attributeDoubleClicked(var attribute) + signal attributeDoubleClicked(var mouse, var attribute) implicitHeight: contentHeight @@ -40,7 +40,7 @@ ListView { readOnly: root.readOnly labelWidth: root.labelWidth attribute: object - onDoubleClicked: root.attributeDoubleClicked(attr) + onDoubleClicked: root.attributeDoubleClicked(mouse, attr) } } } diff --git a/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml b/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml index fc447345..795bd59d 100644 --- a/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml +++ b/meshroom/ui/qml/GraphEditor/AttributeItemDelegate.qml @@ -18,7 +18,7 @@ RowLayout { readonly property bool editable: !attribute.isOutput && !attribute.isLink && !readOnly - signal doubleClicked(var attr) + signal doubleClicked(var mouse, var attr) spacing: 2 @@ -62,7 +62,7 @@ RowLayout { anchors.fill: parent hoverEnabled: true acceptedButtons: Qt.AllButtons - onDoubleClicked: root.doubleClicked(root.attribute) + onDoubleClicked: root.doubleClicked(mouse, root.attribute) property Component menuComp: Menu { id: paramMenu diff --git a/meshroom/ui/qml/GraphEditor/GraphEditor.qml b/meshroom/ui/qml/GraphEditor/GraphEditor.qml index e8cd12bd..83e4a0c9 100755 --- a/meshroom/ui/qml/GraphEditor/GraphEditor.qml +++ b/meshroom/ui/qml/GraphEditor/GraphEditor.qml @@ -21,7 +21,7 @@ Item { // signals signal workspaceMoved() signal workspaceClicked() - signal nodeDoubleClicked(var node) + signal nodeDoubleClicked(var mouse, var node) // trigger initial fit() after initialization // (ensure GraphEditor has its final size) @@ -409,7 +409,7 @@ Item { } } - onDoubleClicked: root.nodeDoubleClicked(node) + onDoubleClicked: root.nodeDoubleClicked(mouse, node) onMoved: uigraph.moveNode(node, position) diff --git a/meshroom/ui/qml/GraphEditor/NodeEditor.qml b/meshroom/ui/qml/GraphEditor/NodeEditor.qml index dd099905..5cb63f86 100644 --- a/meshroom/ui/qml/GraphEditor/NodeEditor.qml +++ b/meshroom/ui/qml/GraphEditor/NodeEditor.qml @@ -16,7 +16,7 @@ Panel { property bool readOnly: false property bool isCompatibilityNode: node && node.compatibilityIssue !== undefined - signal attributeDoubleClicked(var attribute) + signal attributeDoubleClicked(var mouse, var attribute) signal upgradeRequest() title: "Node" + (node !== null ? " - " + node.label + "" : "") @@ -116,7 +116,7 @@ Panel { Layout.fillWidth: true attributes: root.node.attributes readOnly: root.readOnly || root.isCompatibilityNode - onAttributeDoubleClicked: root.attributeDoubleClicked(attribute) + onAttributeDoubleClicked: root.attributeDoubleClicked(mouse, attribute) onUpgradeRequest: root.upgradeRequest() } diff --git a/meshroom/ui/qml/Viewer3D/Viewer3D.qml b/meshroom/ui/qml/Viewer3D/Viewer3D.qml index eca8a239..e9cf67f0 100644 --- a/meshroom/ui/qml/Viewer3D/Viewer3D.qml +++ b/meshroom/ui/qml/Viewer3D/Viewer3D.qml @@ -37,8 +37,21 @@ FocusScope { mediaLibrary.load(filepath); } + /// View 'attribute' in the 3D Viewer. Media will be loaded if needed. + /// Returns whether the attribute can be visualized (matching type and extension). function view(attribute) { - mediaLibrary.view(attribute) + if( attribute.desc.type === "File" + && Viewer3DSettings.supportedExtensions.indexOf(Filepath.extension(attribute.value)) > - 1 ) + { + mediaLibrary.view(attribute); + return true; + } + return false; + } + + /// Solo (i.e display only) the given attribute. + function solo(attribute) { + mediaLibrary.solo(mediaLibrary.find(attribute)); } function clear() { diff --git a/meshroom/ui/qml/Viewer3D/Viewer3DSettings.qml b/meshroom/ui/qml/Viewer3D/Viewer3DSettings.qml index 202b6c21..338024c7 100644 --- a/meshroom/ui/qml/Viewer3D/Viewer3DSettings.qml +++ b/meshroom/ui/qml/Viewer3D/Viewer3DSettings.qml @@ -11,6 +11,16 @@ Item { readonly property Component depthMapLoaderComp: Qt.createComponent("DepthMapLoader.qml") readonly property bool supportDepthMap: depthMapLoaderComp.status == Component.Ready + // supported 3D files extensions + readonly property var supportedExtensions: { + var exts = ['.obj']; + if(supportAlembic) + exts.push('.abc'); + if(supportDepthMap) + exts.push('.exr'); + return exts; + } + // Available render modes readonly property var renderModes: [ // Can't use ListModel because of MaterialIcons expressions {"name": "Solid", "icon": MaterialIcons.crop_din }, diff --git a/meshroom/ui/qml/WorkspaceView.qml b/meshroom/ui/qml/WorkspaceView.qml index 661b15e0..b62d0e10 100644 --- a/meshroom/ui/qml/WorkspaceView.qml +++ b/meshroom/ui/qml/WorkspaceView.qml @@ -21,6 +21,7 @@ Item { property variant reconstruction: _reconstruction readonly property variant cameraInits: _reconstruction.cameraInits property bool readOnly: false + readonly property Viewer3D viewer3D: viewer3D implicitWidth: 300 @@ -32,10 +33,6 @@ Item { viewer3D.load(filepath); } - function viewAttribute(attr) { - viewer3D.view(attr); - } - Connections { target: reconstruction onGraphChanged: viewer3D.clear() @@ -48,7 +45,7 @@ Item { function viewSfM() { if(!reconstruction.sfm) return; - viewAttribute(reconstruction.sfm.attribute('output')); + viewer3D.view(reconstruction.sfm.attribute('output')); } SystemPalette { id: activePalette } @@ -144,7 +141,7 @@ Item { anchors.bottomMargin: 10 anchors.horizontalCenter: parent.horizontalCenter visible: outputReady && outputMediaIndex == -1 - onClicked: viewAttribute(_reconstruction.endNode.attribute("outputMesh")) + onClicked: viewer3D.view(_reconstruction.endNode.attribute("outputMesh")) } } } diff --git a/meshroom/ui/qml/main.qml b/meshroom/ui/qml/main.qml index 690ce7eb..2bec9d19 100755 --- a/meshroom/ui/qml/main.qml +++ b/meshroom/ui/qml/main.qml @@ -31,8 +31,6 @@ ApplicationWindow { return t } - // supported 3D files extensions - readonly property var _3dFileExtensions: ['.obj', '.abc'] onClosing: { // make sure document is saved before exiting application close.accepted = false @@ -505,6 +503,14 @@ ApplicationWindow { Layout.minimumHeight: 50 reconstruction: _reconstruction readOnly: _reconstruction.computing + + function viewIn3D(attribute, mouse) { + var loaded = viewer3D.view(attribute); + // solo media if Control modifier was held + if(loaded && mouse && mouse.modifiers & Qt.ControlModifier) + viewer3D.solo(attribute); + return loaded; + } } } @@ -550,15 +556,6 @@ ApplicationWindow { } } - function displayAttribute(attr) { - if( attr.desc.type === "File" - && _3dFileExtensions.indexOf(Filepath.extension(attr.value)) > - 1 ) - { - workspaceView.viewAttribute(attr); - return true; - } - return false; - } GraphEditor { id: graphEditor @@ -571,14 +568,13 @@ ApplicationWindow { onNodeDoubleClicked: { if(node.nodeType === "StructureFromMotion") { - _reconstruction.sfm = node - return + _reconstruction.sfm = node; } for(var i=0; i < node.attributes.count; ++i) { var attr = node.attributes.at(i) if(attr.isOutput - && graphEditorPanel.displayAttribute(attr)) + && workspaceView.viewIn3D(attr, mouse)) { break; } @@ -592,7 +588,7 @@ ApplicationWindow { node: _reconstruction.selectedNode // Make NodeEditor readOnly when computing readOnly: graphLocked - onAttributeDoubleClicked: graphEditorPanel.displayAttribute(attribute) + onAttributeDoubleClicked: workspaceView.viewIn3D(attribute, mouse) onUpgradeRequest: { var n = _reconstruction.upgradeNode(node); _reconstruction.selectedNode = n;