[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 var metadata
function clear()
{
source = ''
metadata = {}
}
// slots
Keys.onPressed: {
if(event.key == Qt.Key_F) {

View file

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

View file

@ -175,7 +175,7 @@ class Reconstruction(UIGraph):
def onGraphChanged(self):
""" React to the change of the internal graph. """
self._liveSfmManager.reset()
self._sfm = None
self.sfm = None
self._endChunk = None
self.setMeshFile('')
self.updateCameraInits()
@ -404,32 +404,37 @@ class Reconstruction(UIGraph):
self._views, self._poses = self._sfm.nodeDesc.getViewsAndPoses(self._sfm)
self.sfmReportChanged.emit()
def _resetSfm(self):
""" Reset sfm-related members. """
self._sfm = None
self.updateViewsAndPoses()
def getSfm(self):
""" Returns the current SfM node. """
return self._sfm
def setSfm(self, node):
""" Set the current SfM node.
This node will be used to retrieve sparse reconstruction result like camera poses.
def _setSfm(self, node=None):
""" Set current SfM node to 'node' and update views and 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
# Update views and poses and do so each time
# the status of the SfM node's only chunk changes
self.updateViewsAndPoses()
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.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)
def isInViews(self, viewpoint):
# keys are strings (faster lookup)