Skip to content

Tomviz 3.1 - #2309

Closed
psavery wants to merge 163 commits into
OpenChemistry:masterfrom
psavery:3.1
Closed

psavery wants to merge 163 commits into
OpenChemistry:masterfrom
psavery:3.1

Conversation

@psavery

@psavery psavery commented Sep 25, 2026

Copy link
Copy Markdown
Contributor

Highlights:

  • Live data: Python sources can re-run periodically as new data arrives; the PyXRF and Ptycho sources pick up new scans, and Sample Data -> Simulated Live Acquisition demonstrates it.
  • Fourier-space filtering: FFT, Fourier Filter, Fourier Peak Mask (with automatic peak detection), Fourier Mask, Image Math and Combine Datasets.
  • Segmentation and label maps: thresholding and connected components on NumPy/SciPy, a Label Map visualization, and Remove Labels.
  • Volume rendering: saved lighting presets, cut-out and exploded views, region auto-contrast, opacity presets, several volumes in one view, linked slices and clips, and a 2D image viewer.
  • Animation: a new Animation menu and a reworked Animation Helper (viewpoints with recorded state, orbits, captions, MP4 export).
  • Pipelines: the standalone tomviz-pipeline package with command-line batch runs, a custom transform manager, and saving transient outputs.
  • Python 3.14 support, now tested in CI

Docs are still being worked on.

psavery added 30 commits August 10, 2026 17:43
State loads reset the ParaView session but never re-registered the
restored views with the animation scene or time keeper, so animations
ticked without rendering. Also flush animation property writes and
relink the dialog's frame count spin box to the new scene.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Contour and slice ranges were only read on selection changes, so
they went stale whenever the pipeline produced new data. Track
executionFinished and rebuild a tab only when its range actually
changed, so user-entered values survive unrelated runs.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
QVTKOpenGLNativeWidget grabs Qt::PanGesture, whose macOS recognizer
enables single-touch trackpad events. VTK maps those to left button
presses, so merely hovering drew rubber band rectangles in the 2D
views and dragged histogram markers. Drop the touch events on macOS.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
HDF5 is built without thread safety, but pipeline executors call it
from worker threads (shim files, port-data disk cache) while the GUI
thread loads, saves and decodes intermediates. Lock every H5ReadWrite
entry point with one recursive mutex.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Add ChimeraX-style Flat/Simple/Soft/Full buttons to the volume panel,
driving VTK's volumetric scattering, global illumination reach,
scattering anisotropy and opacity-derived normals. The individual
parameters move into a collapsed Advanced section, and new volumes now
start shaded on Simple rather than unlit.

Scattering still frames are bounded by measuring a cheap probe frame
and solving for the sampling that fits a time budget: an unbounded one
can run long enough for the OS to reset the GPU, which is fatal on
macOS and takes other applications with it. Camera moves render unlit,
which is both the fastest option and the closest match to the
scattering look.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
progress() left out the range start, so it was only correct for a range
beginning at zero.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
The timeChanged handler that swapped time steps was lost in the legacy
pipeline removal, so playing an animation never changed the volume. The
color map now spans every step rather than rescaling to each one.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Our packages have no MP4 writer and .ogv does not play on macOS. Render
PNG frames offscreen and encode H.264 with the ffmpeg executable, with
resolution, frame rate and quality controls.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Gentle is matte, low contrast and casts no shadows, for noisy data where
Simple turns noise into glitter. The Shadows box switches volumetric
shadows off without leaving the selected preset.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
A playing time series swaps in a new image every frame, so keying on
identity sent it back to a probe frame every time and pinned it at
maximum coarseness.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
It also uploads the texture and compiles the shader, and extrapolating
that one-time cost made the volume look unaffordable.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
A probe frame is dominated by fixed overhead, so scaling it up turned
"the probe was slow" into "this needs 24 minutes a frame" and fired the
valve on volumes that render fine.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Sharpness settles at the fourth root of the budget, so this is a real
gain and still leaves 2x headroom under the tightest watchdog we ship
against.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
The extra reach cost render time without changing the picture, so Full
was trading its own resolution for nothing.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
It is a backstop against a measurement wrong in the optimistic
direction, not against the overhead bias, which can only read
pessimistic.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Nothing told the user why the shadows had gone away, so the panel now
does.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
The clip sweeps by slice index while axis aligned and by distance along
its normal when not, and all three visualizations can fade. Camera paths
are built from saved viewpoints, each leg with its own length and
easing, which a ParaView keyframe cue cannot express.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Visualization animations were owned by the dialog and lost on reload.
They now live in a registry beside the viewpoints, and the frame count
is saved too, since loading rebuilt the scene at a fixed 200.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
"Viewpoint 3" says nothing about which view it is. The picture is stored
with the viewpoint, since it cannot be regenerated without flying the
camera there and back.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Everything ran across the whole timeline, so nothing could be timed
against the camera. A leg is looked up through the same stops the camera
is paced by, so retiming it moves the visualization too.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Label maps carry a table of the labels present, each with a color and a
visibility flag projected onto the transfer functions, reconciled rather
than rebuilt so user edits survive a re-run. It is offered for any
volume whose values read as labels, since a segmentation loaded from a
file arrives as a plain volume.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
The guard keyed on the volume property, so every curve edit threw the
estimate away. An animated curve never escaped its probe frame and
rendered every frame at maximum coarseness.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Capture the curve in the histogram editor at each end and the volume
dissolves between them. Matching point counts blend point by point,
others through a table sampled over one reference window.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Tracking the curve is sharper on average but changes sharpness between
frames, which reads as the picture breathing. Exporting sizes every
frame for the most expensive point of the animation.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
scipy grows the output box and zero-pads the corners it gains, so a
small alignment rotation adds slices that read as blank. Add an Expand
to Fit option to turn that off.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Authored animations were invisible and each module could hold only one.
A list now shows every animation with its own remove button, the camera
modes become one radio choice, and the per-type tabs collapse into a
property dropdown. Volume opacity morphs are keyframed per viewpoint.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
A label map renders through VolumeSink, so the helper offered it a curve
morph that would fight the label table every tick.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
A scene nothing has configured holds one frame, so Play rendered a
single still and the camera looked stuck. Apply the animation once on
creation too, since playback starting at zero announces no time change.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Capturing was one way only, with no way to see what a keyframe held.
Double clicking one puts its curve back, the counterpart of double
clicking a viewpoint.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
An adopted label table lives in the sink, so its colors and names were
lost on reload, and nothing recorded which animation drove the camera.
Loading also dereferenced the main window, which is null headlessly.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
psavery and others added 28 commits September 21, 2026 14:40
The guard's interrupt on module animation changes had no test of its
own; add one from inside a tick, as the dialog's Add button would, and
check the playback stops, rewinds and then runs through with the new
animation applied.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Manage custom transforms in the user directory: create/clone/edit/delete
A Camera Orbit viewpoint added at load sat at the top of every path a
user built afterwards, framed by the load-time camera. Play with
nothing set up to animate now makes it from the current view, before
the player starts, so the list stays empty until then and a lone plain
viewpoint, an authored animation or a time series is left alone.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Legs and orbits now carry a frame count instead of a relative weight,
and the scene's total is their sum, shown in place of the frame box.
Older state files convert their weights, and a leg of zero frames
plays as a cut.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
The custom transform manager dropped ~/.tomviz from the search paths,
so operators placed there by earlier releases vanished; it is scanned
again, read-only. Its tests also pass on Windows now.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
A tilt series of a synthetic object arrives on a wall clock, and
should_auto_execute asks for a re-run only while new projections exist,
so it shows every hook a live source needs. It heads the Sample Data
menu and turns on periodic execution through a new autoExecute block.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
examples/batch builds four volumes and a blur-threshold-label pipeline
and runs them all with one tomviz-pipeline call. A test runs the
example, skipping when tomviz-pipeline has no label map writer.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Rename sets the editable flag before opening the editor, and Qt
reports that as an item change, so the deferred rename handler saw an
unchanged name and rebuilt the list, closing the editor before the
user could type. An unchanged name is now left alone.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
flush_dataset flattened a replaced array in Fortran order and handed
VTK a one-component array, so a script that replaced an RGB stack's
array left the image with three times too many scalars and the
channels scrambled. Interleave the components the way VTK stores them.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Recalling a viewpoint or playing a recorded change of exploded axis
went through the setters that refit the camera, which yanked it away
from the viewpoint just placed or off the path mid-flight. The axis
setter takes the same refitCamera switch the enable setter has, and
both are passed false from the recorded animations and Go To.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
The directory fingerprint only covered the recon_*.npy files, so a
scan whose arrays arrived before its angle config was never absorbed
until some later change. The config files count now.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
ParaView clamps the clipping range to cached scene bounds that it only
refreshes for its own representations, so data tomviz adds to the
renderer directly was cut once it grew or moved. The bounds are now
refreshed at the start of every render of every render view.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Operator search matches names, and "FFT (abs log)" did not contain
"Fourier". It is now "Fast Fourier Transform (FFT)", with a description
saying it shows the log magnitude, and the Fourier operators refer to
it by the new name.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Outputs copied the color map of the first input in port-name order, so
Fourier Mask took its mask's label colors. They now follow the primary
input and skip label maps, and an output with nothing to inherit, like
the FFT's, which opts out, starts from the default preset.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
New labels took the next color in sequence, so a label map with labels
removed from the middle, like the output of Remove Labels, shifted the
color of every label after them. A label now keeps its color in any
label map that holds it.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Save Data only offered persistent ports, so a transient output still in
memory, like the last step of a pipeline, could not be saved. Any port
holding data now can, and the dialog names transient ports whose data
was released and says how to get it back.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
ParaView's linkToOtherView() connects QWidget::close, a slot, as a
signal, which warned "signal not found" on every camera link and leaked
the link widget. tomviz now shows that widget itself and frees it once
it hides.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Opacity edits reach the proxy one event-loop turn late, so range
changes rescaled a copy that still held the placeholder nodes. Each
auto-contrast Apply squeezed the curve further, and Reset Range left
it narrowed.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Entering 2D always viewed a slice from one fixed side with a fixed up.
The camera now stays on the side it was on, with the in-plane axis
nearest its current up pointing up.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
The cut-out and exploded view grow, shrink and change setup smoothly
instead of snapping, slices and clips swing round to a new direction,
and volume solidity is recorded and can be swept. Clip normals are
recorded in the data coordinates they are restored in.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Orbits turn at constant speed unless their own Ease In/Out is checked,
new legs take 100 frames, and captions are centered on their position,
the bottom middle by default, with clearer field text.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Builds without git history, such as one from a release tarball, now
report 3.1.0 rather than 3.0.0. The SAM environments drop the beta
channel from the 3.0 prerelease and accept tomviz-pipeline up to 4.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Showing a clip again, as playback and Go To do, drew its arrow whenever
Show Arrow was checked, even with Show Plane off; so did a state file
that set Show Arrow after Show Plane. The arrow now needs both.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
Viewpoints record a volume's solidity too, so the tooltip listing what
they record now says so.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
File and Animation > Export Movie... still ran ParaView's exporter,
which has no MP4 writer in our packages; only the Animation Helper's
button opened the tomviz dialog. Both now do, and the dialog hides the
"x" between the custom width and height along with the fields.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
tomviz supports 3.14, and ParaView 6.1 and the rest of the test
environment, including the PyXRF stack, resolve for it on Linux, macOS
and Windows.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
visible_if hid a string parameter's field but left its label behind,
since the label is the field's buddy rather than the row's; Fourier
Peak Mask showed a bare "Peak Centers" with auto-detect on.

Signed-off-by: Patrick Avery <patrick.avery@kitware.com>
@psavery psavery closed this Sep 25, 2026
@psavery

psavery commented Sep 25, 2026

Copy link
Copy Markdown
Contributor Author

Meant to put this up against the NSLS2/tomviz repo...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants