ipc-toolkit: Collision queries as a library boundary
ipc-toolkit provides geometric building blocks for contact-aware simulation. This fork contains collision meshes, broad-phase candidates, continuous collision detection and contact-related energies. An external simulation still owns its time stepping and solve loop.
Repository languagesC++ 94.46%5
Shares calculated from GitHub Linguist bytes.
| Language | % | Bytes |
|---|---|---|
| C++ | 2,400,346 | |
| CMake | 75,800 | |
| Python | 53,463 | |
| Cuda | 9,561 | |
| Dockerfile | 2,051 |
Overview
Why it exists
Friction and contact physics toolkit for robust computer graphics and finite element simulation.
Best fit
Nonlinear continuous contact mechanics in 3D physics engines.
Getting started
These commands come from the repository documentation. They were not run during this review.
pip install ipctkpip install git+https://github.com/ipc-sim/ipc-toolkitpip install .python -c "import ipctk"mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DIPC_TOOLKIT_BUILD_PYTHON=ON ..
make -j$(nproc)Repository references
Excerpts from the repository’s guides, in their original language. Links open the inspected source revision.
Prerequisites and first run
Quick Start
README.md
Installation
python/README.md
Installation
docs/PYPI_README.md
Development and contributions
Contributing
README.md
This project is open to contributors! Contributions can come in the form of feature requests, bug fixes, documentation, tutorials, and the like. We highly recommend filing an Issue first before submitting a Pull Request. Simply fork this repository and make a Pull Request! We would appreciate:
- Implementation of new features
- Bug Reports
- Documentation
- Testing
Contributing
docs/PYPI_README.md
This project is open to contributors! Contributions can come in the form of feature requests, bug fixes, documentation, tutorials, and the like. We highly recommend filing an Issue first before submitting a Pull Request. Simply fork this repository and make a Pull Request! We would appreciate:
- Implementation of new features
- Bug Reports
- Documentation
- Testing
Contributing
docs/CONTRIBUTING.md
Source documentation
README.mdpython/README.mddocs/PYPI_README.mddocs/CONTRIBUTING.mddocs/source/developers/contributing.rstdocs/source/tutorials/getting_started.rst
6 documents read from 6 candidates.
Features and components 2
- Geometry and collision queries
- ipc.hpp accepts a CollisionMesh and vertex positions for intersection and collision-free-step queries. Broad-phase and narrow-phase CCD implementations are explicit parameters with defaults, separating candidate discovery from detailed tests.
- Contact calculations
- The source tree separates distance, barrier, friction, tangent and potential modules. These components support a caller’s objective and derivatives; they do not automatically integrate an entire physical scene.
Architecture
The components and their connections remain available as text. The diagram adds an interactive view.
- External simulation
- Collision mesh and vertex motion
- Broad-phase candidates
- Narrow-phase CCD
- Collision query result
Links verified in the repository.
Mermaid Interactive diagram (loads on open)
System overview of the components and connections verified in the repository.

flowchart LR
n0["External simulation"]
n1["Collision mesh and vertex motion"]
n2["Broad-phase candidates"]
n3["Narrow-phase CCD"]
n4["Collision query result"]
n0 --> n1
n1 --> n2
n2 --> n3
n3 --> n4
n4 --> n0
Text version of the diagram
- External simulation → Collision mesh and vertex motion
- Collision mesh and vertex motion → Broad-phase candidates
- Broad-phase candidates → Narrow-phase CCD
- Narrow-phase CCD → Collision query result
- Collision query result → External simulation
Follow one path through the code
Follow is_step_collision_free from the public declaration into its implementation. Its result answers a geometric query for a proposed motion. The caller must decide how that result changes a step, line search or contact solve.
Algorithm
Problem
Decide whether a CollisionMesh at given vertex positions intersects, or whether a proposed vertex displacement stays collision-free, so a contact-aware simulator can query geometry without owning the full time-step loop.
Inputs
A CollisionMesh plus current (and optionally proposed) vertex positions; broad-phase and narrow-phase CCD strategies are explicit parameters with defaults.
Outputs
Intersection or collision-free-step answers, plus contact-related quantities (distances, barriers, friction helpers) consumed by the caller’s objective — not a full scene solve.
Pseudocode (source-backed)
given mesh M, positions x, optional next positions x'
if has_intersections(M, x): report contact candidates
if not is_step_collision_free(M, x, x'): reject or shorten step
else: assemble contact energies/derivatives for the caller’s solver- 1. Build or accept a collision mesh
The library expects a CollisionMesh that separates geometry from the caller’s simulation state.
- 2. Broad-phase candidates
Candidate pairs are discovered with an explicit broad-phase strategy before expensive narrow tests.
- 3. Narrow-phase CCD / intersection
ipc.hpp entry points test intersections at a configuration or whether a displacement remains collision-free.
- 4. Contact quantities for the solver
Distance, barrier, friction and related modules supply values and derivatives; the external simulation still owns time stepping.
No asymptotic complexity claim is published in this fork’s inspected headers; cost depends on mesh size, broad-phase choice and CCD settings used by the caller.
Types and file structure
140 declared types, with 12 in the base-relationship overview.
Type diagram
classDiagram
direction TB
class ta4ad2d054a1a["CXXFunctionGenerator"] {
__init__()
signature()
__call__()
}
class t0935cb7a441b["CXXGradientGenerator"] {
__init__()
}
class t1aec9e647746["CXXJacobianGenerator"] {
__init__()
}
class t6c43b7865a81["CXXHessianGenerator"] {
__init__()
}
class t05fe515aed0d["Inertia"] {
__init__()
__call__()
gradient()
hessian()
}
class tcb5b8ab75455["PyBarrier"] {
first_derivative()
second_derivative()
units()
}
class te947d03a9485["PyBroadPhase"] {
name()
build()
clear()
detect_vertex_vertex_candidates()
}
class ta8c42662e683["PyNarrowPhaseCCD"] {
point_point_ccd()
point_edge_ccd()
point_triangle_ccd()
edge_edge_ccd()
}
class tb0adabdf7fe2["PyNonlinearTrajectory"] {
max_distance_from_linear()
}
class tc83b025ce434["PyIntervalNonlinearTrajectory"] {
max_distance_from_linear()
}
class t9ee9c14a4b05["PairHash"] {
<<struct>>
}
class t5a3d1613cb4b["SparseCanCollide"] {
SparseCanCollide()
}
ta4ad2d054a1a <|-- t0935cb7a441b
ta4ad2d054a1a <|-- t1aec9e647746
t1aec9e647746 <|-- t6c43b7865a81
class b7bd3eedf5849["Barrier"] {
<<unresolved_base>>
}
b7bd3eedf5849 <|-- tcb5b8ab75455
class b80b43ba1bca8["BroadPhase"] {
<<unresolved_base>>
}
b80b43ba1bca8 <|-- te947d03a9485
class b1ced31ba20e0["NarrowPhaseCCD"] {
<<unresolved_base>>
}
b1ced31ba20e0 <|-- ta8c42662e683
class b9fe354f68d01["NonlinearTrajectory"] {
<<unresolved_base>>
}
b9fe354f68d01 <|-- tb0adabdf7fe2
class b28bdf016fc91["IntervalNonlinearTrajectory"] {
<<unresolved_base>>
}
b28bdf016fc91 <|-- tc83b025ce434
Unresolved bases remain labelled; full signatures are not reconstructed.
Type index
CXXFunctionGenerator(class) ·notebooks/generate_cpp_code.py:56Methods in the overview:
__init__, signature, __call__.CXXGradientGenerator(class) ·notebooks/generate_cpp_code.py:81Methods in the overview:
__init__.Declared bases:
CXXFunctionGenerator.CXXJacobianGenerator(class) ·notebooks/generate_cpp_code.py:88Methods in the overview:
__init__.Declared bases:
CXXFunctionGenerator.CXXHessianGenerator(class) ·notebooks/generate_cpp_code.py:98Methods in the overview:
__init__.Declared bases:
CXXJacobianGenerator.Inertia(class) ·python/examples/solver.py:15Methods in the overview:
__init__, __call__, gradient, hessian.PyBarrier(class) ·python/src/barrier/barrier.cpp:7Methods in the overview:
first_derivative, second_derivative, units.Declared bases:
Barrier.PyBroadPhase(class) ·python/src/broad_phase/broad_phase.cpp:8Methods in the overview:
name, build, clear, detect_vertex_vertex_candidates.Declared bases:
BroadPhase.PyNarrowPhaseCCD(class) ·python/src/ccd/narrow_phase_ccd.cpp:7Methods in the overview:
point_point_ccd, point_edge_ccd, point_triangle_ccd, edge_edge_ccd.Declared bases:
NarrowPhaseCCD.PyNonlinearTrajectory(class) ·python/src/ccd/nonlinear_ccd.cpp:7Methods in the overview:
max_distance_from_linear.Declared bases:
NonlinearTrajectory.PyIntervalNonlinearTrajectory(class) ·python/src/ccd/nonlinear_ccd.cpp:17Methods in the overview:
max_distance_from_linear.Declared bases:
IntervalNonlinearTrajectory.PairHash(struct) ·python/src/collision_mesh.cpp:10SparseCanCollide(class) ·python/src/collision_mesh.cpp:26Methods in the overview:
SparseCanCollide.
Reference
463 / 463 eligible files read (646 in the tree); 0 oversized, 0 failed reads and 74 syntax diagnostics.
What the scan covers
Known dependency/build folders, credential files and binaries are excluded. The scan covers READMEs, recognized manifests and parser-supported source files.
Linguist statistics cover the whole repository and may include other languages.
File map
flowchart TD
root["ipc-toolkit"]
f0["CMakeLists.txt"]
root --> f0
f1["src/ipc/ipc.cpp"]
root --> f1
f2["src/ipc/ipc.hpp"]
root --> f2
f3["README.md"]
root --> f3
f4["pyproject.toml"]
root --> f4
f5["setup.py"]
root --> f5
f6["notebooks/find_ipctk.py"]
root --> f6
f7["notebooks/generate_cpp_code.py"]
root --> f7
f8["notebooks/parula.py"]
root --> f8
f9["notebooks/utils.py"]
root --> f9
f10["python/CMakeLists.txt"]
root --> f10
f11["python/README.md"]
root --> f11
f12["python/_find_ipctk.py"]
root --> f12
f13["tests/CMakeLists.txt"]
root --> f13
f14["python/examples/find_ipctk.py"]
root --> f14
f15["python/examples/lbvh.py"]
root --> f15
Files to read 3
References
Project facts
Related article: IPC Toolkit: the contact library behind a simulation.