Skip to content

Commit 3db1d97

Browse files
authored
Update Docs with NL CCD Tutorial (#78)
* Update docs; add NL CCD tutorial
1 parent 8d59aca commit 3db1d97

File tree

17 files changed

+500
-166
lines changed

17 files changed

+500
-166
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ endif()
5959
project(IPCToolkit
6060
DESCRIPTION "A set of reusable functions to integrate IPC into an existing simulation."
6161
LANGUAGES CXX
62-
VERSION "1.1.1")
62+
VERSION "1.2.0")
6363

6464
option(IPC_TOOLKIT_BUILD_TESTS "Build unit-tests" ${IPC_TOOLKIT_TOPLEVEL_PROJECT})
6565
option(IPC_TOOLKIT_BUILD_PYTHON "Build Python bindings" OFF)

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ IPC Toolkit is a set of reusable functions to integrate Incremental Potential Co
2626

2727
This is not a full simulation library. As such it does not include any physics or solvers. For a full simulation implementation, we recommend [PolyFEM](https://polyfem.github.io/) (a finite element library) or [Rigid IPC](https://github.com/ipc-sim/rigid-ipc) (rigid-body dynamics) both of which utilize the IPC Toolkit.
2828

29+
<!--- BEGIN C++ README 1 --->
30+
2931
## Build
3032

3133
The easiest way to add the toolkit to an existing CMake project is to download it through CMake.
@@ -53,6 +55,8 @@ target_link_libraries(${PROJECT_NAME} PUBLIC ipc::toolkit)
5355

5456
where `PROJECT_NAME` is the name of your library/binary.
5557

58+
<!--- BEGIN C++ README 2 --->
59+
5660
### Dependencies
5761

5862
**All required dependencies are downloaded through CMake** depending on the build options.
@@ -76,7 +80,7 @@ The following libraries are used in this project:
7680
* Enabled by default
7781
* [filib](https://github.com/zfergus/filib): interval arithmetic for nonlinear trajectories/CCD
7882
* Enable by using the CMake option `IPC_TOOLKIT_WITH_FILIB`
79-
* Enabled by default
83+
* Enabled by default
8084
* [rational-cpp](https://github.io/zfergus/rational-cpp): rational arithmetic used for exact intersection checks
8185
* Enable by using the CMake option `IPC_TOOLKIT_WITH_RATIONAL_INTERSECTION`
8286
* Requires [GMP](https://gmplib.org/) to be installed at a system level
@@ -87,8 +91,7 @@ The following libraries are used in this project:
8791

8892
## Usage
8993

90-
The main functionality is provided in the `ipc.hpp` header. Use the prefix directory `ipc` to include all header files (e.g. `#include <ipc/ipc.hpp>`).
91-
94+
See the [tutorial](https://ipctk.xyz/tutorial/getting_started.html) for a quick introduction to the toolkit, or the [documentation](https://ipctk.xyz/cpp.html) for a full reference.
9295

9396
## Unit Tests
9497

@@ -103,11 +106,13 @@ The following are downloaded when unit tests are enabled (`IPC_TOOLKIT_BUILD_TES
103106
* [finite-diff](https://github.com/zfergus/finite-diff): finite-difference comparisons
104107
* [Nlohman's JSON library](https://github.com/nlohmann/json): loading test data from JSON files
105108

109+
<!--- END C++ README --->
110+
106111
## Python Bindings
107112

108113
We provide Python bindings for functions in the toolkit using [pybind11](https://github.com/pybind/pybind11).
109114

110-
For more information see the [Python documentation](https://ipctk.xyz/python/).
115+
For more information see the [Python documentation](https://ipctk.xyz/python.html).
111116

112117
## Contributing
113118

docs/source/conf.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020

2121
# -- Project information -----------------------------------------------------
2222

23+
import ipctk
24+
2325
project = "IPC Toolkit"
2426
copyright = '2020-2023, IPC-Sim Organization; MIT License'
2527
author = "Zachary Ferguson"
26-
version = "1.1.1"
28+
version = ipctk.__version__
2729

2830
# -- General configuration ---------------------------------------------------
2931

docs/source/cpp.rst

Lines changed: 8 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -18,91 +18,15 @@ C++
1818
:target: https://github.com/ipc-sim/ipc-toolkit/blob/main/LICENSE
1919
:alt: License
2020

21-
Build
22-
-----
23-
24-
The easiest way to add the toolkit to an existing CMake project is to download it through CMake.
25-
CMake provides functionality for doing this called `FetchContent <https://cmake.org/cmake/help/latest/module/FetchContent.html>`__ (requires CMake ≥ 3.14).
26-
We use this same process to download all external dependencies.
27-
28-
For example,
29-
30-
.. code:: cmake
31-
32-
include(FetchContent)
33-
FetchContent_Declare(
34-
ipc_toolkit
35-
GIT_REPOSITORY https://github.com/ipc-sim/ipc-toolkit.git
36-
GIT_TAG ${IPC_TOOLKIT_GIT_TAG}
37-
)
38-
FetchContent_MakeAvailable(ipc_toolkit)
39-
40-
where :cmake:`IPC_TOOLKIT_GIT_TAG` is set to the version of the toolkit you want to use. This will download and add the toolkit to CMake. The toolkit can then be linked against using
41-
42-
.. code:: cmake
43-
44-
# Link against the IPC Toolkit
45-
target_link_libraries(${PROJECT_NAME} PUBLIC ipc::toolkit)
46-
47-
where :cmake:`PROJECT_NAME` is the name of your library/binary.
21+
.. include:: ../../README.md
22+
:parser: myst_parser.sphinx_
23+
:start-after: <!--- BEGIN C++ README 1 --->
24+
:end-before: <!--- BEGIN C++ README 2 --->
4825

4926
.. tip::
5027
If your :cmake:`IPC_TOOLKIT_GIT_TAG` is a tag (e.g. ``v1.1.1``), then you can use the :cmake:`FetchContent_Declare` argument :cmake:`GIT_SHALLOW TRUE` to download only a single commit. Otherwise, you should use the default :cmake:`GIT_SHALLOW FALSE`.
5128

52-
Dependencies
53-
------------
54-
55-
**All required dependencies are downloaded through CMake** depending on the build options.
56-
57-
The following libraries are used in this project:
58-
59-
* `Eigen <https://eigen.tuxfamily.org/>`__: linear algebra
60-
* `libigl <https://github.com/libigl/libigl>`__: basic geometry functions and predicates
61-
* `TBB <https://github.com/wjakob/tbb>`__: parallelization
62-
* `Tight-Inclusion <https://github.com/Continuous-Collision-Detection/Tight-Inclusion>`__: correct (conservative) CCD
63-
* `spdlog <https://github.com/gabime/spdlog>`__: logging information
64-
65-
Optional
66-
--------
67-
68-
* `robin-map <https://github.com/Tessil/robin-map>`__: faster hash set/map than :cpp:`std::unordered_set`/:cpp:`std::unordered_map`
69-
70-
* Enable by using the CMake option :cmake:`IPC_TOOLKIT_WITH_ROBIN_MAP`
71-
* Enabled by default
72-
73-
* `Abseil <https://abseil.io/>`__: hashing utilities
74-
75-
* Enable by using the CMake option :cmake:`IPC_TOOLKIT_WITH_ABSEIL`
76-
* Enabled by default
77-
78-
* `rational-cpp <https://github.io/zfergus/rational-cpp>`__: rational arithmetic used for exact intersection checks
79-
80-
* Enable by using the CMake option :cmake:`IPC_TOOLKIT_WITH_RATIONAL_INTERSECTION`
81-
* Requires `GMP <https://gmplib.org/>`__ to be installed at a system level
82-
83-
* `Etienne Vouga's Collision Detection Library <https://github.com/evouga/collisiondetection>`__: inexact CCD
84-
85-
* Included for comparison with the original IPC library
86-
* Enable by disabling the CMake option :cmake:`IPC_TOOLKIT_WITH_CORRECT_CCD`
87-
* Replaces the default Tight-Inclusion CCD
88-
89-
Usage
90-
-----
91-
92-
The main functionality is provided in the ``ipc.hpp`` header. Use the prefix directory ``ipc`` to include all header files (e.g. :cpp:`#include <ipc/ipc.hpp>`).
93-
94-
Unit Tests
95-
----------
96-
97-
We provide unit tests for ensuring the correctness of our algorithmic pieces. To enable the unit tests use the CMake option :cmake:`IPC_TOOLKIT_BUILD_UNIT_TESTS`.
98-
99-
.. _dependencies-1:
100-
101-
Dependencies
102-
^^^^^^^^^^^^
103-
104-
The following are downloaded when unit tests are enabled(:cmake:`IPC_TOOLKIT_BUILD_TESTS`)
105-
106-
* `Catch2 <https://github.com/catchorg/Catch2.git>`__: testing framework
107-
* `finite-diff <https://github.com/zfergus/finite-diff>`__: finite-difference comparisons
108-
* `Nlohman's JSON library <https://github.com/nlohmann/json>`__: loading test data from JSON files
29+
.. include:: ../../README.md
30+
:parser: myst_parser.sphinx_
31+
:start-after: <!--- BEGIN C++ README 2 --->
32+
:end-before: <!--- END C++ README --->

docs/source/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
:hidden:
1212

1313
tutorial/getting_started.rst
14+
tutorial/nonlinear_ccd.rst
1415
tutorial/simulation.rst
1516
tutorial/misc.rst
1617
tutorial/references.rst

docs/source/refs.bib

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ @article{Li2020IPC
22
title = {Incremental Potential Contact: Intersection- and Inversion-free Large Deformation Dynamics},
33
author = {Minchen Li and Zachary Ferguson and Teseo Schneider and Timothy Langlois and Denis Zorin and Daniele Panozzo and Chenfanfu Jiang and Danny M. Kaufman},
44
year = 2020,
5-
journal = {ACM Transactions on Graphics (SIGGRAPH)},
5+
journal = {{ACM} Transactions on Graphics ({SIGGRAPH})},
66
volume = 39,
77
number = 4,
88
articleno = 49,
@@ -12,7 +12,7 @@ @article{Li2021CIPC
1212
title = {Codimensional Incremental Potential Contact},
1313
author = {Minchen Li and Danny M. Kaufman and Chenfanfu Jiang},
1414
year = 2021,
15-
journal = {ACM Transactions on Graphics (SIGGRAPH)},
15+
journal = {{ACM} Transactions on Graphics ({SIGGRAPH})},
1616
volume = 40,
1717
number = 4,
1818
articleno = 170,
@@ -31,7 +31,7 @@ @article{Wang2021TightInclusion
3131
author = {Bolun Wang and Zachary Ferguson and Teseo Schneider and Xin Jiang and Marco Attene and Daniele Panozzo},
3232
year = 2021,
3333
month = oct,
34-
journal = {ACM Transactions on Graphics},
34+
journal = {{ACM} Transactions on Graphics},
3535
volume = 40,
3636
number = 5,
3737
articleno = 188,
@@ -57,4 +57,14 @@ @inproceedings{Ferguson2023HighOrderIPC
5757
series = {SIGGRAPH '23},
5858
numpages = 11,
5959
note = {\url{https://zferg.us/research/high-order-ipc/}}
60+
}
61+
@article{Ferguson2021RigidIPC,
62+
title = {Intersection-free Rigid Body Dynamics},
63+
author = {Zachary Ferguson and Minchen Li and Teseo Schneider and Francisca Gil-Ureta and Timothy Langlois and Chenfanfu Jiang and Denis Zorin and Danny M. Kaufman and Daniele Panozzo},
64+
year = 2021,
65+
journal = {{ACM} Transactions on Graphics ({SIGGRAPH})},
66+
volume = 40,
67+
number = 4,
68+
articleno = 183,
69+
note = {\url{https://ipc-sim.github.io/rigid-ipc}}
6070
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
Nonlinear CCD
2+
=============
3+
4+
We can also perform CCD of nonlinear trajectories (of linear geometry) using the method of :cite:t:`Ferguson2021RigidIPC`. While :cite:t:`Ferguson2021RigidIPC` introduce their method in the context of rigid bodies, it can be applied to any nonlinear trajectory of linear geometry. The method works by transforming the nonlinear trajectories into (adaptive) piecewise linear trajectories with an envelope/minimum separation around each piece, enclosing the nonlinear trajectory. The method then performs CCD on the piecewise linear trajectories to find the earliest time of impact.
5+
6+
We provide the following functions to perform nonlinear CCD:
7+
8+
.. md-tab-set::
9+
10+
.. md-tab-item:: C++
11+
12+
* :cpp:func:`ipc::point_point_nonlinear_ccd`,
13+
* :cpp:func:`ipc::point_edge_nonlinear_ccd`,
14+
* :cpp:func:`ipc::edge_edge_nonlinear_ccd`, and
15+
* :cpp:func:`ipc::point_triangle_nonlinear_ccd`.
16+
17+
Each of these functions take as input a :cpp:func:`ipc::NonlinearTrajectory` object for the endpoints of the linear geometry.
18+
19+
.. md-tab-item:: Python
20+
21+
* :py:func:`ipctk.point_point_nonlinear_ccd`,
22+
* :py:func:`ipctk.point_edge_nonlinear_ccd`,
23+
* :py:func:`ipctk.edge_edge_nonlinear_ccd`, and
24+
* :py:func:`ipctk.point_triangle_nonlinear_ccd`.
25+
26+
Each of these functions take as input a :py:func:`ipctk.NonlinearTrajectory` object for the endpoints of the linear geometry.
27+
28+
For example, the following code defines a rigid trajectory in 2D in order to perform nonlinear CCD between a point and edge:
29+
30+
.. md-tab-set::
31+
32+
.. md-tab-item:: C++
33+
34+
.. literalinclude:: ../../../tests/src/tests/ccd/test_nonlinear_ccd.cpp
35+
:language: c++
36+
:start-after: // BEGIN_RIGID_2D_TRAJECTORY
37+
:end-before: // END_RIGID_2D_TRAJECTORY
38+
39+
.. md-tab-item:: Python
40+
41+
.. literalinclude:: ../../../python/tests/test_ccd.py
42+
:language: python
43+
:start-after: # BEGIN_RIGID_2D_TRAJECTORY
44+
:end-before: # END_RIGID_2D_TRAJECTORY
45+
:dedent: 4
46+
47+
Defining the Trajectory
48+
-----------------------
49+
50+
Let's dive deeper by breaking down the implementation of Rigid2DTrajectory. The first function we need to implement is the call operator:
51+
52+
.. md-tab-set::
53+
54+
.. md-tab-item:: C++
55+
56+
.. literalinclude:: ../../../tests/src/tests/ccd/test_nonlinear_ccd.cpp
57+
:language: c++
58+
:lines: 127-134
59+
:dedent: 4
60+
61+
62+
.. md-tab-item:: Python
63+
64+
.. literalinclude:: ../../../python/tests/test_ccd.py
65+
:language: python
66+
:lines: 88-92
67+
:dedent: 8
68+
69+
This function computes the position of the point at a time :math:`t \in [0, 1]`. This defines the trajectory of the point. In this case, we have a rigid body with a center of mass (COM) at the origin. The trajectory of the point is given by:
70+
71+
.. math::
72+
73+
x(t) := R(\theta + t \Delta \theta) \bar{x} + T + t \Delta T
74+
75+
where :math:`\theta` is the angle of rotation about the COM, :math:`T` is the translation of the COM, :math:`\Delta \theta` and :math:`\Delta T` are the updates to :math:`\theta` and :math:`T`, respectively, and :math:`\bar{x}` is the position of the point in the interial frame.
76+
77+
Computing a Conservative Envelope
78+
---------------------------------
79+
80+
The second function we need to implement is ``max_distance_from_linear``.
81+
82+
.. md-tab-set::
83+
84+
.. md-tab-item:: C++
85+
86+
.. literalinclude:: ../../../tests/src/tests/ccd/test_nonlinear_ccd.cpp
87+
:language: c++
88+
:lines: 136-147
89+
:dedent: 4
90+
91+
.. md-tab-item:: Python
92+
93+
.. literalinclude:: ../../../python/tests/test_ccd.py
94+
:language: python
95+
:lines: 94-100
96+
:dedent: 8
97+
98+
This function computes the maximum distance over a time interval :math:`[t_0, t_1]` between the nonlinear trajectory and a line segment from :math:`x(t_0)` to :math:`x(t_1)`. Mathematically this function computes
99+
100+
.. math::
101+
102+
\min_{t\in[0, 1]} \|x((t_1 - t_0) t + t_0) - ((x(t_1) - x(t_0))t + x(t_0))\|,
103+
104+
for a given start and end time :math:`t_0` and :math:`t_1`, respectively.
105+
106+
In the case of a 2D rigid body, we can compute this value analytically because we know the :math:`\arg\!\min`:
107+
108+
.. math::
109+
110+
\underset{t\in[0, 1]}{\arg\!\min} \|x((t_1 - t_0) t + t_0) - ((x(t_1) - x(t_0))t + x(t_0))\| = 0.5,
111+
112+
for :math:`(t_1 - t_0) \Delta \theta \leq \pi/2`, otherwise we can use the most conservative envelope radius of :math:`2 \|\bar{x}\|`.
113+
114+
Performing Nonlinear CCD
115+
------------------------
116+
117+
Last, we use the ``Rigid2DTrajectory`` to perform nonlinear CCD between a point and edge:
118+
119+
.. md-tab-set::
120+
121+
.. md-tab-item:: C++
122+
123+
.. literalinclude:: ../../../tests/src/tests/ccd/test_nonlinear_ccd.cpp
124+
:language: c++
125+
:start-after: // BEGIN_TEST_RIGID_2D_TRAJECTORY
126+
:end-before: // END_TEST_RIGID_2D_TRAJECTORY
127+
:dedent: 4
128+
129+
.. md-tab-item:: Python
130+
131+
.. literalinclude:: ../../../python/tests/test_ccd.py
132+
:language: python
133+
:start-after: # BEGIN_TEST_RIGID_2D_TRAJECTORY
134+
:end-before: # END_TEST_RIGID_2D_TRAJECTORY
135+
:dedent: 4
136+
137+
.. note::
138+
We adjust the ``conservative_rescaling`` parameter to get a more accurate time of impact (TOI), but in practice, this is not needed as a more conservative estimate of the TOI is sufficient to avoid penetrations.

notebooks/nonlinear-trajectories.ipynb

Lines changed: 176 additions & 42 deletions
Large diffs are not rendered by default.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta"
99

1010
[project]
1111
name = "ipctk"
12-
version = "1.1.1"
12+
version = "1.2.0"
1313
authors = [{ name = "Zachary Ferguson", email = "[email protected]" }]
1414
description = "A set of reusable functions to integrate Incremental Potential Contact (IPC) into a simulation."
1515
readme = "docs/PYPI_README.md"

python/src/broad_phase/broad_phase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ void define_broad_phase(py::module_& m)
3434
Construct a registered broad phase object.
3535
3636
Parameters:
37-
broad_phase_method: The broad phase method to use.
37+
method: The broad phase method to use.
3838
3939
Returns:
4040
The constructed broad phase object.

0 commit comments

Comments
 (0)