Meshroom/meshroom/ui/qml/Viewer3D/Viewer3D.qml

281 lines
8.9 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.1
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
property alias library: mediaLibrary
property alias inspector: inspector3d
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)
// functions
function resetCameraPosition() {
mainCamera.position = defaultCamPosition;
mainCamera.upVector = defaultCamUpVector;
mainCamera.viewCenter = defaultCamViewCenter;
}
function load(filepath) {
mediaLibrary.load(filepath);
}
function view(attribute) {
mediaLibrary.view(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
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"
}
]
}
}
TrackballGizmo {
beamRadius: 4.0/root.height
alpha: cameraController.moving ? 1.0 : 0.7
enabled: Viewer3DSettings.displayGizmo
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
windowSize: Qt.size(root.width, root.height)
rotationSpeed: 10
trackballSize: 0.4
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(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.OnDemand
activeFrameGraph: RenderSurfaceSelector {
// Use the whole viewport
Viewport {
normalizedRect: Qt.rect(0.0, 0.0, 1.0, 1.0)
CameraSelector {
id: cameraSelector
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.displayLocator }
}
Grid3D { enabled: Viewer3DSettings.displayGrid }
}
}
// 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
}
}
// UI Overlay
Controls1.SplitView {
id: overlaySplitView
anchors.fill: parent
Item { Layout.fillWidth: true; Layout.minimumWidth: parent.width * 0.5 }
Inspector3D {
id: inspector3d
width: 200
Layout.minimumWidth: 5
camera: mainCamera
targetTransform: transform
mediaLibrary: mediaLibrary
}
}
// 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()
}
}
}