Meshroom/meshroom/ui/qml/WorkspaceView.qml

272 lines
10 KiB
QML

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Controls 1.0
import MaterialIcons 2.2
import ImageGallery 1.0
import Viewer 1.0
import Viewer3D 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 ? _reconstruction.cameraInits : null
property bool readOnly: false
property alias panel3dViewer: panel3dViewerLoader.item
readonly property Viewer2D viewer2D: viewer2D
readonly property alias imageGallery: imageGallery
// Use settings instead of visible property as property changes are not propagated
visible: settingsUILayout.showImageGallery || settingsUILayout.showImageViewer || settingsUILayout.showViewer3D || settingsUILayout.showLiveReconstruction
// Load a 3D media file in the 3D viewer
function load3DMedia(filepath, label = undefined) {
if (panel3dViewerLoader.active) {
panel3dViewerLoader.item.viewer3D.load(filepath, label)
}
}
Connections {
target: reconstruction
function onGraphChanged() {
if (panel3dViewerLoader.active) {
panel3dViewerLoader.item.viewer3D.clear()
}
}
function onSfmChanged() { viewSfM() }
function onSfmReportChanged() { viewSfM() }
}
Component.onCompleted: viewSfM()
// Load reconstruction's current SfM file
function viewSfM() {
var activeNode = _reconstruction.activeNodes ? _reconstruction.activeNodes.get('sfm').node : null
if (!activeNode)
return
if (panel3dViewerLoader.active) {
panel3dViewerLoader.item.viewer3D.view(activeNode.attribute('output'))
}
}
SystemPalette { id: activePalette }
MSplitView {
id: mainSplitView
anchors.fill: parent
orientation: Qt.Horizontal
MSplitView {
id: leftSplitView
visible: settingsUILayout.showImageGallery || settingsUILayout.showLiveReconstruction
orientation: Qt.Vertical
SplitView.preferredWidth: imageGallery.defaultCellSize * 2 + 20
SplitView.minimumWidth: imageGallery.defaultCellSize
ImageGallery {
id: imageGallery
visible: settingsUILayout.showImageGallery
SplitView.fillHeight: true
readOnly: root.readOnly
cameraInits: root.cameraInits
cameraInit: reconstruction ? reconstruction.cameraInit : null
tempCameraInit: reconstruction ? reconstruction.tempCameraInit : null
cameraInitIndex: reconstruction ? reconstruction.cameraInitIndex : -1
onRemoveImageRequest: function(attribute) { reconstruction.removeImage(attribute) }
onAllViewpointsCleared: reconstruction.selectedViewId = "-1"
onFilesDropped: function(drop, augmentSfm) {
if (drop["meshroomScenes"].length == 1) {
ensureSaved(function() {
if (reconstruction.handleFilesUrl(drop, augmentSfm ? null : cameraInit)) {
MeshroomApp.addRecentProjectFile(drop["meshroomScenes"][0])
}
})
} else {
reconstruction.handleFilesUrl(drop, augmentSfm ? null : cameraInit)
}
}
}
LiveSfmView {
id: liveSfmView
visible: settingsUILayout.showLiveReconstruction
reconstruction: root.reconstruction
SplitView.preferredHeight: childrenRect.height
}
}
Panel {
id: imageViewer
title: "Image Viewer"
visible: settingsUILayout.showImageViewer
implicitWidth: Math.round(parent.width * 0.35)
SplitView.fillWidth: true
SplitView.minimumWidth: 50
loading: viewer2D.loadingModules.length > 0
loadingText: loading ? "Loading " + viewer2D.loadingModules : ""
headerBar: RowLayout {
MaterialToolButton {
text: MaterialIcons.more_vert
font.pointSize: 11
padding: 2
checkable: true
checked: imageViewerMenu.visible
onClicked: imageViewerMenu.open()
Menu {
id: imageViewerMenu
y: parent.height
x: -width + parent.width
Action {
id: displayImageToolBarAction
text: "Display HDR Toolbar"
checkable: true
checked: true
enabled: viewer2D.useFloatImageViewer
}
Action {
id: displayLensDistortionToolBarAction
text: "Display Lens Distortion Toolbar"
checkable: true
checked: true
enabled: viewer2D.useLensDistortionViewer
}
Action {
id: displayPanoramaToolBarAction
text: "Display Panorama Toolbar"
checkable: true
checked: true
enabled: viewer2D.usePanoramaViewer
}
Action {
id: displayImagePathAction
text: "Display Image Path"
checkable: true
checked: true && !viewer2D.usePanoramaViewer
}
Action {
id: enable8bitViewerAction
text: "Enable 8-bit Viewer"
checkable: true
checked: MeshroomApp.default8bitViewerEnabled
}
Action {
id: enableSequencePlayerAction
text: "Enable Sequence Player"
checkable: true
checked: MeshroomApp.defaultSequencePlayerEnabled
}
}
}
}
Viewer2D {
id: viewer2D
anchors.fill: parent
viewIn3D: root.load3DMedia
DropArea {
anchors.fill: parent
keys: ["text/uri-list"]
onDropped: function(drop) {
viewer2D.loadExternal(drop.urls[0]);
}
}
Rectangle {
z: -1
anchors.fill: parent
color: Qt.darker(activePalette.base, 1.1)
}
}
}
Item {
id: viewer3DContainer
visible: settingsUILayout.showViewer3D
Layout.minimumWidth: 20
Layout.minimumHeight: 80
Layout.fillHeight: true
implicitWidth: Math.round(parent.width * 0.45)
Loader {
id: panel3dViewerLoader
active: settingsUILayout.showViewer3D
visible: active
anchors.fill: parent
sourceComponent: panel3dViewerComponent
}
}
Component {
id: panel3dViewerComponent
Panel {
id: panel3dViewer
title: "3D Viewer"
property alias viewer3D: c_viewer3D
MSplitView {
id: c_viewer3DSplitView
anchors.fill: parent
orientation: Qt.Horizontal
Viewer3D {
id: c_viewer3D
SplitView.fillWidth: true
SplitView.minimumWidth: 50
DropArea {
anchors.fill: parent
keys: ["text/uri-list"]
onDropped: function(drop) {
drop.urls.forEach(function(url) {
load3DMedia(url)
})
}
}
Connections {
target: viewer2D
function onSync3DSelectedChanged() {
Viewer3DSettings.syncWithPickedViewId = viewer2D.sync3DSelected
}
}
// Load reconstructed model
Button {
readonly property var outputAttribute: _reconstruction && _reconstruction.texturing ? _reconstruction.texturing.attribute("outputMesh") : null
readonly property bool outputReady: outputAttribute && _reconstruction.texturing.globalStatus === "SUCCESS"
readonly property int outputMediaIndex: c_viewer3D.library.find(outputAttribute)
text: "Load Model"
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
anchors.horizontalCenter: parent.horizontalCenter
visible: outputReady && outputMediaIndex == -1
onClicked: viewer3D.view(_reconstruction.texturing.attribute("outputMesh"))
}
}
// Inspector Panel
Inspector3D {
id: inspector3d
SplitView.preferredWidth: 220
SplitView.minimumWidth: 100
mediaLibrary: c_viewer3D.library
camera: c_viewer3D.mainCamera
uigraph: reconstruction
onNodeActivated: _reconstruction.setActiveNode(node)
}
}
}
}
}
}