This is the evaluation codebase for reproducing the quantitative simulation experiments (Tables 1 and 2) from the paper. It runs NVIDIA Kaolin for reduced-order simulation using RKPM and MLP (Simplicits) skinning weights, and evaluates against FEM ground truth on the Beam, Thingi10K, and SimReady datasets.
- Python 3 (tested with 3.10)
- CUDA (tested with 12.4)
- uv (Python package manager)
git clone --recursive https://github.com/nv-tlabs/freeform.git
cd freeform
git lfs pull
# If you already cloned without --recursive:
# git submodule update --init
# Create virtual environment (Python 3.10 or 3.11; PyTorch cu124 has no 3.12 wheels)
uv sync --python 3.10
# Install PyTorch with CUDA and numpy (numpy must be installed before kaolin).
# The cu124 torch wheels depend on nvidia-* runtime packages that live on PyPI,
# not on download.pytorch.org. Since --index-url replaces PyPI rather than
# adding to it, PyPI must be supplied as an extra index or resolution fails.
uv pip install torch==2.5.1 torchvision==0.20.1 \
--index-url https://download.pytorch.org/whl/cu124 \
--extra-index-url https://pypi.org/simple \
--index-strategy unsafe-best-match
# setuptools is required because kaolin is built with --no-build-isolation
# and a bare uv virtualenv does not include it. It must be <81: kaolin's build
# imports pkg_resources, which setuptools removed in 81.
uv pip install numpy "setuptools<81"
# Install kaolin (tested with commit 35041a8c)
uv pip install "kaolin @ git+https://github.com/NVIDIAGameWorks/kaolin.git@35041a8c" --no-build-isolation
# Install remaining dependencies
# libigl is pinned: the surface repair (split_nonmanifold) determines the vertex
# ordering of the surface mesh, which the pull_farthest_points boundary condition
# depends on. A different version can silently change the generated boundaries.
uv pip install warp-lang==1.10.0 libigl==2.6.2 meshio pandas scipy gdown nvtx omegaconf trimesh potpourri3d polyscopeAll downloaded and processed data goes into the datasets/ directory. Create it or symlink it to a location with sufficient disk space:
mkdir -p datasets
# or: ln -s /path/to/your/data datasetsBeam geometry is included in the repo under data/beam/ (tracked with Git LFS).
# Run via `uv run` so the venv's gdown is on PATH
uv run bash data/download_thingi10k.sh
uv run python data/export_thingi10k.py19 tetrahedral meshes (.msh) generated by TetWild/fTetWild from NVIDIA SimReady assets, along with per-voxel material properties (Young's modulus, Poisson's ratio, density) predicted by VoMP (.npz) included in the repo via Git LFS (data/simready_tet_npz.tar.gz).
bash data/unzip_simready.sh
uv run python data/export_simready.pyBoundary condition YAML configs are included in config/. The Thingi10K boundary
.npz files are generated by data/export_thingi10k.py in step 2 rather than shipped,
so the repository does not redistribute geometry derived from third-party Thingi10K
models; the Beam and SimReady .npz files are included. Simulation and model creation
configs are generated from CSV files:
uv run python scripts/generate_thingi10k_configs.py
uv run python scripts/generate_simready_configs.pyThe pipeline scripts run the full pipeline end-to-end: FEM ground truth, model creation (RKPM + MLP), simulation, and evaluation. Each step skips automatically if its output already exists. Steps 5-8 are included.
# m=32 handles only
bash scripts/run_beam.sh
# Full handle sweep: m=6, 9, 16, 32 (reproduces Table 1)
bash scripts/run_beam.sh --handle-sweep# 20 examples from data/thingi10k_20examples.csv
# It takes a while to run FEM simulation for the first time.
bash scripts/run_all_thingi10k.sh# 19 examples from data/simready_20examples.csv
# It takes a while to run FEM simulation for the first time.
bash scripts/run_all_simready.shThe following sections show how to run individual steps. Examples use:
export FID=96123 # Thingi10K ID
export BC=fix_front_5percent_ym1e4 # Boundary ConditionFEM ground truth is computed using warp.fem solver (included as a submodule in VoMP).
uv run python fem/fem_sim_gt.py \
--config-file config/thingi10k/${FID}/${BC}.yaml \
--save-vol-results --cg_iters 10000 --cg_tol 1e-8 --fp64 --no-ui# RKPM (eigenanalysis-based, ~3-10s)
uv run python sim/create_model.py --config config/thingi10k/${FID}/create_rkpm.yaml
# MLP (neural network, ~2-5min)
uv run python sim/create_model.py --config config/thingi10k/${FID}/create_mlp.yaml# RKPM
uv run python sim/run_sim.py --config config/thingi10k/${FID}/sim_rkpm_fix_front_5percent.yaml
# MLP
uv run python sim/run_sim.py --config config/thingi10k/${FID}/sim_mlp_fix_front_5percent.yamlCompares simulation output against FEM ground truth:
uv run python eval/compute_vertex_error.py \
--gt-path "datasets/Thingi10K/processed/${FID}/fem_sim_${BC}/frame_{:04d}.msh" \
--pred-path datasets/Thingi10K/output/${FID}/sim_result_rkpm_model_${BC}.pthMeasures how well the skinning weight basis can represent FEM ground truth deformations via least-squares projection, independent of the simulation solver:
uv run python eval/compute_residual_error.py \
--gt-path "datasets/Thingi10K/processed/${FID}/fem_sim_${BC}/frame_{:04d}.msh" \
--model-path datasets/Thingi10K/output/${FID}/rkpm_model.pthResidual error can also be computed as part of the full pipeline by passing --residual-error:
uv run python scripts/run_thingi10k_example.py --fid ${FID} --ym 1e4 --fix-side front --residual-error
uv run python scripts/run_simready_example.py --fid ${FID} --residual-errorPrint comparison tables across all examples:
uv run python eval/summarize_errors.py --dataset beam
uv run python eval/summarize_errors.py --dataset thingi10k
uv run python eval/summarize_errors.py --dataset simready
uv run python eval/summarize_residual_errors.py --dataset thingi10k # in supplementary docuementVisualize simulation results side-by-side with FEM ground truth using Polyscope:
uv run python scripts/visualize_sim.py \
--gt "datasets/Thingi10K/processed/${FID}/fem_sim_${BC}/frame_{:04d}.msh" \
--pred datasets/Thingi10K/output/${FID}/sim_result_rkpm_model_${BC}.pth \
--labels "FEM GT" "RKPM"freeform/
├── config/ # Boundary conditions (YAML+NPZ) and generated sim configs
│ ├── beam/
│ ├── thingi10k/
│ └── simready/
├── data/ # Download/export scripts, beam geometry, CSV example lists
├── datasets/ # Data directory (gitignored)
├── eval/ # Evaluation scripts
├── fem/ # FEM ground truth simulation (extends VoMP's warp.fem solver)
├── third_party/VoMP/ # VoMP submodule, used only for FEM ground truth solver
├── scripts/ # Pipeline runners, config generators, visualization
└── sim/ # Model creation, simulation, and kaolin extensions
├── create_model.py # Create RKPM/MLP skinning weights
├── run_sim.py # Run reduced-order simulation
├── simplicits_ext.py # Kaolin overloads (see docstring for details)
└── utils.py # Sampling utilities
If you use this code in your research, please cite:
@inproceedings{xiang2026freeform,
title = {FreeForm: Reduced-Order Deformable Simulation from Particle-Based Skinning Eigenmodes},
author = {Xiang, Donglai and Modi, Vismay and Dagli, Rishit and Trusty, Ty and Daviet, Gilles and Chen, Anka He and Sharp, Nicholas and Levin, David I.W.},
booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},
year = {2026}
}The source code in this project is licensed under the Apache License, Version 2.0, with the following notes:
fem/mfem/softbody_sim.py,fem/material_loader.py,fem/fem_sim_gt.py, andsim/simplicits_ext.pyare derived from the Apache-2.0 licensed VoMP and Kaolin projects; their headers preserve the upstream notices. See THIRD_PARTY_NOTICES.data/simready_tet_npz.tar.gzandconfig/simready/**/*.npzare derived from NVIDIA SimReady assets and are licensed under the NVIDIA License (Non-Commercial), reproduced in full at the end of LICENSE. This is not an open source license: it limits use of those files to research or evaluation purposes only.- The Beam data (
data/beam/,config/beam/**/*.npz) is procedurally generated and is covered by the Apache License along with the source. - No Thingi10K data is distributed here. Its boundary conditions are generated
locally by
data/export_thingi10k.pyfrom meshes you download yourself, which carry their own per-model Thingiverse licenses.
Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.