Skip to main content

PyVista Quick Look

Press the space bar on a mesh file in the Finder and turn it with the mouse, the same way macOS already previews .ply and .usdz models.

Selecting flow.vtu and pressing space shows its surface in the Quick Look panel, coloured by the active scalars and free to rotate and zoom.

Requirements

  • macOS 12 or newer

Neither PyVista nor a compiler needs to be installed. The installer downloads a published build of the app and provisions its own PyVista; Xcode command line tools (xcode-select --install) are only needed to build from source.

Install

./scripts/install.sh

Then select a .vtu, .vtp, or .vtk file in the Finder and press space.

The installer fetches uv if it is missing, creates a private environment holding PyVista, installs the pvql helper, builds and registers PyVistaQuickLook.app, and loads PyVista once so the first preview is quick. Nothing outside ~/Library/Application Support/PyVistaQuickLook, ~/Applications, and ~/.local/bin is touched, and no existing Python environment is used or changed.

./scripts/install.sh --prefix /Applications                # install for all users
./scripts/install.sh --pyvista /path/to/venv/bin/pyvista   # use an existing PyVista
./scripts/install.sh --app /path/to/PyVistaQuickLook.app   # skip the build

Check the result with pvql doctor.

scripts/bootstrap.sh installs the same way from a URL, once this repository is published:

curl -LsSf https://raw.githubusercontent.com/user27182/pyvista-quicklook/main/scripts/bootstrap.sh | sh

What gets installed

About 270 MB, in ~/Library/Application Support/PyVistaQuickLook/venv:

  • PyVista, from git until 0.49 is released, installed with --no-deps
  • cvista[all], a VTK fork, in place of stock VTK
  • cyclopts, matplotlib, numpy, pillow, pooch, pyobjc-framework-Cocoa, scooby, typing-extensions

Installing PyVista with --no-deps and swapping stock VTK for cvista is what keeps this down; stock VTK alone is 591 MB against cvista's 136 MB.

Point --pyvista at an environment you already have to use that instead.

Supported files

36 extensions are claimed by default, including .vtk, .vti, .vtp, .vtu, .vtm, .vtkhdf, .pvd, .case, .exo, .foam, .cgns, .segy, and .xdmf.

pvql types        # what is claimed now
pvql types --all  # every format pvql knows about

Formats macOS already previews — .stl, .obj, .ply, .png — are deliberately not claimed, so the built-in viewer keeps handling them. Claim them by adding them to the config and reinstalling:

{ "extensions": { "add": [".stl", ".obj"], "remove": [".pdb"] } }

How it works

The app bundle contains a Quick Look extension that declares a uniform type identifier for each claimed extension. When the Finder previews one of those files, the extension hands it to a background render service, which reads it with PyVista, extracts the surface, colours the vertices by the active scalars, and writes a PLY. The extension shows that PLY in a SceneKit view, which is what makes the preview turnable.

Datasets with no surface to show fall back to a still image rendered by pyvista plot --off-screen --screenshot, which keeps the scalar bar and axes that the interactive view leaves out. Setting "interactive": false in the config always uses that still image.

Both are cached under ~/Library/Caches/PyVistaQuickLook, keyed by the file's path, size, and modification time, so editing a file invalidates its preview. Later previews of the same file come from the cache.

Every preview runs PyVista in a fresh process, and VTK is 600 MB of libraries, so the first one after a restart is slow until macOS has those pages cached. The service loads them in the background when it starts, which is at login and whenever it is reinstalled, so that cost is paid before you press space. pvql warmup does the same on demand, and "warm_on_start": false turns the automatic pass off.

Cell data is sampled onto the points before colouring. Surfaces are sent whole: decimating them costs more time than the larger file does, so max_scene_points is a safety valve for very large meshes rather than a routine step. Set it to 0 to never decimate.

When a preview fails, the Quick Look panel shows the error text instead.

The render service

macOS runs Quick Look extensions in a sandbox that VTK cannot render inside, so rendering happens in a launch agent instead. scripts/install.sh sets it up.

pvql service            # report whether it is loaded
pvql service --install  # (re)install and start it
pvql service --uninstall

Its output goes to ~/Library/Logs/pvqld.log.

Files in the Desktop, Documents, and Downloads folders

macOS keeps those folders private to each program, and the render service cannot read them. The Quick Look extension copies the file it was asked to preview into its own container so that the service can render it anyway.

A dataset that points at neighbouring files — .pvd, .vtm, .case, .foam — needs those neighbours, which the copy does not include. Keep such datasets outside those three folders, or grant the render service Full Disk Access in System Settings under Privacy & Security.

Configuration

~/Library/Application Support/PyVistaQuickLook/config.json

Key Default Effect
python set at install Interpreter of the PyVista environment
pyvista unset Optional pyvista executable, for still images
pvql discovered Absolute path to the pvql helper
interactive true Show a turnable surface instead of a still image
max_scene_points 2000000 Decimate only above this many points; 0 never does
colormap 'viridis' Colormap used to colour the surface
warm_on_start true Load PyVista and VTK when the render service starts
window_size [1024, 1024] Rendered preview size in pixels
timeout 60 Seconds before a render is abandoned
max_file_size_mb 512 Files above this size show a notice instead of a render
background null Background color passed to pyvista plot
extra_args [] Extra arguments appended to pyvista plot
cache true Reuse previously rendered previews
log false Append render activity to pvql.log beside the config file

Changing extensions requires a reinstall, because the claimed types are baked into the app bundle. Every other key takes effect on the next preview.

Commands

pvql preview FILE     # render and print the path of the cached PNG
pvql warmup           # load PyVista and VTK ahead of the first preview
pvql warm DIR         # render a directory ahead of time
pvql types            # list claimed extensions
pvql doctor           # check every part of the integration
pvql service          # manage the render service
pvql config --init    # write a config file with discovered defaults
pvql cache --clear    # delete cached previews

Troubleshooting

Run pvql doctor first; it checks the helper, the app, the extension registration, the service, and a real render.

  • The panel says the service is not answering. Run pvql service --install.
  • Nothing happens on space bar. Confirm the type is claimed with pvql types, then check that Finder resolves it: mdls -name kMDItemContentType yourfile.vtu should report an io.github.user27182.pyvista-quicklook.* type.
  • Previews are stale. pvql cache --clear.
  • A render fails. Set "log": true in the config; activity is appended to pvql.log beside it. The extension's own log is in ~/Library/Containers/io.github.user27182.PyVistaQuickLook.QuickLook/Data/tmp/.

Development

uv sync --group dev
uv run pytest tests/          # helper tests, with coverage
uv run pre-commit run --all-files
./scripts/build.sh            # compile and sign the app bundle

main is protected by a pre-commit hook, so work on a branch.

Releases are published to PyPI by CI through trusted publishing: push a v* tag and the publish job uploads from the release environment. That requires a matching pending publisher configured on PyPI for this repository and workflow.

Uninstall

./scripts/uninstall.sh
uv tool uninstall pyvista-quicklook

That removes the app, the private PyVista environment, the downloaded source, and the cache, leaving only the config file.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyvista_quicklook-0.2.0.tar.gz (173.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyvista_quicklook-0.2.0-py3-none-any.whl (28.3 kB view details)

Uploaded Python 3

File details

Details for the file pyvista_quicklook-0.2.0.tar.gz.

File metadata

  • Download URL: pyvista_quicklook-0.2.0.tar.gz
  • Upload date:
  • Size: 173.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for pyvista_quicklook-0.2.0.tar.gz
Algorithm Hash digest
SHA256 6349f115965fae0d7fcc6f9913f629f0a964981996e84e8175da48d84f26014e
MD5 e1f3d69a76969e86708818aa8904b4e8
BLAKE2b-256 9f0c00392d165de695bc9f83a9e2383e0cc72e90722cf587fa809e3c3537f800

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvista_quicklook-0.2.0.tar.gz:

Publisher: ci.yml on user27182/pyvista-quicklook

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyvista_quicklook-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pyvista_quicklook-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 82aefe0834b1fefdb99bb1ce8e9b851e1e8ebcaf1fe7152c7ea356ef887cdffc
MD5 0d4c68f6aaf513a5789747772001c9f5
BLAKE2b-256 bf05ca3c8b7c463e7ce9c7f60f0ed63d0541b0517f583d2cac6247898b5c4f18

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyvista_quicklook-0.2.0-py3-none-any.whl:

Publisher: ci.yml on user27182/pyvista-quicklook

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.5.1

2 files

0.5.0

2 files

0.4.0

2 files

0.3.1

2 files

0.3.0

2 files

This release

0.2.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page