v1.1.1 (Aug 18, 2023)

  • Logo by @zfergus in #52

  • Fix vertex-vertex == and < functions to be order independent

    • This allows vertex-vertex constraints merge correctly

  • Update Tight Inclusion CCD

v1.1.0 (Jul 25, 2023)

Large refactoring to make the code more object-oriented rather than passing objects to functions. Other changes include the friction potential now being a function of velocity, bug fixes, and a new tutorial.


  • Large Refactor in #25

    • construct_collision_candidates(..., candidates)

    • is_step_collision_free(candidates, ...)candidates.is_step_collision_free(...)

    • compute_collision_free_stepsize(candidates, ...)candidates.compute_collision_free_stepsize(...)

    • compute_barrier_potential*(constraints, ...)constraints.compute_potential*(...)

    • compute_shape_derivative(constraints, ...)constraints.compute_shape_derivative(...)

    • compute_minimum_distance(constraints, ...)constraints.compute_minimum_distance(...)

    • construct_friction_constraint_set(..., friction_constraints)

    • compute_friction_*(..., friction_constraints, ...)friction_constraints.compute_*(...)

    • Generic CollisionStencil parent class to Candidates, CollisionConstraints, and FrictionConstraints.

    • Renamed Constraints to CollisionConstraints

    • Replaced single letter variable names V, E, F with vertices/positions, edges, faces

    • Renamed *_index*_id

    • Replaced inflation_radius = min_distance / 1.99 with inflation_radius = min_distance / 2 and use rounding mode to conservativly inflate AABBs

    • CollisionConstraints::use_convergent_formulation and are_shape_derivatives_enabled must now be accessed through getter and setter functions

    • Friction potentials are now functions of velocity. Previously V0 and V1 were passed and U = V1-V0. This limited the integration scheme to implicit Euler. Upstream this means you need to multiply the potential by \(1/(dv/dx)\) to get the correct friction force.

      • Change input \(\epsilon_vh\) to \(\epsilon_v\) in #37 to reflect the fact that friction is defined in terms of velocity instead of displacement now.

  • Changed default project_hessian_to_psd to false in #30

  • Update website with a tutorial (#31) and version dropdown list (#34)

  • Switch from templates to using Eigen::Ref in #28

  • Speed up the CCD by limiting the maximum minimum distance to 1e-4 in #43

  • Fix the bug pointed out in #41 in #42. Namely, to get units of distance in the barrier we should divide the original function by \(\hat{d}\cdot(\hat{d} + 2d_{\min})^2\) when using distance squared. Before it was being divided by \(2d_{\min} \hat{d} + \hat{d}^2\).

  • Fix build for IPC_TOOLKIT_WITH_CORRECT_CCD=OFF in #44

  • Switched from FetchContent to CPM in #48. This provides better caching between builds. Additionally, made robin-map and Abseil optional dependencies.

  • Add the CFL-Inspired Culling of CCD as described in Section 3 of the Technical Supplement to IPC in #50

v1.0.0 (Feb 21, 2023)

This is the first official release. 🚀

This is a stable release of the toolkit prior to refactoring the code and making updates to the API.


  • Added a minimum distance optional parameter to all CCD functions (const double min_distance = 0.0) in #22. This is placed as the first optional argument which can break calling code if optional parameters were previously used.

  • Added CollisionMesh in #7 to wrap up face and edges into a single data structure.

    • Removes Support for ignoring internal vertices. Instead, users should use the CollisionMesh to map from the full mesh to the surface mesh.

    • This also includes a to_full_dof function that can map the reduced gradient/hessian to the full mesh’s DOF.


2021-10-05 (9e2cc2a)


  • Added implicits source folder to organize point-plane collisions

2021-09-05 (9e2cc2a)


  • Added support for point vs. (static) analytical plane contact

2021-08-21 (acf2a80)


  • Changed CMake target name to ipc::toolkit

2021-07-26 (1479aae)


  • Updated the CMake system to use modern FetchContent to download externals

2021-07-22 (e24c76d)


  • Updated CCD strategy when using Tight Inclusion to only perform no_zero_toi=true when there is no minimum distance

2021-07-17 (a20f7a2)


  • Added detect_edge_face_collision_candidates_brute_force for 3D intersection broad-phase

  • Added ability to save an obj of collision candidates

  • Added tests for has_intersection (all pass after fixes)


  • Fixed possible numerical rounding problems in HashGrid AABB::are_overlapping

  • Fixed HashGrid’s function for getting edge-face intersection candidates

2021-07-15 (7301b42)


  • Use ignore_codimensional_vertices in the brute force broad-phase method

  • Fixed AABB inflation in brute force and SpatialHash methods

2021-07-08 (86ae4e5)


  • Replaced vertex group ids with more powerful can_collide function. By default everything can collide with everything (same as before)

  • Reordered parameters in construct_constraint_set(), is_collision_free(), and compute_collision_free_stepsize()

  • update_barrier_stiffness now requires the constraint_set rather than building it

  • update_barrier_stiffness dropped dhat parameter


  • SpatialHash for 2D


  • Verison of initial_barrier_stiffness that computes the constraint set and barrier gradient because there are a lot of parameters to these functions

2021-07-05 (4d16954)


  • Renamed directory src/spatial_hash/src/broad_phase/

  • Renamed files src/ccd/broad_phase.*src/ccd/aabb.*

2021-07-05 (b3808e1)


  • Select the broad-phase method for CCD and distance constraints


  • CCD parameters for Tight Inclusion’s tolerance and maximum iterations


  • ignore_codimensional_vertices to false by default

  • CMake option TIGHT_INCLUSION_WITH_NO_ZERO_TOI=ON as default

2021-06-18 (aa59aeb)


  • construct_friction_constraint_set now clears the given friction_constraint_set

2021-05-18 (245b13b)


  • Use TightInclusion degenerate edge-edge for point-point and point-edge CCD

2021-05-11 (5c34dcd)


  • char* exceptions to std::exceptions

2021-05-06 (24056cc)


  • Gave dhat_epsilon_scale a default value of 1e-9 in update_barrier_stiffness

  • warning:

    Changed order of parameters to update_barrier_stiffness

    • Flipped bbox_diagonal and dhat_epsilon_scale

2021-05-06 (81d65f3)


  • Bug in output min distance of update_barrier_stiffness

2021-05-04 (59ec167)


  • Moved eigen_ext functions into ipc namespace

  • Renamed max size matrices with Max

    • Eigen::VectorX([0-9])ipc::VectorMax$1

    • Eigen::MatrixXX([0-9])ipc::VectorMax$1

    • Eigen::ArrayMax([0-9])ipc::ArrayMax$1

2021-05-03 (664d65f)


  • Added utility function to check for edge-edge intersection in 2D and edge-triangle intersection in 3D.

  • Optionally: use GMP for exact edge-triangle intersection checks

2021-05-03 (9b4ebfc)


  • voxel_size_heuristic.cpp which suggests a good voxel size for the SpatialHash and HashGrid


  • Changed HashGrid voxel size to be the average edge length not considering displacement length. This results in better performance, but can result in large memory usage.

2021-04-29 (293d0ad)


  • Added TBB parallel loops to the main function (compute_potential, compute_friction_potential, compute_collision_free_stepsize, etc.)

  • Added function addVerticesFromEdges that adds the vertices connected to edges in parallel and avoids duplicates


  • Changed the HashGrid to use ArrayMax3 over VectorX3 to simplify the code


  • Fixed some parameters that were not by reference

2021-04-21 (c8a6d5)


  • Added the SpatialHash from the original IPC code base with some modification to get all candidates in parallel

    • Benchmark results indicate this SpatialHash is faster than the HashGrid with multithreading

    • TODO: Improve HashGrid or fully integrate SpatialHash into ipc.hpp

2021-02-11 (9c7493)


  • Switched to the correct (conservative) CCD of Wang et al. [2021]

    • Can select Etienne Vouga’s CCD in the CMake (see

2021-02-01 (b510253)


  • Added minimum seperation distance (thickness) to distance constraints

    • Based on “Codimensional Incremental Potential Contact” [Li et al., 2021]

2021-02-01 (a395175)


  • Added 2D friction model based on the 3D formulation.

    • TODO: Test this further

2021-01-12 (deee6d0)


  • Added and optional parameter F2E to construct_constraint_set(). This is similar to F (which maps faces to vertices), but maps faces to edges. This is optional, but recommended for better performance. If not provided a simple linear search will be done per face edge!

    • TODO: Add a function to compute this mapping.

2021-01-09 (deee6d0)


  • Replaced VectorXd and MatrixXd with static size versions for local gradient and hessians


  • Removed TBB parallelization form the hash grid because we get better performance without it.

    • TODO: Improve parallelization in the hash grid or switch to the original IPC spatial hash

2020-11-06 (4553509)


  • Fixed multiplicity for point-triangle distance computation to avoid duplicate point-point and point-edge pairs.

2020-10-22 (51f4903)


  • Projection of the hessian to PSD. This was completely broken as the projected matrix was never used.

2020-10-22 (9be6c0f)


  • Mollification of EE constraints that have a distance type of PP or PE

  • If there is no mollification needed then the PP and PE constraints are stored with multiplicity

  • Set the parallel EE friction constraint threshold to eps_x like in IPC

    • This avoid needing the mollification for the normal force and these forces are small anyways

2020-10-10 (cb8b53f)


  • Assertions in compute_collision_free_stepsize

2020-10-10 (4a5f84f)


  • Point-triangle distance type by replacing it with the one used in the original IPC code

2020-10-10 (1d51a61)


  • Boolean parameter in compute_friction_potential_hessian that controls if the hessian is projected to PSD

2020-10-09 (b737fb0)


  • Parameter for vertex group IDs to exclude some collisions (e.g., self collisions)

2020-10-08 (6ee60ae)


  • Second version of update_barrier_stiffness() that takes an already computed minimum distance and world bounding box diagonal

2020-10-08 (cc3947d)


  • Second version of initial_barrier_stiffness() that takes an already computed barrier gradient

  • Assertions on initial_barrier_stiffness() input

    • average_mass > 0 && min_barrier_stiffness_scale > 0


  • Fixed typo in initial_barrier_stiffness() name (was intial_barrier_stiffness())

2020-10-07 (5582582)


  • FrictionConstraint structures to store friction information (i.e., tangent basis, normal force magnitude, closest points, and coefficient of friction)

  • Unit test that compares the original IPC code’s friction components with the toolkit’s


  • compute_friction_bases() is now construct_friction_constraint_set()

    • It now takes the coefficient of friction (mu)

    • It now puts all information inside of the FrictionConstraints (friction_constraint_set)

2020-10-06 (b48ba0e)


  • During construct_constraint_set() the constraints are added based on distance type

    • Duplicate vertex-vertex and edge-vertex constraints are handled by a multiplicity multiplier

    • Edge-edge constraints are always line-line distances

    • Point-triangle constraints are always point-plane distances

2020-10-05 (9a4576b)


  • Fixed a bug in the point-triangle closest points and tangent basis computed in compute_friction_bases()

  • Fixed a bug in edge_edge_tangent_basis() used to compute the tangent basis for friction

2020-09-19 (31a37e0)


  • spdlog for logging information

2020-09-19 (acb7664)


  • Headers are now include with the prefix ipc/

    • E.g., #include <ipc.hpp>#include <ipc/ipc.hpp>

2020-09-04 (7dd2ab7)


  • Collision constraint to store distance constraint pairs

    • EdgeEdgeConstraint stores the edge-edge mollifier threshold (eps_x)


  • Input parameter dhat_squared is now dhat (i.e., non-squared value)

  • Input parameter epsv_times_h_squared is now epsv_times_h (i.e., non-squared value)

  • Constraints replaced Candidates

  • construct_constraint_set() now takes the rest vertex position (V_rest)

  • compute_barrier_potential*() no longer take the rest vertex position

Last update: Nov 12, 2023