[ui] better handling of Reconstruction's current sfm node

* reset sfm node on graph change by using 'sfm' property (ensure previous sfm node is correctly disconnected)
* ui: clear viewers when graph changes
This commit is contained in:
Yann Lanthony 2018-04-06 14:24:45 +02:00
parent 11121039dc
commit 472b860131
3 changed files with 38 additions and 23 deletions

View file

@ -11,6 +11,12 @@ FocusScope {
property url source property url source
property var metadata property var metadata
function clear()
{
source = ''
metadata = {}
}
// slots // slots
Keys.onPressed: { Keys.onPressed: {
if(event.key == Qt.Key_F) { if(event.key == Qt.Key_F) {

View file

@ -24,13 +24,13 @@ Item {
implicitWidth: 300 implicitWidth: 300
implicitHeight: 400 implicitHeight: 400
onMeshFileChanged: viewer3D.clear()
signal requestGraphAutoLayout() signal requestGraphAutoLayout()
// Load a 3D media file in the 3D viewer // Load a 3D media file in the 3D viewer
function load3DMedia(filepath) function load3DMedia(filepath)
{ {
if(!Filepath.exists(Filepath.urlToString(filepath)))
return
switch(Filepath.extension(filepath)) switch(Filepath.extension(filepath))
{ {
case ".abc": viewer3D.abcSource = filepath; break; case ".abc": viewer3D.abcSource = filepath; break;
@ -41,13 +41,17 @@ Item {
Connections { Connections {
target: reconstruction target: reconstruction
onSfmReportChanged: loadSfmAbc() onGraphChanged: {
viewer3D.clear()
viewer2D.clear()
} }
onSfmReportChanged: {
function loadSfmAbc() viewer3D.abcSource = ''
{ if(!reconstruction.sfm)
return
load3DMedia(Filepath.stringToUrl(reconstruction.sfm.attribute('output').value)) load3DMedia(Filepath.stringToUrl(reconstruction.sfm.attribute('output').value))
} }
}
SystemPalette { id: palette } SystemPalette { id: palette }
@ -126,7 +130,7 @@ Item {
Label { Label {
anchors.centerIn: parent anchors.centerIn: parent
text: "Loading Model..." text: "Loading..."
visible: viewer3D.loading visible: viewer3D.loading
padding: 6 padding: 6
background: Rectangle { color: palette.base; opacity: 0.5 } background: Rectangle { color: palette.base; opacity: 0.5 }

View file

@ -175,7 +175,7 @@ class Reconstruction(UIGraph):
def onGraphChanged(self): def onGraphChanged(self):
""" React to the change of the internal graph. """ """ React to the change of the internal graph. """
self._liveSfmManager.reset() self._liveSfmManager.reset()
self._sfm = None self.sfm = None
self._endChunk = None self._endChunk = None
self.setMeshFile('') self.setMeshFile('')
self.updateCameraInits() self.updateCameraInits()
@ -404,32 +404,37 @@ class Reconstruction(UIGraph):
self._views, self._poses = self._sfm.nodeDesc.getViewsAndPoses(self._sfm) self._views, self._poses = self._sfm.nodeDesc.getViewsAndPoses(self._sfm)
self.sfmReportChanged.emit() self.sfmReportChanged.emit()
def _resetSfm(self):
""" Reset sfm-related members. """
self._sfm = None
self.updateViewsAndPoses()
def getSfm(self): def getSfm(self):
""" Returns the current SfM node. """ """ Returns the current SfM node. """
return self._sfm return self._sfm
def setSfm(self, node): def _setSfm(self, node=None):
""" Set the current SfM node. """ Set current SfM node to 'node' and update views and poses.
This node will be used to retrieve sparse reconstruction result like camera poses. Notes: this should not be called directly, use setSfm instead.
See Also: setSfm
""" """
if self._sfm:
self._sfm.chunks[0].statusChanged.disconnect(self.updateViewsAndPoses)
self._sfm.destroyed.disconnect(self._resetSfm)
self._sfm = node self._sfm = node
# Update views and poses and do so each time # Update views and poses and do so each time
# the status of the SfM node's only chunk changes # the status of the SfM node's only chunk changes
self.updateViewsAndPoses() self.updateViewsAndPoses()
if self._sfm: if self._sfm:
self._sfm.destroyed.connect(self._resetSfm) # when destroyed, directly use '_setSfm' to bypass
# disconnection step in 'setSfm' (at this point, 'self._sfm' underlying object
# has been destroyed and can't be evaluated anymore)
self._sfm.destroyed.connect(self._setSfm)
self._sfm.chunks[0].statusChanged.connect(self.updateViewsAndPoses) self._sfm.chunks[0].statusChanged.connect(self.updateViewsAndPoses)
self.sfmChanged.emit() self.sfmChanged.emit()
def setSfm(self, node):
""" Set the current SfM node.
This node will be used to retrieve sparse reconstruction result like camera poses.
"""
# disconnect from previous SfM node if any
if self._sfm:
self._sfm.chunks[0].statusChanged.disconnect(self.updateViewsAndPoses)
self._sfm.destroyed.disconnect(self._setSfm)
self._setSfm(node)
@Slot(QObject, result=bool) @Slot(QObject, result=bool)
def isInViews(self, viewpoint): def isInViews(self, viewpoint):
# keys are strings (faster lookup) # keys are strings (faster lookup)