mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-05-02 11:46:45 +02:00
309 lines
10 KiB
QML
309 lines
10 KiB
QML
import QtQuick 2.7
|
|
import QtQuick.Controls 2.3
|
|
import QtQuick.Controls 1.4 as Controls1
|
|
import QtQuick.Layouts 1.3
|
|
import QtQml.Models 2.2
|
|
import QtQuick.Scene3D 2.0
|
|
import Qt3D.Core 2.1
|
|
import Qt3D.Render 2.1
|
|
import Qt3D.Extras 2.10
|
|
import Qt3D.Input 2.1 as Qt3DInput // to avoid clash with Controls2 Action
|
|
|
|
import MaterialIcons 2.2
|
|
|
|
import Controls 1.0
|
|
import Utils 1.0
|
|
|
|
|
|
FocusScope {
|
|
id: root
|
|
|
|
property int renderMode: 2
|
|
readonly property alias library: mediaLibrary
|
|
readonly property alias mainCamera: mainCamera
|
|
|
|
readonly property vector3d defaultCamPosition: Qt.vector3d(12.0, 10.0, -12.0)
|
|
readonly property vector3d defaultCamUpVector: Qt.vector3d(0.0, 1.0, 0.0)
|
|
readonly property vector3d defaultCamViewCenter: Qt.vector3d(0.0, 0.0, 0.0)
|
|
|
|
readonly property var viewpoint: _reconstruction.selectedViewpoint
|
|
readonly property bool doSyncViewpointCamera: Viewer3DSettings.syncViewpointCamera && (viewpoint && viewpoint.isReconstructed)
|
|
|
|
// functions
|
|
function resetCameraPosition() {
|
|
mainCamera.position = defaultCamPosition;
|
|
mainCamera.upVector = defaultCamUpVector;
|
|
mainCamera.viewCenter = defaultCamViewCenter;
|
|
}
|
|
|
|
function load(filepath) {
|
|
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) {
|
|
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() {
|
|
mediaLibrary.clear()
|
|
}
|
|
|
|
SystemPalette { id: activePalette }
|
|
|
|
|
|
Scene3D {
|
|
id: scene3D
|
|
anchors.fill: parent
|
|
cameraAspectRatioMode: Scene3D.AutomaticAspectRatio // vs. UserAspectRatio
|
|
hoverEnabled: true // if true, will trigger positionChanged events in attached MouseHandler
|
|
aspects: ["logic", "input"]
|
|
focus: true
|
|
|
|
|
|
Keys.onPressed: {
|
|
if (event.key == Qt.Key_F) {
|
|
resetCameraPosition();
|
|
}
|
|
else if(Qt.Key_1 <= event.key && event.key <= Qt.Key_3)
|
|
{
|
|
Viewer3DSettings.renderMode = event.key - Qt.Key_1;
|
|
}
|
|
else {
|
|
event.accepted = false
|
|
}
|
|
}
|
|
|
|
Entity {
|
|
id: rootEntity
|
|
|
|
Camera {
|
|
id: mainCamera
|
|
projectionType: CameraLens.PerspectiveProjection
|
|
enabled: cameraSelector.camera == mainCamera
|
|
fieldOfView: 45
|
|
nearPlane : 0.01
|
|
farPlane : 10000.0
|
|
position: defaultCamPosition
|
|
upVector: defaultCamUpVector
|
|
viewCenter: defaultCamViewCenter
|
|
aspectRatio: width/height
|
|
|
|
Behavior on viewCenter {
|
|
Vector3dAnimation { duration: 250 }
|
|
}
|
|
Behavior on position {
|
|
Vector3dAnimation { duration: 250 }
|
|
}
|
|
|
|
// Scene light, attached to the camera
|
|
Entity {
|
|
components: [
|
|
PointLight {
|
|
color: "white"
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
ViewpointCamera {
|
|
id: viewpointCamera
|
|
enabled: cameraSelector.camera === camera
|
|
viewpoint: root.viewpoint
|
|
camera.aspectRatio: width/height
|
|
}
|
|
|
|
TrackballGizmo {
|
|
beamRadius: 4.0/root.height
|
|
alpha: cameraController.moving ? 1.0 : 0.7
|
|
enabled: Viewer3DSettings.displayGizmo && cameraSelector.camera == mainCamera
|
|
xColor: Colors.red
|
|
yColor: Colors.green
|
|
zColor: Colors.blue
|
|
centerColor: Colors.sysPalette.highlight
|
|
transform: Transform {
|
|
translation: mainCamera.viewCenter
|
|
scale: 0.15 * mainCamera.viewCenter.minus(mainCamera.position).length()
|
|
}
|
|
}
|
|
|
|
DefaultCameraController {
|
|
id: cameraController
|
|
enabled: cameraSelector.camera == mainCamera
|
|
|
|
windowSize {
|
|
width: root.width
|
|
height: root.height
|
|
}
|
|
rotationSpeed: 16
|
|
trackballSize: 0.9
|
|
|
|
camera: mainCamera
|
|
focus: scene3D.activeFocus
|
|
onMousePressed: {
|
|
scene3D.forceActiveFocus()
|
|
if(mouse.button == Qt.LeftButton)
|
|
{
|
|
if(!doubleClickTimer.running)
|
|
doubleClickTimer.restart()
|
|
}
|
|
else
|
|
doubleClickTimer.stop()
|
|
}
|
|
onMouseReleased: {
|
|
if(moving)
|
|
return
|
|
if(!moved && mouse.button == Qt.RightButton)
|
|
{
|
|
contextMenu.popup()
|
|
}
|
|
}
|
|
|
|
// Manually handle double click to activate object picking
|
|
// for camera re-centering only during a short amount of time
|
|
Timer {
|
|
id: doubleClickTimer
|
|
running: false
|
|
interval: 300
|
|
}
|
|
}
|
|
|
|
components: [
|
|
RenderSettings {
|
|
pickingSettings.pickMethod: PickingSettings.PrimitivePicking // enables point/edge/triangle picking
|
|
pickingSettings.pickResultMode: PickingSettings.NearestPick
|
|
renderPolicy: RenderSettings.Always
|
|
|
|
activeFrameGraph: RenderSurfaceSelector {
|
|
// Use the whole viewport
|
|
Viewport {
|
|
normalizedRect: Qt.rect(0.0, 0.0, 1.0, 1.0)
|
|
CameraSelector {
|
|
id: cameraSelector
|
|
camera: doSyncViewpointCamera ? viewpointCamera.camera : mainCamera
|
|
FrustumCulling {
|
|
ClearBuffers {
|
|
clearColor: "transparent"
|
|
buffers : ClearBuffers.ColorDepthBuffer
|
|
RenderStateSet {
|
|
renderStates: [
|
|
PointSize {
|
|
sizeMode: Viewer3DSettings.fixedPointSize ? PointSize.Fixed : PointSize.Programmable
|
|
value: Viewer3DSettings.pointSize
|
|
},
|
|
DepthTest { depthFunction: DepthTest.Less }
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
Qt3DInput.InputSettings { }
|
|
]
|
|
|
|
MediaLibrary {
|
|
id: mediaLibrary
|
|
renderMode: Viewer3DSettings.renderMode
|
|
// Picking to set focus point (camera view center)
|
|
// Only activate it when a double click may happen or when the 'Control' key is pressed
|
|
pickingEnabled: cameraController.pickingActive || doubleClickTimer.running
|
|
|
|
components: [
|
|
Transform {
|
|
id: transform
|
|
}
|
|
]
|
|
|
|
onPressed: {
|
|
if(pick.button == Qt.LeftButton)
|
|
{
|
|
mainCamera.viewCenter = pick.worldIntersection;
|
|
}
|
|
doubleClickTimer.stop();
|
|
}
|
|
|
|
}
|
|
Locator3D { enabled: Viewer3DSettings.displayOrigin }
|
|
Grid3D { enabled: Viewer3DSettings.displayGrid }
|
|
}
|
|
}
|
|
|
|
// Image overlay when navigating reconstructed cameras
|
|
Loader {
|
|
id: imageOverlayLoader
|
|
anchors.fill: parent
|
|
|
|
active: doSyncViewpointCamera
|
|
visible: Viewer3DSettings.showViewpointImageOverlay
|
|
|
|
sourceComponent: ImageOverlay {
|
|
id: imageOverlay
|
|
source: root.viewpoint.undistortedImageSource
|
|
imageRatio: root.viewpoint.orientedImageSize.width / root.viewpoint.orientedImageSize.height
|
|
uvCenterOffset: root.viewpoint.uvCenterOffset
|
|
showFrame: Viewer3DSettings.showViewpointImageFrame
|
|
imageOpacity: Viewer3DSettings.viewpointImageOverlayOpacity
|
|
}
|
|
}
|
|
|
|
// Media loading overlay
|
|
// (Scene3D is frozen while a media is being loaded)
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
visible: mediaLibrary.loading
|
|
color: Qt.darker(Colors.sysPalette.mid, 1.2)
|
|
opacity: 0.6
|
|
BusyIndicator {
|
|
anchors.centerIn: parent
|
|
running: parent.visible
|
|
}
|
|
}
|
|
|
|
// Rendering modes
|
|
FloatingPane {
|
|
anchors.bottom: parent.bottom
|
|
padding: 4
|
|
Row {
|
|
Repeater {
|
|
model: Viewer3DSettings.renderModes
|
|
|
|
delegate: MaterialToolButton {
|
|
text: modelData["icon"]
|
|
ToolTip.text: modelData["name"] + " (" + (index+1) + ")"
|
|
font.pointSize: 11
|
|
onClicked: Viewer3DSettings.renderMode = index
|
|
checked: Viewer3DSettings.renderMode === index
|
|
checkable: !checked // hack to disabled check on toggle
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Menu
|
|
Menu {
|
|
id: contextMenu
|
|
|
|
MenuItem {
|
|
text: "Fit All"
|
|
onTriggered: mainCamera.viewAll()
|
|
}
|
|
MenuItem {
|
|
text: "Reset View"
|
|
onTriggered: resetCameraPosition()
|
|
}
|
|
}
|
|
}
|