Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/alicevision/meshroom.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCandice Bentéjac <candice.bentejac@gmail.com>2022-11-10 19:58:24 +0300
committerCandice Bentéjac <candice.bentejac@gmail.com>2022-11-10 19:58:24 +0300
commit1bfc7cd08328ff90340d07919ae3245311dcb646 (patch)
tree77e71b645d445fa5ee9aee92c43b226dcc220dbc
parentd9c330eba8bbe4cb6fff830947d976e3af22bb8a (diff)
parentc4d44aa55022d36024f3799107d340b5ca695d67 (diff)
Merge branch 'develop' into dev/qt6-migrationdev/qt6-migration
-rw-r--r--bin/ion_start_meshroom.sh2
-rw-r--r--meshroom/ui/app.py5
-rw-r--r--meshroom/ui/components/scene3D.py114
-rwxr-xr-xmeshroom/ui/qml/GraphEditor/GraphEditor.qml42
-rw-r--r--meshroom/ui/qml/Viewer/PanoramaViewer.qml57
-rw-r--r--meshroom/ui/qml/Viewer/Viewer2D.qml60
-rw-r--r--meshroom/ui/qml/Viewer3D/MeshingBoundingBox.qml50
-rwxr-xr-xmeshroom/ui/qml/main.qml13
8 files changed, 282 insertions, 61 deletions
diff --git a/bin/ion_start_meshroom.sh b/bin/ion_start_meshroom.sh
index 5215e054..54de022e 100644
--- a/bin/ion_start_meshroom.sh
+++ b/bin/ion_start_meshroom.sh
@@ -1,3 +1,4 @@
+#!/bin/bash
PATH_QML=${ION_CONTAINER_ROOT}/base/qml/QtQuick
PATH_QML_TRUE=`readlink -f $PATH_QML`/../
@@ -6,6 +7,5 @@ PATH_PLUGIN_TRUE=`readlink -f $PATH_PLUGIN`/../
export QML2_IMPORT_PATH=$PATH_QML_TRUE:$QML2_IMPORT_PATH
export QT_PLUGIN_PATH=$PATH_PLUGIN_TRUE:$QT_PLUGIN_PATH
-export ALICEVISION_ROOT=${ION_CONTAINER_ROOT}/base
python ${ION_CONTAINER_ROOT}/base/meshroom/meshroom/ui
diff --git a/meshroom/ui/app.py b/meshroom/ui/app.py
index 5e06a92a..fe910a09 100644
--- a/meshroom/ui/app.py
+++ b/meshroom/ui/app.py
@@ -343,8 +343,13 @@ class MeshroomApp(QApplication):
}
]
+ def _default8bitViewerEnabled(self):
+ return bool(os.environ.get("MESHROOM_USE_8BIT_VIEWER", False))
+
+
licensesModel = Property("QVariantList", _licensesModel, constant=True)
pipelineTemplateFilesChanged = Signal()
recentProjectFilesChanged = Signal()
pipelineTemplateFiles = Property("QVariantList", _pipelineTemplateFiles, notify=pipelineTemplateFilesChanged)
recentProjectFiles = Property("QVariantList", _recentProjectFiles, notify=recentProjectFilesChanged)
+ default8bitViewerEnabled = Property(bool, _default8bitViewerEnabled, constant=True)
diff --git a/meshroom/ui/components/scene3D.py b/meshroom/ui/components/scene3D.py
index b7c04d85..ad03464e 100644
--- a/meshroom/ui/components/scene3D.py
+++ b/meshroom/ui/components/scene3D.py
@@ -1,4 +1,4 @@
-from math import acos, pi, sqrt
+from math import acos, pi, sqrt, atan2, cos, sin, asin
from PySide6.QtCore import QObject, Slot, QSize, Signal, QPointF
from PySide6.Qt3DCore import Qt3DCore
@@ -110,6 +110,101 @@ class Transformations3DHelper(QObject):
# ---------- Exposed to QML ---------- #
+ @Slot(QVector3D, QVector3D, result=QQuaternion)
+ def rotationBetweenAandB(self, A, B):
+
+ A = A/A.length()
+ B = B/B.length()
+
+ # Get rotation matrix between 2 vectors
+ v = QVector3D.crossProduct(A, B)
+ s = v.length()
+ c = QVector3D.dotProduct(A, B)
+ return QQuaternion.fromAxisAndAngle(v / s, atan2(s, c) * 180 / pi)
+
+ @Slot(QVector3D, result=QVector3D)
+ def fromEquirectangular(self, vector):
+ return QVector3D(cos(vector.x()) * sin(vector.y()), sin(vector.x()), cos(vector.x()) * cos(vector.y()))
+
+ @Slot(QVector3D, result=QVector3D)
+ def toEquirectangular(self, vector):
+ return QVector3D(asin(vector.y()), atan2(vector.x(), vector.z()), 0)
+
+ @Slot(QVector3D, QVector2D, QVector2D, result=QVector3D)
+ def updatePanorama(self, euler, ptStart, ptEnd):
+
+ delta = 1e-3
+
+ #Get initial rotation
+ qStart = QQuaternion.fromEulerAngles(euler.y(), euler.x(), euler.z())
+
+ #Convert input to points on unit sphere
+ vStart = self.fromEquirectangular(QVector3D(ptStart))
+ vStartdY = self.fromEquirectangular(QVector3D(ptStart.x(), ptStart.y() + delta, 0))
+ vEnd = self.fromEquirectangular(QVector3D(ptEnd))
+
+ qAdd = QQuaternion.rotationTo(vStart, vEnd)
+
+
+ #Get the 3D point on unit sphere which would correspond to the no rotation +X
+ vCurrent = qAdd.rotatedVector(vStartdY)
+ vIdeal = self.fromEquirectangular(QVector3D(ptEnd.x(), ptEnd.y() + delta, 0))
+
+ #project on rotation plane
+ lambdaEnd = 1 / QVector3D.dotProduct(vEnd, vCurrent)
+ lambdaIdeal = 1 / QVector3D.dotProduct(vEnd, vIdeal)
+ vPlaneCurrent = lambdaEnd * vCurrent
+ vPlaneIdeal = lambdaIdeal * vIdeal
+
+ #Get the directions
+ rotStart = (vPlaneCurrent - vEnd).normalized()
+ rotEnd = (vPlaneIdeal - vEnd).normalized()
+
+ # Get rotation matrix between 2 vectors
+ v = QVector3D.crossProduct(rotEnd, rotStart)
+ s = QVector3D.dotProduct(v, vEnd)
+ c = QVector3D.dotProduct(rotStart, rotEnd)
+ angle = atan2(s, c) * 180 / pi
+
+ qImage = QQuaternion.fromAxisAndAngle(vEnd, -angle)
+
+ return (qImage * qAdd * qStart).toEulerAngles()
+
+ @Slot(QVector3D, QVector2D, QVector2D, result=QVector3D)
+ def updatePanoramaInPlane(self, euler, ptStart, ptEnd):
+
+ delta = 1e-3
+
+ #Get initial rotation
+ qStart = QQuaternion.fromEulerAngles(euler.y(), euler.x(), euler.z())
+
+ #Convert input to points on unit sphere
+ vStart = self.fromEquirectangular(QVector3D(ptStart))
+ vEnd = self.fromEquirectangular(QVector3D(ptEnd))
+
+ #Get the 3D point on unit sphere which would correspond to the no rotation +X
+ vIdeal = self.fromEquirectangular(QVector3D(ptStart.x(), ptStart.y() + delta, 0))
+
+ #project on rotation plane
+ lambdaEnd = 1 / QVector3D.dotProduct(vStart, vEnd)
+ lambdaIdeal = 1 / QVector3D.dotProduct(vStart, vIdeal)
+ vPlaneEnd = lambdaEnd * vEnd
+ vPlaneIdeal = lambdaIdeal * vIdeal
+
+ #Get the directions
+ rotStart = (vPlaneEnd - vStart).normalized()
+ rotEnd = (vPlaneIdeal - vStart).normalized()
+
+ # Get rotation matrix between 2 vectors
+ v = QVector3D.crossProduct(rotEnd, rotStart)
+ s = QVector3D.dotProduct(v, vStart)
+ c = QVector3D.dotProduct(rotStart, rotEnd)
+ angle = atan2(s, c) * 180 / pi
+
+ qAdd = QQuaternion.fromAxisAndAngle(vStart, angle)
+
+ return (qAdd * qStart).toEulerAngles()
+
@Slot(QVector4D, Qt3DRender.QCamera, QSize, result=QVector2D)
def pointFromWorldToScreen(self, point, camera, windowSize):
""" Compute the Screen point corresponding to a World Point.
@@ -124,7 +219,7 @@ class Transformations3DHelper(QObject):
viewMatrix = camera.transform().matrix().inverted()
projectedPoint = (camera.projectionMatrix() * viewMatrix[0]).map(point)
projectedPoint2D = QVector2D(
- projectedPoint.x()/projectedPoint.w(),
+ projectedPoint.x()/projectedPoint.w(),
projectedPoint.y()/projectedPoint.w()
)
@@ -146,7 +241,7 @@ class Transformations3DHelper(QObject):
initialScaleMat (QMatrix4x4): initial scale matrix
translateVec (QVector3D): vector used for the local translation
"""
- # Compute the translation transformation matrix
+ # Compute the translation transformation matrix
translationMat = QMatrix4x4()
translationMat.translate(translateVec)
@@ -246,6 +341,19 @@ class Transformations3DHelper(QObject):
return modelMat
+ @Slot(QVector3D, result=QVector3D)
+ def convertRotationFromCV2GL(self, rotation):
+ """ Convert rotation (euler angles) from Computer Vision
+ to Computer Graphics coordinate system (like opengl).
+ """
+ M = QQuaternion.fromAxisAndAngle(QVector3D(1, 0, 0), 180.0)
+
+ quaternion = QQuaternion.fromEulerAngles(rotation)
+
+ U = M * quaternion * M
+
+ return U.toEulerAngles()
+
@Slot(QVector3D, QMatrix4x4, Qt3DRender.QCamera, QSize, result=float)
def computeScaleUnitFromModelMatrix(self, axis, modelMat, camera, windowSize):
""" Compute the length of the screen projected vector axis unit transformed by the model matrix.
diff --git a/meshroom/ui/qml/GraphEditor/GraphEditor.qml b/meshroom/ui/qml/GraphEditor/GraphEditor.qml
index 19683cda..6c105930 100755
--- a/meshroom/ui/qml/GraphEditor/GraphEditor.qml
+++ b/meshroom/ui/qml/GraphEditor/GraphEditor.qml
@@ -117,20 +117,34 @@ Item {
return mapToItem(draggable, mouseArea.width / 2, mouseArea.height / 2)
}
- Keys.onPressed: function (event) {
- if (event.key === Qt.Key_F)
- fit()
- if (event.key === Qt.Key_Delete)
- if (event.modifiers == Qt.AltModifier)
- uigraph.removeNodesFrom(uigraph.selectedNodes)
- else
- uigraph.removeNodes(uigraph.selectedNodes)
- if (event.key === Qt.Key_D)
- duplicateNode(event.modifiers == Qt.AltModifier)
- if (event.key === Qt.Key_C && event.modifiers == Qt.ControlModifier)
- copyNodes()
- if (event.key === Qt.Key_V && event.modifiers == Qt.ControlModifier)
- pasteNodes()
+ Keys.onPressed: {
+ if (event.key === Qt.Key_F) {
+ fit();
+ }
+ else if (event.key === Qt.Key_Delete) {
+ if (event.modifiers == Qt.AltModifier) {
+ uigraph.removeNodesFrom(uigraph.selectedNodes);
+ }
+ else {
+ uigraph.removeNodes(uigraph.selectedNodes);
+ }
+ }
+ else if (event.key === Qt.Key_D) {
+ duplicateNode(event.modifiers == Qt.AltModifier);
+ }
+ else if (event.key === Qt.Key_C && event.modifiers == Qt.ControlModifier) {
+ copyNodes();
+ }
+ else if (event.key === Qt.Key_V && event.modifiers == Qt.ControlModifier) {
+ pasteNodes();
+ }
+ else if (event.key == Qt.Key_Tab) {
+ event.accepted = true;
+ if (mouseArea.containsMouse) {
+ newNodeMenu.spawnPosition = mouseArea.mapToItem(draggable, mouseArea.mouseX, mouseArea.mouseY);
+ newNodeMenu.popup();
+ }
+ }
}
MouseArea {
diff --git a/meshroom/ui/qml/Viewer/PanoramaViewer.qml b/meshroom/ui/qml/Viewer/PanoramaViewer.qml
index d2439902..157eb2e3 100644
--- a/meshroom/ui/qml/Viewer/PanoramaViewer.qml
+++ b/meshroom/ui/qml/Viewer/PanoramaViewer.qml
@@ -59,6 +59,10 @@ AliceVision.PanoramaViewer {
property var xStart : 0
property var yStart : 0
+ property var previous_yaw: 0;
+ property var previous_pitch: 0;
+ property var previous_roll: 0;
+
property double yaw: 0;
property double pitch: 0;
property double roll: 0;
@@ -132,18 +136,43 @@ AliceVision.PanoramaViewer {
// Rotate Panorama
if (isRotating && isEditable) {
- var xoffset = mouse.x - lastX;
- var yoffset = mouse.y - lastY;
- lastX = mouse.x;
- lastY = mouse.y;
-
- // Update Euler Angles
- if (mouse.modifiers & Qt.AltModifier) {
- root.roll = limitAngle(root.roll + toDegrees((xoffset / width) * mouseMultiplier))
- }
- else {
- root.yaw = limitAngle(root.yaw + toDegrees((xoffset / width) * mouseMultiplier))
- root.pitch = limitPitch(root.pitch + toDegrees(-(yoffset / height) * mouseMultiplier))
+
+ var nx = Math.max(0, mouse.x)
+ var nx = Math.min(width - 1, mouse.x)
+ var ny = Math.max(0, mouse.y)
+ var ny = Math.min(height - 1, mouse.y)
+
+ var xoffset = nx - lastX;
+ var yoffset = ny - lastY;
+
+ if (xoffset != 0 || yoffset !=0)
+ {
+ var latitude_start = (yStart / height) * Math.PI - (Math.PI / 2);
+ var longitude_start = ((xStart / width) * 2 * Math.PI) - Math.PI;
+ var latitude_end = (ny / height) * Math.PI - ( Math.PI / 2);
+ var longitude_end = ((nx / width) * 2 * Math.PI) - Math.PI;
+
+ var start_pt = Qt.vector2d(latitude_start, longitude_start)
+ var end_pt = Qt.vector2d(latitude_end, longitude_end)
+
+ var previous_euler = Qt.vector3d(previous_yaw, previous_pitch, previous_roll)
+
+ if (mouse.modifiers & Qt.ControlModifier)
+ {
+ var result = Transformations3DHelper.updatePanoramaInPlane(previous_euler, start_pt, end_pt)
+ root.pitch = result.x
+ root.yaw = result.y
+ root.roll = result.z
+ }
+ else
+ {
+ var result = Transformations3DHelper.updatePanorama(previous_euler, start_pt, end_pt)
+ root.pitch = result.x
+ root.yaw = result.y
+ root.roll = result.z
+ }
+
+
}
_reconstruction.setAttribute(activeNode.attribute("manualTransform.manualRotation.x"), Math.round(root.pitch));
@@ -160,6 +189,10 @@ AliceVision.PanoramaViewer {
xStart = mouse.x;
yStart = mouse.y;
+
+ previous_yaw = yaw;
+ previous_pitch = pitch;
+ previous_roll = roll;
}
onReleased: function (mouse) {
diff --git a/meshroom/ui/qml/Viewer/Viewer2D.qml b/meshroom/ui/qml/Viewer/Viewer2D.qml
index d8d043da..7efa2e35 100644
--- a/meshroom/ui/qml/Viewer/Viewer2D.qml
+++ b/meshroom/ui/qml/Viewer/Viewer2D.qml
@@ -20,12 +20,13 @@ FocusScope {
property Component floatViewerComp: Qt.createComponent("FloatImage.qml")
property Component panoramaViewerComp: Qt.createComponent("PanoramaViewer.qml")
- property alias useFloatImageViewer: displayHDR.checked
+ property var useFloatImageViewer: displayHDR.checked
property alias useLensDistortionViewer: displayLensDistortionViewer.checked
property alias usePanoramaViewer: displayPanoramaViewer.checked
property var activeNodeFisheye: _reconstruction.activeNodes.get("PanoramaInit").node
property bool cropFisheye : activeNodeFisheye ? activeNodeFisheye.attribute("useFisheye").value : false
+ property bool enable8bitViewer: MeshroomApp.default8bitViewerEnabled
QtObject {
id: m
@@ -62,8 +63,10 @@ FocusScope {
readonly property bool oiioPluginAvailable: oiioPluginLoader.status === Component.Ready
Component.onCompleted: {
- if(!aliceVisionPluginAvailable)
+ if(!aliceVisionPluginAvailable) {
console.warn("Missing plugin qtAliceVision.")
+ displayHDR.checked = false
+ }
if(!oiioPluginAvailable)
console.warn("Missing plugin qtOIIO.")
}
@@ -96,7 +99,7 @@ FocusScope {
}
if(msfmDataLoader.status === Loader.Ready && msfmDataLoader.item)
{
- if(msfmDataLoader.item.status === MSfMData.Loading)
+ if(msfmDataLoader.item != null && msfmDataLoader.item.status === MSfMData.Loading)
{
res += " SfMData";
}
@@ -370,12 +373,35 @@ FocusScope {
active: root.aliceVisionPluginAvailable && (root.useFloatImageViewer || root.useLensDistortionViewer) && !panoramaViewerLoader.active
visible: (floatImageViewerLoader.status === Loader.Ready) && active
anchors.centerIn: parent
+ property var fittedOnce: false
+ property var previousWidth: 0
+ property var previousHeight: 0
+ onHeightChanged: {
+ /* Image size is not updated through a single signal with the floatImage viewer, unlike
+ * the simple QML image viewer: instead of updating straight away the width and height to x and
+ * y, the emitted signals look like:
+ * - width = -1, height = -1
+ * - width = x, height = -1
+ * - width = x, height = y
+ * We want to do the auto-fit on the first display of an image from the group, and then keep its
+ * scale when displaying another image from the group, so we need to know if an image in the
+ * group has already been auto-fitted. If we change the group of images (when another project is
+ * opened, for example, and the images have a different size), then another auto-fit needs to be
+ * performed */
+ if ((!fittedOnce && imgContainer.image.status == Image.Ready && imgContainer.image.height > 0) ||
+ (fittedOnce && ((width > 1 && previousWidth != width) || (height > 1 && previousHeight != height)))) {
+ fit();
+ fittedOnce = true;
+ previousWidth = width;
+ previousHeight = height;
+ }
+ }
// handle rotation/position based on available metadata
rotation: {
var orientation = m.imgMetadata ? m.imgMetadata["Orientation"] : 0
- switch(orientation) {
+ switch (orientation) {
case "6": return 90;
case "8": return -90;
default: return 0;
@@ -383,7 +409,7 @@ FocusScope {
}
onActiveChanged: {
- if(active) {
+ if (active) {
// instantiate and initialize a FeaturesViewer component dynamically using Loader.setSource
// Note: It does not work to use previously created component, so we re-create it with setSource.
// floatViewerComp.createObject(floatImageViewerLoader, {
@@ -398,7 +424,7 @@ FocusScope {
'surface.gridColor' : Qt.binding(function(){ return lensDistortionImageToolbar.color;}),
'surface.subdivisions' : Qt.binding(function(){ return root.useFloatImageViewer ? 1 : lensDistortionImageToolbar.subdivisionsValue;}),
'viewerTypeString': Qt.binding(function(){ return displayLensDistortionViewer.checked ? "distortion" : "hdr";}),
- 'surface.msfmData': Qt.binding(function() { return (msfmDataLoader.status === Loader.Ready && msfmDataLoader.item && msfmDataLoader.item.status === 2) ? msfmDataLoader.item : null; }),
+ 'surface.msfmData': Qt.binding(function() { return (msfmDataLoader.status === Loader.Ready && msfmDataLoader.item != null && msfmDataLoader.item.status === 2) ? msfmDataLoader.item : null; }),
'canBeHovered': false,
'idView': Qt.binding(function() { return _reconstruction.selectedViewId; }),
'cropFisheye': false
@@ -406,6 +432,7 @@ FocusScope {
} else {
// Force the unload (instead of using Component.onCompleted to load it once and for all) is necessary since Qt 5.14
setSource("", {})
+ fittedOnce = false
}
}
@@ -474,7 +501,6 @@ FocusScope {
}
}
-
property var image: {
if (floatImageViewerLoader.active)
floatImageViewerLoader.item
@@ -483,8 +509,8 @@ FocusScope {
else
qtImageViewerLoader.item
}
- width: image ? image.width : 1
- height: image ? image.height : 1
+ width: image ? (image.width > 0 ? image.width : 1) : 1
+ height: image ? (image.height > 0 ? image.height : 1) : 1
scale: 1.0
// FeatureViewer: display view extracted feature points
@@ -953,12 +979,14 @@ FocusScope {
padding: 0
Layout.minimumWidth: 0
checkable: true
- checked: false
+ checked: root.aliceVisionPluginAvailable
enabled: root.aliceVisionPluginAvailable
+ visible: root.enable8bitViewer
onCheckedChanged : {
- if(displayLensDistortionViewer.checked && checked){
+ if (displayLensDistortionViewer.checked && checked) {
displayLensDistortionViewer.checked = false;
}
+ root.useFloatImageViewer = !root.useFloatImageViewer
}
}
MaterialToolButton {
@@ -989,9 +1017,11 @@ FocusScope {
checked: false
enabled: activeNode && isComputed
onCheckedChanged : {
- if((displayHDR.checked || displayPanoramaViewer.checked) && checked){
+ if ((displayHDR.checked || displayPanoramaViewer.checked) && checked) {
displayHDR.checked = false;
displayPanoramaViewer.checked = false;
+ } else if (!checked) {
+ displayHDR.checked = true;
}
}
}
@@ -1021,15 +1051,15 @@ FocusScope {
checked: false
enabled: activeNode && isComputed
onCheckedChanged : {
- if(displayLensDistortionViewer.checked && checked){
+ if (displayLensDistortionViewer.checked && checked) {
displayLensDistortionViewer.checked = false;
}
- if(displayFisheyeCircleLoader.checked && checked){
+ if (displayFisheyeCircleLoader.checked && checked) {
displayFisheyeCircleLoader.checked = false;
}
}
onEnabledChanged : {
- if(!enabled){
+ if (!enabled) {
checked = false;
}
}
diff --git a/meshroom/ui/qml/Viewer3D/MeshingBoundingBox.qml b/meshroom/ui/qml/Viewer3D/MeshingBoundingBox.qml
index 92769efb..f0842f78 100644
--- a/meshroom/ui/qml/Viewer3D/MeshingBoundingBox.qml
+++ b/meshroom/ui/qml/Viewer3D/MeshingBoundingBox.qml
@@ -24,18 +24,22 @@ Entity {
// Update node meshing slider values when the gizmo has changed: translation, rotation, scale, type
transformGizmo.onGizmoChanged: {
+
+ var rotationEuler_cv = Qt.vector3d(rotation.x, rotation.y, rotation.z)
+ var rotation_gl = Transformations3DHelper.convertRotationFromCV2GL(rotationEuler_cv)
+
switch(type) {
case TransformGizmo.Type.TRANSLATION: {
_reconstruction.setAttribute(
root.currentMeshingNode.attribute("boundingBox.bboxTranslation"),
- JSON.stringify([translation.x, translation.y, translation.z])
+ JSON.stringify([translation.x, -translation.y, -translation.z])
)
break
}
case TransformGizmo.Type.ROTATION: {
_reconstruction.setAttribute(
root.currentMeshingNode.attribute("boundingBox.bboxRotation"),
- JSON.stringify([rotation.x, rotation.y, rotation.z])
+ JSON.stringify([rotation_gl.x, rotation_gl.y, rotation_gl.z])
)
break
}
@@ -50,8 +54,8 @@ Entity {
_reconstruction.setAttribute(
root.currentMeshingNode.attribute("boundingBox"),
JSON.stringify([
- [translation.x, translation.y, translation.z],
- [rotation.x, rotation.y, rotation.z],
+ [translation.x, -translation.y, -translation.z],
+ [rotation_gl.x, rotation_gl.y, rotation_gl.z],
[scale.x, scale.y, scale.z]
])
)
@@ -63,13 +67,41 @@ Entity {
// Translation values from node (vector3d because this is the type of QTransform.translation)
property var nodeTranslation : Qt.vector3d(
root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxTranslation.x").value : 0,
- root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxTranslation.y").value : 0,
- root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxTranslation.z").value : 0
+ root.currentMeshingNode ? -root.currentMeshingNode.attribute("boundingBox.bboxTranslation.y").value : 0,
+ root.currentMeshingNode ? -root.currentMeshingNode.attribute("boundingBox.bboxTranslation.z").value : 0
)
+
// Rotation values from node (3 separated values because QTransform stores Euler angles like this)
- property var nodeRotationX: root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxRotation.x").value : 0
- property var nodeRotationY: root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxRotation.y").value : 0
- property var nodeRotationZ: root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxRotation.z").value : 0
+ property var nodeRotationX: {
+ var rx = root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxRotation.x").value : 0
+ var ry = root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxRotation.y").value : 0
+ var rz = root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxRotation.z").value : 0
+
+ var rotationEuler_cv = Qt.vector3d(rx, ry, rz)
+ var rotation_gl = Transformations3DHelper.convertRotationFromCV2GL(rotationEuler_cv)
+ return rotation_gl.x
+ }
+
+ property var nodeRotationY: {
+ var rx = root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxRotation.x").value : 0
+ var ry = root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxRotation.y").value : 0
+ var rz = root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxRotation.z").value : 0
+
+ var rotationEuler_cv = Qt.vector3d(rx, ry, rz)
+ var rotation_gl = Transformations3DHelper.convertRotationFromCV2GL(rotationEuler_cv)
+ return rotation_gl.y
+ }
+
+ property var nodeRotationZ: {
+ var rx = root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxRotation.x").value : 0
+ var ry = root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxRotation.y").value : 0
+ var rz = root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxRotation.z").value : 0
+
+ var rotationEuler_cv = Qt.vector3d(rx, ry, rz)
+ var rotation_gl = Transformations3DHelper.convertRotationFromCV2GL(rotationEuler_cv)
+ return rotation_gl.z
+ }
+
// Scale values from node (vector3d because this is the type of QTransform.scale3D)
property var nodeScale: Qt.vector3d(
root.currentMeshingNode ? root.currentMeshingNode.attribute("boundingBox.bboxScale.x").value : 1,
diff --git a/meshroom/ui/qml/main.qml b/meshroom/ui/qml/main.qml
index 0923f352..a119ce4d 100755
--- a/meshroom/ui/qml/main.qml
+++ b/meshroom/ui/qml/main.qml
@@ -322,13 +322,12 @@ ApplicationWindow {
}
FileDialog {
- id: importFilesDialog
+ id: importImagesDialog
title: "Import Images"
fileMode: FileDialog.OpenFiles
nameFilters: []
onAccepted: {
- console.warn("importFilesDialog selectedFiles: " + importFilesDialog.selectedFiles)
- _reconstruction.importImagesUrls(importFilesDialog.selectedFiles)
+ _reconstruction.importImagesUrls(importImagesDialog.selectedFiles)
}
}
@@ -588,17 +587,17 @@ ApplicationWindow {
}
}
Action {
- id: importActionItem
+ id: importImagesAction
text: "Import Images"
shortcut: "Ctrl+I"
onTriggered: {
- initFileDialogFolder(importFilesDialog);
- importFilesDialog.open();
+ initFileDialogFolder(importImagesDialog);
+ importImagesDialog.open();
}
}
Action {
- id: clearActionItem
+ id: clearImagesAction
text: "Clear Images"
onTriggered: {
//Loop through all the camera inits