mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-05-21 13:06:28 +02:00
[ui] ImageGallery: allow to visualize the list of HDR images created by LDRToHDR
Conflicts: meshroom/ui/reconstruction.py
This commit is contained in:
parent
85dd992927
commit
19d2f90554
5 changed files with 85 additions and 12 deletions
|
@ -606,6 +606,10 @@ class BaseNode(BaseObject):
|
|||
return False
|
||||
return True
|
||||
|
||||
@Slot(result=bool)
|
||||
def isComputed(self):
|
||||
return self.hasStatus(Status.SUCCESS)
|
||||
|
||||
@Slot()
|
||||
def clearData(self):
|
||||
""" Delete this Node internal folder.
|
||||
|
|
|
@ -160,6 +160,9 @@ class CameraInit(desc.CommandLineNode):
|
|||
),
|
||||
]
|
||||
|
||||
def readSfMData(self, sfmFile):
|
||||
return readSfMData(sfmFile)
|
||||
|
||||
def buildIntrinsics(self, node, additionalViews=()):
|
||||
""" Build intrinsics from node current views and optional additional views
|
||||
|
||||
|
|
|
@ -16,13 +16,13 @@ Panel {
|
|||
|
||||
property variant cameraInits
|
||||
property variant cameraInit
|
||||
property variant hdrCameraInit
|
||||
readonly property alias currentItem: grid.currentItem
|
||||
readonly property string currentItemSource: grid.currentItem ? grid.currentItem.source : ""
|
||||
readonly property var currentItemMetadata: grid.currentItem ? grid.currentItem.metadata : undefined
|
||||
property int defaultCellSize: 160
|
||||
property int currentIndex: 0
|
||||
property bool readOnly: false
|
||||
readonly property variant viewpoints: cameraInit.attribute('viewpoints').value
|
||||
|
||||
signal removeImageRequest(var attribute)
|
||||
signal filesDropped(var drop, var augmentSfm)
|
||||
|
@ -30,6 +30,17 @@ Panel {
|
|||
title: "Images"
|
||||
implicitWidth: (root.defaultCellSize + 2) * 2
|
||||
|
||||
function changeCurrentIndex(newIndex) {
|
||||
_reconstruction.cameraInitIndex = newIndex
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: m
|
||||
property variant currentCameraInit: displayHDR.checked ? _reconstruction.hdrCameraInit : root.cameraInit
|
||||
property variant viewpoints: currentCameraInit ? currentCameraInit.attribute('viewpoints').value : undefined
|
||||
property bool readOnly: root.readOnly || displayHDR.checked
|
||||
}
|
||||
|
||||
headerBar: RowLayout {
|
||||
MaterialToolButton {
|
||||
text: MaterialIcons.more_vert
|
||||
|
@ -99,7 +110,7 @@ Panel {
|
|||
|
||||
model: SortFilterDelegateModel {
|
||||
id: sortedModel
|
||||
model: _reconstruction.viewpoints
|
||||
model: m.viewpoints
|
||||
sortRole: "path"
|
||||
// TODO: provide filtering on reconstruction status
|
||||
// filterRole: _reconstruction.sfmReport ? "reconstructed" : ""
|
||||
|
@ -123,7 +134,7 @@ Panel {
|
|||
viewpoint: object.value
|
||||
width: grid.cellWidth
|
||||
height: grid.cellHeight
|
||||
readOnly: root.readOnly
|
||||
readOnly: m.readOnly
|
||||
displayViewId: displayViewIdsAction.checked
|
||||
|
||||
isCurrentItem: GridView.isCurrentItem
|
||||
|
@ -202,9 +213,9 @@ Panel {
|
|||
{
|
||||
event.accepted = true
|
||||
if(event.key == Qt.Key_Right)
|
||||
root.currentIndex = Math.min(root.cameraInits.count - 1, root.currentIndex + 1)
|
||||
root.changeCurrentIndex(Math.min(root.cameraInits.count - 1, root.currentIndex + 1))
|
||||
else if(event.key == Qt.Key_Left)
|
||||
root.currentIndex = Math.max(0, root.currentIndex - 1)
|
||||
root.changeCurrentIndex(Math.max(0, root.currentIndex - 1))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,7 +238,7 @@ Panel {
|
|||
DropArea {
|
||||
id: dropArea
|
||||
anchors.fill: parent
|
||||
enabled: !root.readOnly
|
||||
enabled: !m.readOnly
|
||||
keys: ["text/uri-list"]
|
||||
// TODO: onEntered: call specific method to filter files based on extension
|
||||
onDropped: {
|
||||
|
@ -274,7 +285,7 @@ Panel {
|
|||
text: "Augment Reconstruction"
|
||||
font.bold: true
|
||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||
visible: viewpoints.count > 0
|
||||
visible: m.viewpoints ? m.viewpoints.count > 0 : false
|
||||
background: Rectangle {
|
||||
color: parent.hovered ? palette.highlight : palette.window
|
||||
opacity: 0.8
|
||||
|
@ -299,14 +310,13 @@ Panel {
|
|||
enabled: nodesCB.currentIndex > 0
|
||||
onClicked: nodesCB.decrementCurrentIndex()
|
||||
}
|
||||
Label { text: "Group " }
|
||||
Label { id: groupLabel; text: "Group " }
|
||||
ComboBox {
|
||||
id: nodesCB
|
||||
model: root.cameraInits.count
|
||||
implicitWidth: 40
|
||||
currentIndex: root.currentIndex
|
||||
onActivated: root.currentIndex = currentIndex
|
||||
|
||||
onActivated: root.changeCurrentIndex(currentIndex)
|
||||
}
|
||||
Label { text: "/ " + (root.cameraInits.count - 1) }
|
||||
ToolButton {
|
||||
|
@ -337,6 +347,26 @@ Panel {
|
|||
}
|
||||
}
|
||||
|
||||
MaterialToolButton {
|
||||
id: displayHDR
|
||||
font.pointSize: 20
|
||||
padding: 0
|
||||
anchors.margins: 0
|
||||
implicitHeight: 14
|
||||
ToolTip.text: "Visualize HDR images"
|
||||
text: MaterialIcons.hdr_on
|
||||
visible: _reconstruction.ldr2hdr
|
||||
enabled: visible && _reconstruction.ldr2hdr.isComputed()
|
||||
onEnabledChanged: {
|
||||
// Reset the toggle to avoid getting stuck
|
||||
// with the HDR node checked but disabled.
|
||||
checked = false;
|
||||
}
|
||||
checkable: true
|
||||
checked: false
|
||||
onClicked: { _reconstruction.setupLDRToHDRCameraInit(); }
|
||||
}
|
||||
|
||||
Item { Layout.fillHeight: true; Layout.fillWidth: true }
|
||||
|
||||
// Thumbnail size icon and slider
|
||||
|
|
|
@ -64,9 +64,9 @@ Item {
|
|||
Layout.fillHeight: true
|
||||
readOnly: root.readOnly
|
||||
cameraInits: root.cameraInits
|
||||
cameraInit: _reconstruction.cameraInit
|
||||
cameraInit: reconstruction.cameraInit
|
||||
hdrCameraInit: reconstruction.hdrCameraInit
|
||||
currentIndex: reconstruction.cameraInitIndex
|
||||
onCurrentIndexChanged: reconstruction.cameraInitIndex = currentIndex
|
||||
onRemoveImageRequest: reconstruction.removeAttribute(attribute)
|
||||
onFilesDropped: reconstruction.handleFilesDrop(drop, augmentSfm ? null : cameraInit)
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ from threading import Thread
|
|||
from PySide2.QtCore import QObject, Slot, Property, Signal, QUrl, QSizeF
|
||||
from PySide2.QtGui import QMatrix4x4, QMatrix3x3, QQuaternion, QVector3D, QVector2D
|
||||
|
||||
import meshroom.core
|
||||
from meshroom import multiview
|
||||
from meshroom.common.qt import QObjectListModel
|
||||
from meshroom.core import Version
|
||||
|
@ -369,6 +370,8 @@ class Reconstruction(UIGraph):
|
|||
self._buildingIntrinsics = False
|
||||
self.intrinsicsBuilt.connect(self.onIntrinsicsAvailable)
|
||||
|
||||
self._hdrCameraInit = None
|
||||
|
||||
self.importImagesFailed.connect(self.onImportImagesFailed)
|
||||
|
||||
# - Feature Extraction
|
||||
|
@ -394,6 +397,10 @@ class Reconstruction(UIGraph):
|
|||
# - Texturing
|
||||
self._texturing = None
|
||||
|
||||
# - LDR2HDR
|
||||
self._ldr2hdr = None
|
||||
self.cameraInitChanged.connect(self.updateLdr2hdrNode)
|
||||
|
||||
# react to internal graph changes to update those variables
|
||||
self.graphChanged.connect(self.onGraphChanged)
|
||||
|
||||
|
@ -449,6 +456,8 @@ class Reconstruction(UIGraph):
|
|||
self.prepareDenseScene = None
|
||||
self.depthMap = None
|
||||
self.texturing = None
|
||||
self.ldr2hdr = None
|
||||
self.hdrCameraInit = None
|
||||
self.updateCameraInits()
|
||||
if not self._graph:
|
||||
return
|
||||
|
@ -478,6 +487,10 @@ class Reconstruction(UIGraph):
|
|||
|
||||
def getCameraInitIndex(self):
|
||||
if not self._cameraInit:
|
||||
# No CameraInit node
|
||||
return -1
|
||||
if not self._cameraInit.graph:
|
||||
# The CameraInit node is a temporary one not attached to a graph
|
||||
return -1
|
||||
return self._cameraInits.indexOf(self._cameraInit)
|
||||
|
||||
|
@ -493,6 +506,24 @@ class Reconstruction(UIGraph):
|
|||
""" Set the current FeatureExtraction node based on the current CameraInit node. """
|
||||
self.depthMap = self.lastNodeOfType('DepthMapFilter', self.cameraInit) if self.cameraInit else None
|
||||
|
||||
def updateLdr2hdrNode(self):
|
||||
""" Set the current LDR2HDR node based on the current CameraInit node. """
|
||||
self.ldr2hdr = self.lastNodeOfType('LDRToHDR', self.cameraInit) if self.cameraInit else None
|
||||
|
||||
@Slot()
|
||||
def setupLDRToHDRCameraInit(self):
|
||||
if not self.ldr2hdr:
|
||||
self.hdrCameraInit = Node("CameraInit")
|
||||
return
|
||||
sfmFile = self.ldr2hdr.attribute("outSfMDataFilename").value
|
||||
if not sfmFile or not os.path.isfile(sfmFile):
|
||||
self.hdrCameraInit = Node("CameraInit")
|
||||
return
|
||||
nodeDesc = meshroom.core.nodesDesc["CameraInit"]()
|
||||
views, intrinsics = nodeDesc.readSfMData(sfmFile)
|
||||
tmpCameraInit = Node("CameraInit", viewpoints=views, intrinsics=intrinsics)
|
||||
self.hdrCameraInit = tmpCameraInit
|
||||
|
||||
def lastSfmNode(self):
|
||||
""" Retrieve the last SfM node from the initial CameraInit node. """
|
||||
return self.lastNodeOfType("StructureFromMotion", self._cameraInit, Status.SUCCESS)
|
||||
|
@ -778,6 +809,8 @@ class Reconstruction(UIGraph):
|
|||
|
||||
cameraInitChanged = Signal()
|
||||
cameraInit = makeProperty(QObject, "_cameraInit", cameraInitChanged, resetOnDestroy=True)
|
||||
hdrCameraInitChanged = Signal()
|
||||
hdrCameraInit = makeProperty(QObject, "_hdrCameraInit", hdrCameraInitChanged, resetOnDestroy=True)
|
||||
cameraInitIndex = Property(int, getCameraInitIndex, setCameraInitIndex, notify=cameraInitChanged)
|
||||
viewpoints = Property(QObject, getViewpoints, notify=cameraInitChanged)
|
||||
cameraInits = Property(QObject, lambda self: self._cameraInits, constant=True)
|
||||
|
@ -970,6 +1003,9 @@ class Reconstruction(UIGraph):
|
|||
texturingChanged = Signal()
|
||||
texturing = makeProperty(QObject, "_texturing", notify=texturingChanged)
|
||||
|
||||
ldr2hdrChanged = Signal()
|
||||
ldr2hdr = makeProperty(QObject, "_ldr2hdr", notify=ldr2hdrChanged, resetOnDestroy=True)
|
||||
|
||||
nbCameras = Property(int, reconstructedCamerasCount, notify=sfmReportChanged)
|
||||
|
||||
# Signals to propagate high-level messages
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue