Skip to content


Switch branches/tags


A simulation framework for discrete elastic rods and X-Shells written in C++ with Python bindings. This is the codebase for our 2019 Siggraph paper, X-Shells. Check out the section on reproducing the paper figures for pointers to some Jupyter notebooks to try.

Getting Started

C++ Code Dependencies

The C++ code relies on Boost and CHOLMOD/UMFPACK, which must be installed separately. Some parts of the code (actuator sparsification, design optimization) also depend on the commercial optimization package Knitro; these will be omitted from the build if Knitro is not found.

The code also relies on several dependencies that are included as submodules: MeshFEM, libigl, spectra, and visvalingam_simplify.


You can install all the mandatory dependencies on macOS with MacPorts:

# Build/version control tools, C++ code dependencies
sudo port install cmake boost suitesparse ninja
# Install nodejs/npm using nvm
curl -o- | bash
nvm install 17 && nvm use 17

Ubuntu 19.04

A few more packages need to be installed on a fresh Ubuntu 19.04 install:

# Build/version control tools
sudo apt install git cmake ninja-build
# Dependencies for C++ code
sudo apt install libboost-filesystem-dev libboost-system-dev libboost-program-options-dev libsuitesparse-dev
# LibIGL/GLFW dependencies
sudo apt install libgl1-mesa-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev
# Dependencies (pybind11, jupyterlab/notebooks)
sudo apt install python3-pip npm
# Ubuntu 19.04 packages an older version of npm that is incompatible with its nodejs version...
sudo npm install npm@latest -g

Obtaining and Building

Clone this repository recursively so that its submodules are also downloaded:

git clone --recursive

Build the C++ code and its Python bindings using cmake and your favorite build system. For example, with ninja:

cd ElasticRods
mkdir build && cd build
cmake .. -GNinja

Running the Jupyter Notebooks

The preferred way to interact with the rods code is in a Jupyter notebook, using the Python bindings.

JuptyerLab and Extensions

To run the Jupyter notebooks, you will need to install JupyterLab and my fork of the pythreejs library. JupyterLab can be installed through pip, and the following commands should set up all the requirements on both macOS and Ubuntu. Using a virtual environment is strongly recommended!

pip3 install wheel # Needed if installing in a virtual environment
pip3 install jupyterlab ipykernel==5.5.5 # Use a slightly older version of ipykernel to avoid cluttering notebook with stdout content.
# If necessary, follow the instructions in the warnings to add the Python user
# bin directory (containing the 'jupyter' binary) to your PATH...

git clone
cd pythreejs
pip3 install -e .
cd js
jupyter labextension install .

pip3 install matplotlib scipy

You may need to add the following to your shell startup script for the installation of pythreejs's dependencies during pip3 install -e . to succeed:

export NODE_OPTIONS=--openssl-legacy-provider;

Launch Jupyter lab from the root python directory:

cd python
jupyter lab

Now try opening and running an example notebook, e.g., python/Demos/MantaRayDemo.ipynb. Several other demo notebooks are included in the same directory to introduce you to some of the features of the codebase.

Reproducing the Paper Figures

Each figure in the paper that includes an X-Shell simulation has corresponding Jupyter notebook(s) in python/XShellSiggraphPaperFigures. Note that these notebooks generate the raw data used to produce the figures, but the final renderings for most figures were produced in Rhino using scripts that are not included in this release. Basic preview renderings are available in the in-notebook viewer.


Elastic Rod and X-Shell Simulation






No releases published


No packages published