Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
223 changes: 223 additions & 0 deletions modsim_toolbox/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
.DS_Store
.dev/

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[codz]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py.cover
*.lcov
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
# Pipfile.lock

# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# uv.lock

# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
# poetry.lock
# poetry.toml

# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
# pdm.lock
# pdm.toml
.pdm-python
.pdm-build/

# pixi
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
# pixi.lock
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
# in the .venv directory. It is recommended not to include this directory in version control.
.pixi/*
!.pixi/config.toml

# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/

# Celery stuff
celerybeat-schedule*
celerybeat.pid

# Redis
*.rdb
*.aof
*.pid

# RabbitMQ
mnesia/
rabbitmq/
rabbitmq-data/

# ActiveMQ
activemq-data/

# SageMath parsed files
*.sage.py

# Environments
.env
.envrc
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/

# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
# .idea/

# Abstra
# Abstra is an AI-powered process automation framework.
# Ignore directories containing user credentials, local state, and settings.
# Learn more at https://abstra.io/docs
.abstra/

# Visual Studio Code
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# you could uncomment the following to ignore the entire vscode folder
# .vscode/
# Temporary file for partial code execution
tempCodeRunnerFile.py

# Ruff stuff:
.ruff_cache/

# PyPI configuration file
.pypirc

# Marimo
marimo/_static/
marimo/_lsp/
__marimo__/

# Streamlit
.streamlit/secrets.toml
1 change: 1 addition & 0 deletions modsim_toolbox/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.12
45 changes: 45 additions & 0 deletions modsim_toolbox/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# ModSim Toolbox

ModSim Toolbox is a minimal example of building reusable, accelerated, and
differentiable infrastructure for multimodal simulation on top of
[fVDB](https://github.com/AcademySoftwareFoundation/openvdb/tree/master/fvdb).
It is not a simulator for any particular sensor. Instead, it factors out the
geometric work that most sensor simulations share, so that the physics
specific to a given modality can be written separately, on top of a common
tensor-based interface.

## Components

The toolbox covers three areas:

- **geometry** — rotations and the coordinate frames a sensor is mounted in.
- **voxels** — converting group-jagged meshes into an `fvdb.GridBatch`, and
carrying per-corner attributes onto the resulting voxels.
- **ray tracing** — casting a bundle of rays against a voxel grid batch using
fVDB's voxel ray tracing, finding the nearest surface each ray hits, and
computing visibility between a surface and a direction (for example,
toward a light source).

There is also a viewer (`visualization.Visualizer`) for displaying the
result. Because ray tracing runs against voxel grids rather than triangle
meshes, and because fVDB's operations are differentiable, the same trace can
be used both for fast forward simulation and for gradient-based tasks such as
calibration or inverse rendering.

The toolbox does not model physics: it has no notion of spectra, materials,
or units of radiance, and it does not read files. Every function operates on
tensors and returns tensors, and the modules are stateless, with the
exception of `visualization.Visualizer`, which owns a live viser server. What
a modality's outputs represent — radiance, a range value, a label — is
decided by the caller. This is what allows the same underlying trace to
support different modalities, such as a panchromatic camera or a
spectrometer, without changes to the toolbox itself.

## Example

[`examples/car`](examples/car) shows one modality built on the toolbox: a
DIRSIG vehicle-glint scene, voxelized per OBJ group, imaged by the
panchromatic frame camera described in the scene's own platform file, and
shaded using solar irradiance and Beard-Maxwell BRDFs. The physics specific
to that example — spectral reflectance, shading, band integration — is
implemented in the example itself, not in the toolbox.
1 change: 1 addition & 0 deletions modsim_toolbox/examples/car/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/scene
43 changes: 43 additions & 0 deletions modsim_toolbox/examples/car/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Car: vehicle-glint example

This example uses the toolbox to simulate a panchromatic frame camera imaging
a car, based on RIT's DIRSIG vehicle-glint demo scene. The toolbox handles
voxelization and ray tracing; this example adds the optical physics —
solar irradiance, Beard-Maxwell BRDFs, spectral reflectance, and band
integration — in `radiometry.py` and `shade`.

## Layout

| File | Contents |
|---|---|
| `main.py` | `build_scene`, `build_sensor`, `simulate`, `serve` |
| `radiometry.py` | Solar spectrum, Beard-Maxwell, Fresnel, spectral resampling |
| `loader.py` | Wavefront OBJ and DIRSIG `.platform` / `.ppd` / `.mat` / `.ems` / `.fit` parsing |

## Scene data

The scene data is not checked in. Download the DIRSIG vehicle-glint demo
scene from the [DIRSIG demo scenes page](https://dirsig.cis.rit.edu/) and
unpack it into `scene/`, subject to RIT's license terms for that data. This
example reads five files from it:

```
scene/geometry/infiniti_g35_vn.obj car geometry, per group, with vertex normals
scene/demo.platform 320x240 at 16 um, f = 100 mm, 0.400-0.800 um "Pan"
scene/demo.ppd platform pose: 150 m up, yawed 135 deg
scene/materials/demo.mat material table, referencing:
scene/materials/*.ems, *.fit emissivity curves and Beard-Maxwell fits
```

The 6 km ground plane declared in the scene is replaced with a 40 m patch,
and capture time and location are constants in `main.py` rather than parsed
from the scene files. Everything else the demo ships is unused.

## Running it

```bash
uv run python main.py
```

This opens a viser page showing the voxelized scene alongside the simulated
focal plane, with controls for solar azimuth, elevation, and shadows.
Loading