| name | module-trimming |
| description | How cvista trims VTK down to PyVista's module closure — the three levers (module deny-list, NOWRAP classes, NOCOMPILE classes), the CVISTA_KEEP_CLASSES override, closure rules, and how to add, remove, or restore a class or module safely. Load when a PyVista path needs a class cvista dropped, when shrinking the wheel further, or when a build fails because something is missing. |
Module and class trimming
cvista ships ~84 modules (PyVista's measured closure) out of VTK's ~160, and within those modules
drops classes PyVista never touches. The result is a ~37 MB wheel vs stock's ~120 MB. The full
rationale and measurements are in docs/build-internals.md (levers 1–11). This skill is the
operational guide.
The three levers
All three live in cvista-config/. The class lists are append-only and closure-closed by
design — every entry is there because nothing kept refers to it.
-
Module deny-list — cvista-config/_modules_minimal.cmake
VTK_BUILD_ALL_MODULES OFF; only PyVista's closure is enabled via WANT/YES. This is ~53
direct C++ imports plus the IO format readers reached through the object factory plus the
rendering impl modules (RenderingContextOpenGL2, RenderingGL2PSOpenGL2).
-
Lever A — NOWRAP — cvista-config/_nowrap_classes.cmake (~1,173 classes)
The C++ compiles, but the Python wrapper is skipped. Closed under header references from kept
classes plus the vtkmodules bundled imports. Removing an entry is zero-risk (you only
add a wrapper back). Adding an entry needs a check that no kept Python path imports it.
-
Lever B — NOCOMPILE — cvista-config/_nocompile_classes.cmake (~742 classes)
Dropped entirely: no compile, no wrapper, no hierarchy. Closed under C++ source references,
transitive ::New() bases, and generated ObjectFactory registrations. Adding an entry
needs closure analysis (nothing kept may reference it, directly or via factory). Removing an
entry is safe.
The promotion hooks for both levers live in CMake/vtkModule.cmake.
Restoring a class (the common case)
A PyVista path needs vtkFooBar, but it was trimmed and import fails or a filter is missing.
- Find where it was dropped:
grep -rn vtkFooBar cvista-config/_nowrap_classes.cmake cvista-config/_nocompile_classes.cmake
- Two ways to restore:
- Validate: configure in a fresh build dir, build,
python smoke-cvista.py, then the bitexact
gate if the class affects a filter path.
Dropping a new class to shrink further
- Confirm nothing kept references it: search C++ sources for the type, check for
::New()
callers and ObjectFactory registrations, and confirm no kept Python path imports it.
- NOWRAP first (cheap, reversible). Only move to NOCOMPILE once you have proven the full
closure, since NOCOMPILE removes the hierarchy too.
- Add the entry to the appropriate list (append-only).
- Validate in a fresh build dir (a dirty cache hides generate-time breakage): configure,
build,
smoke-cvista.py, then the PyVista regression suite — the bar is zero new failures vs
stock 9.6.2.
Enabling a whole module
Edit cvista-config/_modules_minimal.cmake to WANT/YES the module. Watch for the WANT
silent-drop cascade: forcing a module to NO silently removes its dependents while configure
still succeeds, so a missing module can surface far from where you turned it off. Re-run a fresh
configure and read the module report.
Traps (read before extending)
- NOCOMPILE filters classes, not files. A class listed in a module's SOURCES or TEMPLATES
still compiles; do not delete its
.cxx/.h to "help".
- Not every
Testing/ directory is deletable; some carry a vtk.module or are referenced at
the top level.
- Structurally-required disabled modules (MPI, Catalyst, WebGPU, Java, SerializationManager)
must stay declared even though they are off.
- Source pruning does not change which classes compile (NOCOMPILE already excluded them), so a
configure + compile + import-smoke is sufficient to prove a prune; the full proof is still the
PyVista suite + bitexact gate.