Meshroom/meshroom/ui/qml/WorkspaceView.qml
Yann Lanthony 2f307c16fb [ui] Viewer3D: synchronize media list and graph hover/selection
* ease bidirectional navigation between 3D media list and graph
* use same mechanism to indicate selected/hovered elements
* remove 'frame' button (space gain + action available on double click)
2018-12-07 16:07:42 +01:00

149 lines
4.7 KiB
QML

import QtQuick 2.7
import QtQuick.Controls 2.3
import QtQuick.Controls 1.4 as Controls1 // For SplitView
import QtQuick.Layouts 1.3
import Qt.labs.platform 1.0 as Platform
import Viewer 1.0
import Viewer3D 1.0
import MaterialIcons 2.2
import Utils 1.0
/**
* WorkspaceView is an aggregation of Meshroom's main modules.
*
* It contains an ImageGallery, a 2D and a 3D viewer to manipulate and visualize reconstruction data.
*/
Item {
id: root
property variant reconstruction: _reconstruction
readonly property variant cameraInits: _reconstruction.cameraInits
property bool readOnly: false
implicitWidth: 300
implicitHeight: 400
// Load a 3D media file in the 3D viewer
function load3DMedia(filepath) {
viewer3D.load(filepath);
}
function viewAttribute(attr) {
viewer3D.view(attr);
}
Connections {
target: reconstruction
onGraphChanged: viewer3D.clear()
onSfmChanged: viewSfM()
onSfmReportChanged: viewSfM()
}
Component.onCompleted: viewSfM()
// Load reconstruction's current SfM file
function viewSfM() {
if(!reconstruction.sfm)
return;
viewAttribute(reconstruction.sfm.attribute('output'));
}
SystemPalette { id: activePalette }
Controls1.SplitView {
anchors.fill: parent
Controls1.SplitView {
orientation: Qt.Vertical
Layout.fillHeight: true
Layout.minimumWidth: imageGallery.defaultCellSize
ImageGallery {
id: imageGallery
Layout.fillHeight: true
readOnly: root.readOnly
cameraInits: root.cameraInits
cameraInit: _reconstruction.cameraInit
currentIndex: reconstruction.cameraInitIndex
onCurrentIndexChanged: reconstruction.cameraInitIndex = currentIndex
onRemoveImageRequest: reconstruction.removeAttribute(attribute)
onFilesDropped: reconstruction.handleFilesDrop(drop, augmentSfm ? null : cameraInit)
}
LiveSfmView {
visible: settings_UILayout.showLiveReconstruction
reconstruction: root.reconstruction
Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
}
}
Panel {
title: "Image Viewer"
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: 40
Viewer2D {
id: viewer2D
anchors.fill: parent
Connections {
target: imageGallery
onCurrentItemChanged: {
viewer2D.source = imageGallery.currentItemSource
viewer2D.metadata = imageGallery.currentItemMetadata
}
}
DropArea {
anchors.fill: parent
keys: ["text/uri-list"]
onDropped: {
viewer2D.source = drop.urls[0]
viewer2D.metadata = {}
}
}
Rectangle {
z: -1
anchors.fill: parent
color: Qt.darker(activePalette.base, 1.1)
}
}
}
Panel {
title: "3D Viewer"
implicitWidth: Math.round(parent.width * 0.45)
Layout.minimumWidth: 20
Layout.minimumHeight: 80
Viewer3D {
id: viewer3D
readonly property var outputAttribute: _reconstruction.endNode ? _reconstruction.endNode.attribute("outputMesh") : null
readonly property bool outputReady: outputAttribute && _reconstruction.endNode.globalStatus === "SUCCESS"
readonly property int outputMediaIndex: library.find(outputAttribute)
anchors.fill: parent
inspector.uigraph: reconstruction
DropArea {
anchors.fill: parent
keys: ["text/uri-list"]
onDropped: {
drop.urls.forEach(function(url){ load3DMedia(url); });
}
}
}
// Load reconstructed model
Button {
text: "Load Model"
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
anchors.horizontalCenter: parent.horizontalCenter
visible: viewer3D.outputReady && viewer3D.outputMediaIndex == -1
onClicked: viewAttribute(_reconstruction.endNode.attribute("outputMesh"))
}
}
}
}