[ui] Add a "Clear All Images" action and update "Clear Images"'s behaviour

"Clear Images" used to clear the intrinsics and viewpoints for all the
existing CameraInit nodes in the graph. There was no-user friendly way
to clear the images of a specific CameraInit node.

This commit modifies the behaviour of "Clear Images" so that it only
deletes the intrinsics and viewpoints of the current CameraInit. A new menu
action, "Clear All Images", is added in the "Advanced" sub-menu, and
deletes all the intrinsics and viewpoints for all the CameraInit nodes.

The way images are cleared is also modified: instead of removing the
intrinsics and viewpoints attributes, they are reset. To be undone
properly, a corresponding "ClearImagesCommand" has been added. This offers
a great performance increase (clearing 1000 images now takes 1s).

Tooltips have been added to make the distinction clearer for users.
This commit is contained in:
Candice Bentéjac 2023-02-22 13:24:32 +01:00
parent 2987bf0617
commit 43f439be88
4 changed files with 66 additions and 26 deletions

View file

@ -350,6 +350,31 @@ class ListAttributeRemoveCommand(GraphCommand):
listAttribute.insert(self.index, self.value)
class ClearImagesCommand(GraphCommand):
def __init__(self, graph, cameraInitNodes, parent=None):
super(ClearImagesCommand, self).__init__(graph, parent)
self.cameraInits = cameraInitNodes
self.viewpoints = { cameraInit.name: cameraInit.attribute("viewpoints").getExportValue() for cameraInit in self.cameraInits }
self.intrinsics = { cameraInit.name: cameraInit.attribute("intrinsics").getExportValue() for cameraInit in self.cameraInits }
self.title = "Clear{}Images".format(" " if len(self.cameraInits) == 1 else " All ")
self.setText(self.title)
def redoImpl(self):
for i in range(len(self.cameraInits)):
# Reset viewpoints
self.cameraInits[i].viewpoints.resetValue()
self.cameraInits[i].viewpoints.valueChanged.emit()
# Reset intrinsics
self.cameraInits[i].intrinsics.resetValue()
self.cameraInits[i].intrinsics.valueChanged.emit()
def undoImpl(self):
for cameraInit in self.viewpoints:
with GraphModification(self.graph):
self.graph.node(cameraInit).viewpoints.value = self.viewpoints[cameraInit]
self.graph.node(cameraInit).intrinsics.value = self.intrinsics[cameraInit]
class MoveNodeCommand(GraphCommand):
""" Move a node to a given position. """
def __init__(self, graph, node, position, parent=None):

View file

@ -733,6 +733,16 @@ class UIGraph(QObject):
def removeAttribute(self, attribute):
self.push(commands.ListAttributeRemoveCommand(self._graph, attribute))
@Slot()
def clearImages(self):
with self.groupedGraphModification("Clear Images"):
self.push(commands.ClearImagesCommand(self._graph, [self.cameraInit]))
@Slot()
def clearAllImages(self):
with self.groupedGraphModification("Clear All Images"):
self.push(commands.ClearImagesCommand(self._graph, list(self.cameraInits)))
@Slot(Node)
def appendSelection(self, node):
""" Append 'node' to the selection if it is not already part of the selection. """

View file

@ -427,6 +427,26 @@ ApplicationWindow {
uigraph: _reconstruction
}
Action {
id: clearImagesAction
property string tooltip: "Clear images for the current CameraInit group"
text: "Clear Images"
onTriggered: {
_reconstruction.clearImages()
_reconstruction.selectedViewId = "-1"
}
}
Action {
id: clearAllImagesAction
property string tooltip: "Clear all the images for all the CameraInit groups"
text: "Clear All Images"
onTriggered: {
_reconstruction.clearAllImages()
_reconstruction.selectedViewId = "-1"
}
}
Action {
id: undoAction
@ -638,13 +658,12 @@ ApplicationWindow {
}
}
Action {
id: clearImagesAction
text: "Clear Images"
onTriggered: {
_reconstruction.clearImages()
}
MenuItem {
action: clearImagesAction
ToolTip.visible: hovered
ToolTip.text: clearImagesAction.tooltip
}
MenuSeparator { }
Menu {
id: advancedMenu
@ -677,6 +696,12 @@ ApplicationWindow {
importProjectDialog.open();
}
}
MenuItem {
action: clearAllImagesAction
ToolTip.visible: hovered
ToolTip.text: clearAllImagesAction.tooltip
}
}
MenuSeparator { }
Action {

View file

@ -694,26 +694,6 @@ class Reconstruction(UIGraph):
""" Get all view Ids involved in the reconstruction. """
return [vp.viewId.value for node in self._cameraInits for vp in node.viewpoints.value]
@Slot()
def clearImages(self):
""" Clear the list of viewpoints and intrinsics for all the CameraInit nodes. """
with self.groupedGraphModification("Clear Images"):
for cameraInit in self._cameraInits:
# Delete all viewpoints
viewpoints = cameraInit.attribute("viewpoints")
y = len(viewpoints.value) - 1
while y >= 0:
self.removeAttribute(viewpoints.value[y])
y = y - 1
# Delete all intrinsics
intrinsics = cameraInit.attribute("intrinsics")
z = len(intrinsics.value) - 1
while z >= 0:
self.removeAttribute(intrinsics.value[z])
z = z - 1
@Slot(QObject, Node)
def handleFilesDrop(self, drop, cameraInit):
""" Handle drop events aiming to add images to the Reconstruction.