Skip to content

Commit 4abd11a

Browse files
committed
Restore visualization on operator cancel
Previously, the visualization would just be gone. Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
1 parent c962310 commit 4abd11a

6 files changed

Lines changed: 62 additions & 1 deletion

File tree

tomviz/pipeline/Node.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ class Node : public QObject
152152
/// widget. Otherwise return nullptr and a default QProgressBar will be used.
153153
virtual QWidget* getCustomProgressWidget(QWidget*) const { return nullptr; }
154154

155+
/// Re-show any visualization this node owns (or, for group nodes, that its
156+
/// children own) after an input link is recreated, without re-running the
157+
/// pipeline. The counterpart of the implicit hide that happens when a link
158+
/// is broken. Called when a deferred insertion is cancelled and the original
159+
/// links are restored. Default no-op.
160+
virtual void restorePresentation() {}
161+
155162
/// Whether the node supports canceling mid-execution via cancelExecution().
156163
bool supportsCancelingMidExecution() const;
157164

tomviz/pipeline/NodeEditDialog.cxx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "Node.h"
1010
#include "OutputPort.h"
1111
#include "Pipeline.h"
12+
#include "sinks/LegacyModuleSink.h"
1213

1314
#include "Utilities.h"
1415

@@ -150,7 +151,20 @@ void NodeEditDialog::reject()
150151
// Recreate the original links that were broken to insert the node.
151152
for (const auto& ep : m_deferred.linksToRestore) {
152153
if (ep.from && ep.to) {
153-
m_pipeline->createLink(ep.from, ep.to);
154+
auto* link = m_pipeline->createLink(ep.from, ep.to);
155+
// Breaking the link to insert the node hid any downstream module: a
156+
// direct module sink via onInputDisconnected, or modules behind a
157+
// SinkGroupNode via the group's resetVisualization() fan-out. Re-link
158+
// alone does not re-show them and we deliberately do not re-execute, so
159+
// ask the downstream node to restore its presentation explicitly. The
160+
// VTK objects still hold the last data, so this is presentation-only --
161+
// no pipeline run and no dependence on upstream PortData (which a
162+
// transient source releases on disconnect). Done only on this cancel
163+
// path so the insertion preview keeps its current behavior (the moved
164+
// module stays hidden until the not-yet-run transform produces data).
165+
if (link && ep.to->node()) {
166+
ep.to->node()->restorePresentation();
167+
}
154168
}
155169
}
156170

tomviz/pipeline/SinkGroupNode.cxx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,18 @@ void SinkGroupNode::addPassthrough(const QString& name, PortType type)
4747
});
4848
}
4949

50+
void SinkGroupNode::restorePresentation()
51+
{
52+
// Symmetric with the resetVisualization() fan-out performed when this
53+
// group's input is disconnected (see addPassthrough). Child sinks' own
54+
// input links never changed, so they need an explicit re-show.
55+
for (auto* sink : sinks()) {
56+
if (auto* legacy = qobject_cast<LegacyModuleSink*>(sink)) {
57+
legacy->restoreVisualization();
58+
}
59+
}
60+
}
61+
5062
bool SinkGroupNode::execute()
5163
{
5264
for (auto* port : inputPorts()) {

tomviz/pipeline/SinkGroupNode.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ class SinkGroupNode : public Node
3636

3737
bool execute() override;
3838

39+
/// Re-show the visualizations of all child sinks. Counterpart of the
40+
/// resetVisualization() fan-out done when this group's input is
41+
/// disconnected; used to restore modules when a cancelled deferred
42+
/// insertion recreates the group's original input link.
43+
void restorePresentation() override;
44+
3945
/// All sink nodes currently connected to this group's output ports.
4046
QList<SinkNode*> sinks() const;
4147

tomviz/pipeline/sinks/LegacyModuleSink.cxx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,18 @@ void LegacyModuleSink::resetVisualization()
293293
emit renderNeeded();
294294
}
295295

296+
void LegacyModuleSink::restoreVisualization()
297+
{
298+
// Re-apply the current visibility flag. Each subclass's setVisibility()
299+
// override pushes visibility onto its props/widgets unconditionally before
300+
// the base call, so this re-shows props that clearVisualization() hid even
301+
// though m_visible never changed (the base call's guard then suppresses a
302+
// redundant visibilityChanged signal). The VTK objects still hold the last
303+
// consumed data, so nothing needs to be re-read or re-executed.
304+
setVisibility(m_visible);
305+
emit renderNeeded();
306+
}
307+
296308
void LegacyModuleSink::onInputDisconnected(InputPort*)
297309
{
298310
resetVisualization();

tomviz/pipeline/sinks/LegacyModuleSink.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,15 @@ class LegacyModuleSink : public SinkNode
106106
/// direct input disconnect.
107107
void resetVisualization();
108108

109+
/// Re-show the props this sink owns according to its current visibility
110+
/// flag, then request a repaint. The counterpart of resetVisualization():
111+
/// the underlying VTK objects still hold the last-consumed data after a
112+
/// clearVisualization(), so reconnecting an input only needs to re-apply
113+
/// visibility -- no upstream data and no pipeline run required. Used to
114+
/// restore a module when a broken link is recreated (e.g. cancelling a
115+
/// deferred operator insertion).
116+
void restoreVisualization();
117+
109118
/// Return sibling LegacyModuleSinks connected to the same upstream
110119
/// OutputPort as this sink's given input port (excluding this node).
111120
QList<LegacyModuleSink*> siblingSinks(
@@ -158,6 +167,7 @@ class LegacyModuleSink : public SinkNode
158167
void postConsume(bool success) override;
159168

160169
void onInputDisconnected(InputPort* port) override;
170+
void restorePresentation() override { restoreVisualization(); }
161171

162172
private:
163173
/// Reset camera on first consume if no other sink has rendered to this view.

0 commit comments

Comments
 (0)