mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-05-01 03:07:46 +02:00
[ui] save after drag&drop: split of handling types and processing files
First get type of files, then either ensure the save or process files.
This commit is contained in:
parent
67fbf1b00f
commit
58e9bafa45
3 changed files with 47 additions and 29 deletions
|
@ -81,7 +81,14 @@ Item {
|
||||||
onRemoveImageRequest: reconstruction.removeAttribute(attribute)
|
onRemoveImageRequest: reconstruction.removeAttribute(attribute)
|
||||||
onAllViewpointsCleared: { reconstruction.removeAllImages(); reconstruction.selectedViewId = "-1" }
|
onAllViewpointsCleared: { reconstruction.removeAllImages(); reconstruction.selectedViewId = "-1" }
|
||||||
onFilesDropped: {
|
onFilesDropped: {
|
||||||
reconstruction.handleFilesUrl(drop.urls, augmentSfm ? null : cameraInit)
|
var filesByType = _reconstruction.getFilesByTypeFromDrop(drop.urls)
|
||||||
|
if (filesByType["other"].length > 0) {
|
||||||
|
ensureSaved(function() {
|
||||||
|
reconstruction.handleFilesUrl(filesByType, augmentSfm ? null : cameraInit)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
reconstruction.handleFilesUrl(filesByType, augmentSfm ? null : cameraInit)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LiveSfmView {
|
LiveSfmView {
|
||||||
|
|
|
@ -1187,7 +1187,14 @@ ApplicationWindow {
|
||||||
computeManager.submit(node)
|
computeManager.submit(node)
|
||||||
}
|
}
|
||||||
onFilesDropped: {
|
onFilesDropped: {
|
||||||
_reconstruction.handleFilesUrl(drop.urls, null, mousePosition)
|
var filesByType = _reconstruction.getFilesByTypeFromDrop(drop.urls)
|
||||||
|
if (filesByType["other"].length > 0) {
|
||||||
|
ensureSaved(function() {
|
||||||
|
_reconstruction.handleFilesUrl(filesByType, null, mousePosition)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
_reconstruction.handleFilesUrl(filesByType, null, mousePosition)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -716,15 +716,19 @@ class Reconstruction(UIGraph):
|
||||||
""" Get all view Ids involved in the reconstruction. """
|
""" Get all view Ids involved in the reconstruction. """
|
||||||
return [vp.viewId.value for node in self._cameraInits for vp in node.viewpoints.value]
|
return [vp.viewId.value for node in self._cameraInits for vp in node.viewpoints.value]
|
||||||
|
|
||||||
@Slot('QList<QUrl>')
|
@Slot("QVariantMap")
|
||||||
@Slot('QList<QUrl>', Node)
|
@Slot("QVariantMap", Node)
|
||||||
@Slot('QList<QUrl>', Node, 'QPoint')
|
@Slot("QVariantMap", Node, "QPoint")
|
||||||
def handleFilesUrl(self, urls, cameraInit=None, position=None):
|
def handleFilesUrl(self, filesByType, cameraInit=None, position=None):
|
||||||
""" Handle drop events aiming to add images to the Reconstruction.
|
""" Handle drop events aiming to add images to the Reconstruction.
|
||||||
This method allows to reduce process time by doing it on Python side.
|
This method allows to reduce process time by doing it on Python side.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
{images, videos, panoramaInfo, otherFiles}: Map of paths of recognized images and list of other files
|
||||||
|
Node: cameraInit node used to add new images to it
|
||||||
|
QPoint: position to locate the node (usually the mouse position)
|
||||||
"""
|
"""
|
||||||
filesByType = self.getFilesByTypeFromDrop(urls)
|
if filesByType["images"]:
|
||||||
if filesByType.images:
|
|
||||||
if cameraInit is None:
|
if cameraInit is None:
|
||||||
boundingBox = self.layout.boundingBox()
|
boundingBox = self.layout.boundingBox()
|
||||||
if not position:
|
if not position:
|
||||||
|
@ -734,15 +738,15 @@ class Reconstruction(UIGraph):
|
||||||
else:
|
else:
|
||||||
p = position
|
p = position
|
||||||
cameraInit = self.addNewNode("CameraInit", position=p)
|
cameraInit = self.addNewNode("CameraInit", position=p)
|
||||||
self._workerThreads.apply_async(func=self.importImagesSync, args=(filesByType.images, cameraInit,))
|
self._workerThreads.apply_async(func=self.importImagesSync, args=(filesByType["images"], cameraInit,))
|
||||||
if filesByType.videos:
|
if filesByType["videos"]:
|
||||||
boundingBox = self.layout.boundingBox()
|
boundingBox = self.layout.boundingBox()
|
||||||
keyframeNode = self.addNewNode("KeyframeSelection", position=Position(boundingBox[0], boundingBox[1] + boundingBox[3]))
|
keyframeNode = self.addNewNode("KeyframeSelection", position=Position(boundingBox[0], boundingBox[1] + boundingBox[3]))
|
||||||
keyframeNode.inputPaths.value = filesByType.videos
|
keyframeNode.inputPaths.value = filesByType["videos"]
|
||||||
if len(filesByType.videos) == 1:
|
if len(filesByType["videos"]) == 1:
|
||||||
newVideoNodeMessage = "New node '{}' added for the input video.".format(keyframeNode.getLabel())
|
newVideoNodeMessage = "New node '{}' added for the input video.".format(keyframeNode.getLabel())
|
||||||
else:
|
else:
|
||||||
newVideoNodeMessage = "New node '{}' added for a rig of {} synchronized cameras.".format(keyframeNode.getLabel(), len(filesByType.videos))
|
newVideoNodeMessage = "New node '{}' added for a rig of {} synchronized cameras.".format(keyframeNode.getLabel(), len(filesByType["videos"]))
|
||||||
self.info.emit(
|
self.info.emit(
|
||||||
Message(
|
Message(
|
||||||
"Video Input",
|
"Video Input",
|
||||||
|
@ -752,17 +756,17 @@ class Reconstruction(UIGraph):
|
||||||
"If you know the Camera Make/Model, it is highly recommended to declare them in the Node."
|
"If you know the Camera Make/Model, it is highly recommended to declare them in the Node."
|
||||||
))
|
))
|
||||||
|
|
||||||
if filesByType.panoramaInfo:
|
if filesByType["panoramaInfo"]:
|
||||||
if len(filesByType.panoramaInfo) > 1:
|
if len(filesByType["panoramaInfo"]) > 1:
|
||||||
self.error.emit(
|
self.error.emit(
|
||||||
Message(
|
Message(
|
||||||
"Multiple XML files in input",
|
"Multiple XML files in input",
|
||||||
"Ignore the xml Panorama files:\n\n'{}'.".format(',\n'.join(filesByType.panoramaInfo)),
|
"Ignore the xml Panorama files:\n\n'{}'.".format(',\n'.join(filesByType["panoramaInfo"])),
|
||||||
"",
|
"",
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
panoramaInitNodes = self.graph.nodesOfType('PanoramaInit')
|
panoramaInitNodes = self.graph.nodesOfType('PanoramaInit')
|
||||||
for panoramaInfoFile in filesByType.panoramaInfo:
|
for panoramaInfoFile in filesByType["panoramaInfo"]:
|
||||||
for panoramaInitNode in panoramaInitNodes:
|
for panoramaInitNode in panoramaInitNodes:
|
||||||
panoramaInitNode.attribute('initializeCameras').value = 'File'
|
panoramaInitNode.attribute('initializeCameras').value = 'File'
|
||||||
panoramaInitNode.attribute('config').value = panoramaInfoFile
|
panoramaInitNode.attribute('config').value = panoramaInfoFile
|
||||||
|
@ -771,44 +775,44 @@ class Reconstruction(UIGraph):
|
||||||
Message(
|
Message(
|
||||||
"Panorama XML",
|
"Panorama XML",
|
||||||
"XML file declared on PanoramaInit node",
|
"XML file declared on PanoramaInit node",
|
||||||
"XML file '{}' set on node '{}'".format(','.join(filesByType.panoramaInfo), ','.join([n.getLabel() for n in panoramaInitNodes])),
|
"XML file '{}' set on node '{}'".format(','.join(filesByType["panoramaInfo"]), ','.join([n.getLabel() for n in panoramaInitNodes])),
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
self.error.emit(
|
self.error.emit(
|
||||||
Message(
|
Message(
|
||||||
"No PanoramaInit Node",
|
"No PanoramaInit Node",
|
||||||
"No PanoramaInit Node to set the Panorama file:\n'{}'.".format(','.join(filesByType.panoramaInfo)),
|
"No PanoramaInit Node to set the Panorama file:\n'{}'.".format(','.join(filesByType["panoramaInfo"])),
|
||||||
"",
|
"",
|
||||||
))
|
))
|
||||||
|
|
||||||
if not filesByType.images and not filesByType.videos and not filesByType.panoramaInfo:
|
if not filesByType["images"] and not filesByType["videos"] and not filesByType["panoramaInfo"]:
|
||||||
if filesByType.other:
|
if filesByType["other"]:
|
||||||
singleMgFile = False
|
singleMgFile = False
|
||||||
if len(filesByType.other) == 1:
|
if len(filesByType["other"]) == 1:
|
||||||
url = filesByType.other[0]
|
url = filesByType["other"][0]
|
||||||
ext = os.path.splitext(url)[1]
|
ext = os.path.splitext(url)[1]
|
||||||
if ext == '.mg':
|
if ext == '.mg':
|
||||||
self.loadUrl(url)
|
self.loadUrl(url)
|
||||||
singleMgFile = True
|
singleMgFile = True
|
||||||
if not singleMgFile:
|
if not singleMgFile:
|
||||||
extensions = set([os.path.splitext(url)[1] for url in filesByType.other])
|
extensions = set([os.path.splitext(url)[1] for url in filesByType["other"]])
|
||||||
self.error.emit(
|
self.error.emit(
|
||||||
Message(
|
Message(
|
||||||
"No Recognized Input File",
|
"No Recognized Input File",
|
||||||
"No recognized input file in the {} dropped files".format(len(filesByType.other)),
|
"No recognized input file in the {} dropped files".format(len(filesByType["other"])),
|
||||||
"Unknown file extensions: " + ', '.join(extensions)
|
"Unknown file extensions: " + ', '.join(extensions)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@Slot("QList<QUrl>", result="QVariantMap")
|
||||||
def getFilesByTypeFromDrop(urls):
|
def getFilesByTypeFromDrop(self, urls):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
urls: list of filepaths
|
urls: list of filepaths
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
<images, otherFiles> List of recognized images and list of other files
|
{images, otherFiles}: Map of recognized images and list of other files
|
||||||
"""
|
"""
|
||||||
# Build the list of images paths
|
# Build the list of images paths
|
||||||
filesByType = multiview.FilesByType()
|
filesByType = multiview.FilesByType()
|
||||||
|
@ -818,7 +822,7 @@ class Reconstruction(UIGraph):
|
||||||
filesByType.extend(multiview.findFilesByTypeInFolder(localFile))
|
filesByType.extend(multiview.findFilesByTypeInFolder(localFile))
|
||||||
else:
|
else:
|
||||||
filesByType.addFile(localFile)
|
filesByType.addFile(localFile)
|
||||||
return filesByType
|
return {"images": filesByType.images, "videos": filesByType.videos, "panoramaInfo":filesByType.panoramaInfo, "other":filesByType.other}
|
||||||
|
|
||||||
def importImagesFromFolder(self, path, recursive=False):
|
def importImagesFromFolder(self, path, recursive=False):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Add table
Reference in a new issue