A Python implementation of projected gradient-descent methods for repulsive optimization of polygonal curves, inspired by the paper Repulsive Curves by Yu, Schumacher, and Crane.
This project currently focuses on the (Sobolev preconditioned)
There is an official C++ implementation associated with the original work at https://github.com/ythea/repulsive-curves.
The package provides three command-line apps:
repcurve-flow Run projected gradient descent on an input OBJ curve.
repcurve-view Open an interactive viewer for a saved gradient flow run.
repcurve-plot-energy Plot energy histories from one or more saved runs.
This is the first working version of the Python package.
Planned future work includes:
- a cleaner Python API,
- better documentation for library usage,
- a fractional
$H^s$ Sobolev-gradient implementation, - more faithful comparisons with the methods in the Repulsive Curves paper,
- more examples and tests.
These instructions assume you have no Python, no conda, and no Miniforge installed.
Do not install Python separately.
Install Miniforge first. Miniforge provides conda/mamba, which this project uses to create a reproducible environment.
On Windows:
- Go to the official Miniforge download page at https://github.com/conda-forge/miniforge/releases.
- Download the Windows x86_64 installer.
- Run the installer.
- Accept the default options unless you know you want something else.
- Open Miniforge Prompt.
Check that conda is available:
conda --versionOptionally check whether mamba is available:
mamba --versionIt is okay if mamba is not found. The setup script will use mamba if available and fall back to conda otherwise.
Extract the project .zip.
The project folder should look roughly like this:
repulsive-curves-python/
├─ README.md
├─ LICENSE
├─ CITATION.cff
├─ pyproject.toml
├─ environment-base.yml
├─ environment-cpu.yml
├─ environment-cuda.yml
├─ scripts/
├─ src/
├─ inputs/
└─ outputs/
On Windows:
- Open Miniforge Prompt.
- In Miniforge Prompt, navigate to the project folder using the
cdcommand.
After navigating to the project folder, check that you are in the correct folder:
dirYou should see files such as:
README.md
pyproject.toml
Normal automatic install (inside Miniforge Prompt):
powershell -ExecutionPolicy Bypass -File scripts\setup_env.ps1This will:
- Create a conda environment named repulsive-curves.
- Install the base scientific dependencies.
- Try to install CUDA PyTorch if a NVIDIA GPU is detected.
- Fall back to CPU PyTorch if CUDA does not work.
- Install this project in editable mode.
- Check that the command-line apps are available.
To force CPU-only installation:
powershell -ExecutionPolicy Bypass -File scripts\setup_env.ps1 -CpuTo force a CUDA attempt:
powershell -ExecutionPolicy Bypass -File scripts\setup_env.ps1 -CudaThe default automatic install is recommended for most users. Installation will likely take a while. Whenever prompted to Confirm changes: [Y/n] during install, enter Y.
Each time you open a new Miniforge Prompt terminal and want to use the command-line apps directly, make sure to navigate to the project folder and activate the environment:
conda activate repulsive-curvescon Then the commands should be available:
repcurve-flow --help
repcurve-view --help
repcurve-plot-energy --helpIf those commands print help messages, installation worked.
The usual workflow is:
- Put an
.objcurve file ininputs/. - Run
repcurve-flowto generate an.npzresult file. - Visualize the result with
repcurve-view. - Compare energy histories with
repcurve-plot-energy.
Main app. Runs projected gradient descent on an input polygonal curve, keeping edge lengths fixed throughout the flow (the curve barycenter also remains fixed).
Basic usage:
repcurve-flow inputs\knot.obj --preconditioner H1 --energy tpe --iters 2000 --verboseThis loads initial curve
inputs/knot.obj
, runs the flow starting at that curve, and saves an .npz file containing results in:
outputs/
Run projected gradient descent of the tangent-point energy on the input curve using an
repcurve-flow inputs\knot.obj --preconditioner H1 --energy tpe --iters 2000 --verboseRun projected gradient descent of the Coulomb energy on the input curve using an
repcurve-flow inputs\knot.obj --preconditioner H1 --energy coulomb --iters 2000 --verboseRun projected gradient descent of the tangent-point energy on the input curve using an
repcurve-flow inputs\knot.obj --preconditioner L2 --energy tpe --iters 2000 --verboseRun projected gradient descent of the tangent-point energy on the input curve using no preconditioner:
repcurve-flow inputs\knot.obj --preconditioner none --energy tpe --iters 2000 --verboseRun on CUDA, if CUDA PyTorch is installed and working:
repcurve-flow inputs\knot.obj --preconditioner H1 --energy tpe --device cuda --iters 2000 --verboseSave each iterate as an .obj file:
repcurve-flow inputs\knot.obj --preconditioner H1 --energy tpe --iters 2000 --save-obj-frames--preconditioner H1 Use the H1 stiffness matrix preconditioner.
--preconditioner L2 Use the L2 mass matrix preconditioner.
--preconditioner none Use the raw Euclidean gradient.
--energy tpe Use tangent-point energy.
--energy coulomb Use Coulomb-type energy.
--iters T Maximum number of gradient flow iterations.
--device cpu Use CPU PyTorch.
--device cuda Use CUDA PyTorch.
--verbose Print per-iterate information.
--save-obj-frames Also save each iterate as an OBJ file.
For the full argument list, run command:
repcurve-flow --helpVisualization app. Opens an interactive PyVista/Qt viewer for a saved .npz run.
Basic usage:
repcurve-view outputs\knot_tpe_H1.npzThe viewer allows you to:
- scrub through the gradient flow iterates,
- play/pause the evolution,
- view projected-gradient arrows,
- toggle lighting/visualization options,
- export animation frames.
For help:
repcurve-view --helpEnergy plotting app. Plots energy histories from one or more saved .npz files.
Basic usage:
repcurve-plot-energy outputs\knot_tpe_H1.npz --labels "TPE H1"Compare two runs:
repcurve-plot-energy outputs\knot_tpe_H1.npz outputs\knot_coulomb_H1.npz --labels "TPE H1" "Coulomb H1"Compare
repcurve-plot-energy outputs\knot_tpe_H1.npz outputs\knot_tpe_L2.npz outputs\knot_tpe_none.npz --labels "H1" "L2" "raw"For help:
repcurve-plot-energy --helpThe input should be a polygonal curve stored in .obj format.
The file should contain:
v x y z
lines for vertices, and
l i j
lines for edges.
Example closed curve:
v 1 0 0
v 0 1 0
v -1 0 0
v 0 -1 0
l 1 2
l 2 3
l 3 4
l 4 1
Example open curve:
v 0 0 0
v 1 0 0
v 2 1 0
v 3 1 0
l 1 2
l 2 3
l 3 4
The curve should be a single polygonal chain (open or closed).
repcurve-flow saves .npz files in the outputs/ folder.
Each saved .npz file contains data such as (but not limited to):
traj Curve vertices at each gradient flow iterate.
grads Projected-gradient vectors (along the curve) at each iterate.
energies Energy value at each iterate.
step_durations Wall-clock timing data.
closed Whether the input curve was closed.
These .npz files are used by:
repcurve-view
repcurve-plot-energy
repulsive-curves-python/
│
├─ README.md
├─ pyproject.toml
├─ environment-base.yml
├─ environment-cpu.yml
├─ environment-cuda.yml
├─ .gitignore
│
├─ scripts/
│ ├─ setup_env.ps1
│ └─ setup_env.sh
│
├─ .vscode/
│ ├─ extensions.json
│ ├─ settings.json
│ ├─ tasks.json
│ └─ launch.json
│
├─ inputs/
│ └─ put input OBJ files here
│
├─ outputs/
│ └─ generated output files
│
└─ src/
└─ repulsive_curves/
├─ __init__.py
├─ curve.py
├─ energies.py
├─ gradient_descent.py
├─ run_gradient_flow.py
├─ curve_evolution_visualization.py
└─ plot_energy_histories.py
After installation:
- Open the project folder in VS Code.
- Install the recommended extensions if prompted.
- Open a terminal in VS Code.
- Run:
conda activate repulsive-curves- Press
Ctrl+Shift+P. - Search for Python: Select Interpreter.
- Select the environment named repulsive-curves.
This project is released under the MIT License. See the LICENSE file for details.
This is an unofficial Python implementation/package inspired by the paper:
Christopher Yu, Henrik Schumacher, and Keenan Crane.
Repulsive Curves.
ACM Transactions on Graphics 40, no. 2, Article 10, 2021.
DOI: 10.1145/3439429.
The original paper and official C++ implementation are separate works by their respective authors. This project is not an official release of the original authors.
If you use this software in academic work, please cite both this software and the original paper.
This repository includes a CITATION.cff file so GitHub and citation tools can generate citation information automatically.