diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 1747bfb62..68df6f19d 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -4,44 +4,60 @@
# Technical API documentation (Doxygen)
- if(WITH_PYTHON)
-
- find_package(Doxygen)# 1.16.1 QUIET)
+ # Doxygen is looked for whatever WITH_PYTHON is: besides the docstrings of the
+ # binding, its XML output provides the API references of the manual (breathe)
+ # and its HTML output the api/ pages of the manual website.
+ find_package(Doxygen)# 1.16.1 QUIET)
- if(NOT DOXYGEN_FOUND)
+ if(NOT DOXYGEN_FOUND)
- message(STATUS "The required version of Doxygen has not been found, the API documentation will not be generated.")
+ message(STATUS "The required version of Doxygen has not been found, the API documentation will not be generated.")
+ else()
+
+ if(NOT DOXYGEN_DIR)
+ message(STATUS "Doxygen ${DOXYGEN_VERSION} found.")
else()
+ message(STATUS "Doxygen ${DOXYGEN_VERSION} found in ${DOXYGEN_DIR}.")
+ endif()
- if(NOT DOXYGEN_DIR)
- message(STATUS "Doxygen ${DOXYGEN_VERSION} found.")
- else()
- message(STATUS "Doxygen ${DOXYGEN_VERSION} found in ${DOXYGEN_DIR}.")
- endif()
+ # Includes CMake commands in config file:
+ configure_file(api/Doxyfile.in api/Doxyfile)
- # Includes CMake commands in config file:
- configure_file(api/Doxyfile.in api/Doxyfile)
+ set(DOXYGEN_INPUT ${CMAKE_CURRENT_BINARY_DIR}/api/Doxyfile)
+ set(DOXYGEN_OUTPUT ${APIDOC_DIR}/html/index.html)
- set(DOXYGEN_INPUT ${CMAKE_CURRENT_BINARY_DIR}/api/Doxyfile)
- set(DOXYGEN_OUTPUT ${APIDOC_DIR}/html/index.html)
+ if(WIN32)
+ set(NULL_DEST NUL 2>&1)
+ else()
+ set(NULL_DEST "/dev/null")
+ endif()
- if(WIN32)
- set(NULL_DEST NUL 2>&1)
- else()
- set(NULL_DEST "/dev/null")
- endif()
+ # Only the binding needs the XML output at configure time, python/ turning
+ # it into docstring headers while it is configured. The manual needs it when
+ # it is built, and gets it from the api target, which it depends on.
+ if(WITH_PYTHON)
message(STATUS "Building API Documentation (mandatory for Python binding or for building the manual)")
- set(SPHINX_EXTRA_API ${CMAKE_CURRENT_BINARY_DIR}/manual/extra_html/api)
- file(MAKE_DIRECTORY ${SPHINX_EXTRA_API})
-
- execute_process(COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_INPUT} OUTPUT_QUIET)
- add_custom_target(api COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_INPUT} OUTPUT_QUIET)
+ execute_process(
+ COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_INPUT}
+ OUTPUT_QUIET
+ ERROR_VARIABLE DOXYGEN_ERROR
+ RESULT_VARIABLE DOXYGEN_RESULT
+ )
+ if(NOT DOXYGEN_RESULT EQUAL 0)
+ if(DOXYGEN_RESULT STREQUAL "Segmentation fault" AND EXISTS "${CMAKE_BINARY_DIR}/doc/api/xml/index.xml")
+ message(WARNING "Doxygen exited with '${DOXYGEN_RESULT}' but generated XML output. Continuing so Python docstrings can still be generated.")
+ else()
+ message(FATAL_ERROR "Doxygen failed to generate the API documentation (exit code ${DOXYGEN_RESULT}), which is required for the Python docstrings. Doxygen errors: ${DOXYGEN_ERROR}")
+ endif()
+ endif()
endif()
+ add_custom_target(api COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_INPUT} OUTPUT_QUIET)
+
endif()
# User manual (Sphinx)
@@ -58,17 +74,28 @@
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/manual/conf.py.in ${CMAKE_CURRENT_BINARY_DIR}/manual/conf.py)
set(SPHINX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/manual)
- set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}/manual)
+ # The HTML output (outdir) is kept distinct from, and nested under, the confdir
+ # (${CMAKE_CURRENT_BINARY_DIR}/manual, where conf.py/_static live): otherwise
+ # Sphinx warns that html_static_path sits inside outdir.
+ set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}/manual/html)
# Copying _static files of Sphinx to build directories
- foreach(static_file ${CMAKE_CURRENT_SOURCE_DIR}/manual/_static/)
- file(COPY ${static_file} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/manual/_static/)
- endforeach()
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/manual/_static")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ "${CMAKE_CURRENT_SOURCE_DIR}/manual/_static"
+ "${CMAKE_CURRENT_BINARY_DIR}/manual/_static"
+ )
+ endif()
# Copying tmp files
- foreach(static_file ${CMAKE_CURRENT_SOURCE_DIR}/manual/tmp/)
- file(COPY ${static_file} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/manual/tmp/)
- endforeach()
+ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/manual/tmp")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ "${CMAKE_CURRENT_SOURCE_DIR}/manual/tmp"
+ "${CMAKE_CURRENT_BINARY_DIR}/manual/tmp"
+ )
+ endif()
# todo: the SPHINX_EXECUTABLE is already set by FindSphinx.cmake:
# check that it works without the following overload for Win and Linux:
@@ -87,19 +114,34 @@
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating the manual website using Sphinx")
- add_custom_command(
- TARGET manual POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy_directory
- ${CMAKE_BINARY_DIR}/doc/api/html
- ${SPHINX_EXTRA_API}
- COMMENT "Copying generated Doxygen HTML to Sphinx extra_html/api"
- )
-
+ if(TARGET api)
+
+ # Without this dependency, Sphinx would read whatever Doxygen output the
+ # build tree happens to hold: none at all when WITH_PYTHON is off, and the
+ # one of the last configuration otherwise.
+ add_dependencies(manual api)
+
+ add_custom_command(
+ TARGET manual POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_directory
+ ${CMAKE_BINARY_DIR}/doc/api/html
+ ${SPHINX_BUILD}/api
+ COMMENT "Copying generated Doxygen HTML into the manual output (outdir)/api"
+ )
+
+ else()
+
+ message(STATUS "Doxygen not found, the manual will be generated without its API references.")
+
+ endif()
+
+ # The Doxygen API HTML is already part of ${SPHINX_BUILD}/api (copied there
+ # by the POST_BUILD step above), so installing ${SPHINX_BUILD}/ below is
+ # sufficient -- a separate install of ${CMAKE_CURRENT_BINARY_DIR}/api would
+ # duplicate it under a different, unreferenced layout (api/html/*.html
+ # alongside the Doxyfile, instead of api/*.html).
install(DIRECTORY ${SPHINX_BUILD}/
DESTINATION share/codac_website
OPTIONAL)
- install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/api
- DESTINATION share/codac_website
- OPTIONAL)
endif()
\ No newline at end of file
diff --git a/doc/manual/conf.py.in b/doc/manual/conf.py.in
index 8c92a6019..b91a492a5 100644
--- a/doc/manual/conf.py.in
+++ b/doc/manual/conf.py.in
@@ -108,4 +108,9 @@ breathe_projects = {
togglebutton_hint = "Reveal the solution."
togglebutton_hint_hide = "Hide the solution."
-html_extra_path = ['extra_html']
\ No newline at end of file
+# The generated Doxygen API HTML is copied directly into outdir/api by a
+# POST_BUILD step in doc/CMakeLists.txt (after sphinx-build runs), rather
+# than staged through html_extra_path: since outdir is a distinct directory
+# from confdir, there is no ordering constraint forcing it to exist beforehand,
+# so a direct copy avoids maintaining (and duplicating on disk) an
+# intermediate staging copy that only html_extra_path would ever read.
diff --git a/doc/manual/development/api_redirect.rst b/doc/manual/development/api_redirect.rst
index 4effec051..aa27dc980 100644
--- a/doc/manual/development/api_redirect.rst
+++ b/doc/manual/development/api_redirect.rst
@@ -5,4 +5,4 @@ C++ API
.. raw:: html
-
+
diff --git a/doc/manual/development/changelog.rst b/doc/manual/development/changelog.rst
index 1002ecf90..e227a3f84 100644
--- a/doc/manual/development/changelog.rst
+++ b/doc/manual/development/changelog.rst
@@ -3,13 +3,203 @@
Changelog
=========
-Upcoming version
+Upcoming version
****************
+Nothing reported yet since :ref:`version 2.1.1 `.
+
+.. _sec-dev-changelog-2-1-1:
+
+Version 2.1.1
+*************
+
+Commit 4c9af64 ([qinter] Invert q-relaxed intersection convention)
+-------------------------------------------------------------------
+
+Meaning of ``q`` in ``CtcQInter`` and ``SepQInter``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**This is a breaking change: existing code keeps compiling, but computes something else.**
+
+The q-relaxed intersection of :math:`n` sets is now parametrized by the number of
+constraints that are allowed to be **violated**, where ``q`` used to be the number
+of constraints that had to be **satisfied**. With :math:`n` sets, a former ``q``
+becomes :math:`n-q`.
+
+.. tabs::
+
+ .. code-tab:: py
+
+ # Three separators, at most one of which may be wrong.
+
+ # Old way: q was the number of sets an element had to belong to
+ # sep = SepQInter(2, s1,s2,s3)
+
+ # New way: q is the number of sets it may be outside of
+ sep = SepQInter(1, s1,s2,s3)
+
+ .. code-tab:: c++
+
+ // Three separators, at most one of which may be wrong.
+
+ // Old way: q was the number of sets an element had to belong to
+ // SepQInter sep(2, s1,s2,s3);
+
+ // New way: q is the number of sets it may be outside of
+ SepQInter sep(1, s1,s2,s3);
+
+The same applies to ``CtcQInter`` and to the ``qinter()`` function.
+
+Commit ff4fe62 ([ctc] added CtcWrapper(Y&& y) constructor)
+-----------------------------------------------------------
+
+``CtcWrapper`` can now be built from a temporary domain, which avoids naming an
+intermediate variable when the wrapped value is built on the spot.
+
+Commit 21c9a3c ([graphics] corrected bug with random colors)
+--------------------------------------------------------------
+
+Bugfix in the generation of random colors.
+
+Commit b134a18 ([ctc] minor improvment in CtcUnion)
+------------------------------------------------------
+
+Internal improvement of ``CtcUnion``, with no change to its interface.
+
+
+Version 2.1.0
+*************
+
+Commit b688eee ([ctc/sep] revised constructors of Ctc/Sep Inter/Union/QInter)
+-------------------------------------------------------------------------------
+
+Building an intersection or a union from several operators
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``CtcInter``, ``CtcUnion``, ``CtcQInter``, ``SepInter``, ``SepUnion`` and
+``SepQInter`` now accept a variadic list of operands as well as an initializer
+list, instead of requiring a collection built beforehand:
+
+.. tabs::
+
+ .. code-tab:: py
+
+ sep = SepInter(s1, s2, s3) # variadic
+ sep = SepInter([s1, s2, s3]) # or from a list
+
+ .. code-tab:: c++
+
+ SepInter sep(s1, s2, s3); // variadic
+ SepInter sep({s1, s2, s3}); // or from an initializer list
+
+The former constructors still work, so this addition is backward compatible.
+
+Commit ec5e3d2 ([graphics] save function for Figure2D, closes #377)
+----------------------------------------------------------------------
+
+``Figure2D`` gained a ``save(filename)`` method, which writes the current state
+of the figure to a file. Together with ``clear()``, it is what lets an animation
+export one file per frame; see the ``00_graphics/graphic_animation`` example.
+
+Commit 91a656c ([graphics] solving IPE figure not clearing, closes #383)
+---------------------------------------------------------------------------
+
+Bugfix: ``clear()`` had no effect on the IPE output of a figure.
+
+Commit 3212d3a ([graphics] dot detection for IPE file save)
+--------------------------------------------------------------
+
+The name given to an IPE output is now handled correctly when it already carries
+an extension.
+
+Commits 055ee10, e62d2f3 ([matlab] graphical example and bindings)
+--------------------------------------------------------------------
+
+The drawing functions are now available from MATLAB, with a dedicated graphical
+example (``00_graphics/graphic_examples.m``).
+
+
+Version 2.0.5
+*************
+
+Commit dacd8e7 ([op] corrected bug in several definition domains)
+--------------------------------------------------------------------
+
+Bugfix in the definition domains used for the backward evaluation of several
+operators: ``abs``, ``acos``, ``asin``, ``atan2``, ``log``, ``max``, ``sign``,
+``sqrt``, ``tan`` and the division. Contractions involving these operators could
+remove values that were in fact feasible, so results obtained with an earlier
+version and relying on them are worth recomputing.
+
+
+Version 2.0.4
+*************
+
+Commit 9754d0f ([sep] SepInter and SepUnion can be built from a list of separators)
+-------------------------------------------------------------------------------------
+
+First step of what commit b688eee generalized in version 2.1.0.
+
+
+Version 2.0.3
+*************
+
Pull Request #379 from godardma (27/04)
---------------------------------------
``Zonotope`` and ``Parallelepiped`` center is now ``c`` instead of ``z`` to avoid ambiguity.
+The same commit added ``operator+`` on ``Zonotope``.
+
+Commits 1860083, 8c7b17e ([ctc] CtcParallelepiped is now CtcWrapper)
+--------------------------------------------------------------------------------------
+
+``CtcParallelepiped`` was introduced and then immediately replaced by the generic
+``CtcWrapper``; use the latter. The same commit added the handling
+of empty ``Zonotope`` objects. See :ref:`sec-ctc-shape-ctcwrapper`.
+
+Commit 82fd8a3 ([sep] added SepPolarCart + binding)
+-----------------------------------------------------
+
+New separator ``SepPolarCart``, the counterpart of ``SepCartPolar``, available in
+C++ and in Python.
+
+Commit 7b6ba3a ([intv] added < and > operators)
+-------------------------------------------------
+
+``Interval`` gained the comparison operators ``<`` and ``>``. They return a
+``BoolInterval`` enclosing the truth value of :math:`ts`) for
+every :math:`t` of the first interval and every :math:`s` of the second:
+``TRUE`` or ``FALSE`` when the two intervals are separated, ``UNKNOWN`` when they
+overlap, and ``EMPTY`` when either of them is empty. See
+:ref:`sec-intervals-class` and :ref:`sec-intervals-boolinterval-class`.
+
+Commits 710a154, fa00923 (Bugfix for IntvFullPivLU::solve)
+-------------------------------------------------------------
+
+``IntvFullPivLU::solve`` gave a wrong result when called with rectangular
+matrices (more rows than columns). See :ref:`sec-linear-lu`.
+
+Commit f815210 ([graphics] possibility to choose origin for axes)
+--------------------------------------------------------------------
+
+``Figure3D::draw_axes`` takes a second argument, the origin of the axes, which
+defaults to the previous behaviour:
+
+.. tabs::
+
+ .. code-tab:: py
+
+ fig.draw_axes(1.0, [1,2,3]) # size, then origin
+
+ .. code-tab:: c++
+
+ fig.draw_axes(1.0, {1,2,3}); // size, then origin
+
+Commit 312cd79 ([doc] doc for multi-thread)
+----------------------------------------------
+
+Documentation of the threading facilities: see :ref:`sec-tools-threading`.
+
Version 2.0.2
*************
diff --git a/doc/manual/development/info_dev.rst b/doc/manual/development/info_dev.rst
index e99bf5a24..2fa5e4544 100644
--- a/doc/manual/development/info_dev.rst
+++ b/doc/manual/development/info_dev.rst
@@ -21,7 +21,13 @@ To build this manual using Sphinx, follow these steps:
make manual
- The generated website will be locally available in ``./build/doc/manual``.
+ This first runs Doxygen on the sources, whatever
+ ``WITH_PYTHON`` is: its output provides the API references of the manual and
+ the ``api/`` pages of the website. Doxygen therefore has to be installed when
+ the CMake project is configured, otherwise the manual is generated without
+ them.
+
+ The generated website will be locally available in ``./build/doc/manual/html``.
To contribute and extend this manual, please consult the Sphinx documentation:
https://www.sphinx-doc.org
diff --git a/doc/manual/index.rst b/doc/manual/index.rst
index 29fe3a84a..61a6cf8f3 100644
--- a/doc/manual/index.rst
+++ b/doc/manual/index.rst
@@ -180,11 +180,16 @@ User manual
-----------
* :ref:`sec-intro`
+ * Variables, domains, constraints
+ * Contractors
+ * :ref:`sec-intro-separators`
+ * :ref:`sec-intro-pavings`
* :ref:`sec-install`
* :ref:`sec-install-py`
* :ref:`sec-install-cpp`
* :ref:`sec-install-matlab`
+ * :ref:`sec-start-cpp-project`
* :ref:`sec-install-performances`
* :ref:`sec-intervals`
@@ -346,13 +351,15 @@ User manual
* :ref:`sec-extensions-sympy`
* Interface with the IBEX library
+* :ref:`sec-examples`
+
* Frequently Asked Questions
* References
* Related papers
* Contributors
* How to cite Codac
- :ref:`sec-ref-codac-logos`
+ * :ref:`sec-ref-codac-logos`
How-to guides
@@ -409,7 +416,8 @@ Development
manual/visualization/index.rst
manual/tools/index.rst
manual/extensions/index.rst
-
+ manual/examples/index.rst
+
.. linear/index.rst
.. functions/index.rst
.. tubes/index.rst
diff --git a/doc/manual/manual/contractors/analytic/index.rst b/doc/manual/manual/contractors/analytic/index.rst
index d0e781ade..41657b81f 100644
--- a/doc/manual/manual/contractors/analytic/index.rst
+++ b/doc/manual/manual/contractors/analytic/index.rst
@@ -1,3 +1,5 @@
+:orphan:
+
Analytic contractors
====================
diff --git a/doc/manual/manual/contractors/dynamic/ctclohner.rst b/doc/manual/manual/contractors/dynamic/ctclohner.rst
index 1999f1ee4..62bf2b9fb 100644
--- a/doc/manual/manual/contractors/dynamic/ctclohner.rst
+++ b/doc/manual/manual/contractors/dynamic/ctclohner.rst
@@ -144,5 +144,5 @@ Related content
.. admonition:: Technical documentation
- See the `C++ API documentation of this class <../../../extra_html/api/classcodac2_1_1_ctc_lohner.html>`_.
+ See the `C++ API documentation of this class <../../../api/classcodac2_1_1_ctc_lohner.html>`_.
diff --git a/doc/manual/manual/contractors/geometric/index.rst b/doc/manual/manual/contractors/geometric/index.rst
index 938c40df6..7f4fc3741 100644
--- a/doc/manual/manual/contractors/geometric/index.rst
+++ b/doc/manual/manual/contractors/geometric/index.rst
@@ -1,3 +1,5 @@
+:orphan:
+
Geometric contractors
=====================
diff --git a/doc/manual/manual/contractors/index.rst b/doc/manual/manual/contractors/index.rst
index 9b2537821..700b992f5 100644
--- a/doc/manual/manual/contractors/index.rst
+++ b/doc/manual/manual/contractors/index.rst
@@ -1,4 +1,5 @@
.. _sec-ctc:
+
Contractors, separators
=======================
diff --git a/doc/manual/manual/contractors/set/index.rst b/doc/manual/manual/contractors/set/index.rst
index 908dec14b..8522693c5 100644
--- a/doc/manual/manual/contractors/set/index.rst
+++ b/doc/manual/manual/contractors/set/index.rst
@@ -1,3 +1,5 @@
+:orphan:
+
Set contractors
===============
diff --git a/doc/manual/manual/contractors/shape/index.rst b/doc/manual/manual/contractors/shape/index.rst
index b2e377fdd..a23bba7f9 100644
--- a/doc/manual/manual/contractors/shape/index.rst
+++ b/doc/manual/manual/contractors/shape/index.rst
@@ -1,3 +1,5 @@
+:orphan:
+
Shape contractors
=================
diff --git a/doc/manual/manual/examples/index.rst b/doc/manual/manual/examples/index.rst
new file mode 100644
index 000000000..1f1f0b12d
--- /dev/null
+++ b/doc/manual/manual/examples/index.rst
@@ -0,0 +1,246 @@
+.. _sec-examples:
+
+Examples
+========
+
+The `examples `_
+directory of the repository holds around twenty complete, self-contained
+programs. They are worth reading as a complement to this manual: each one is a
+short program that does one thing, and most of them exist in C++, in Python and
+sometimes in MATLAB, so they double as a translation table between the three
+interfaces.
+
+They are also continuously checked. Configuring the project with
+``-D TEST_EXAMPLES=ON`` compiles every one of them against the library being
+built and registers each as a CTest integration test, so an example that stops
+working is caught at the same time as a failing unit test. See
+:ref:`sec-dev-info-examples`.
+
+
+Building and running them
+-------------------------
+
+Every C++ example ships a standalone ``CMakeLists.txt``, written exactly the way
+a project of your own would be (see :ref:`sec-start-cpp-project`). Against an
+installed Codac:
+
+.. code-block:: bash
+
+ cd $HOME/codac/examples/01_batman
+ mkdir build ; cd build
+ cmake -DCMAKE_BUILD_TYPE=Release ..
+ cmake --build .
+ ./codac_example
+
+The Python examples need no build step:
+
+.. code-block:: bash
+
+ cd $HOME/codac/examples/03_sivia
+ python main.py
+
+.. admonition:: Graphical outputs
+
+ Most examples draw something. Those producing a 2D figure need
+ :ref:`the VIBes viewer ` to be running beforehand, and
+ write an ``.ipe`` file as well, readable with :ref:`the IPE editor
+ `. Those producing a 3D figure write an ``.obj`` file, which
+ can be visualized on `3dviewer.net `_ or with any 3D
+ model viewer. See :ref:`sec-graphics`.
+
+
+Graphics
+--------
+
+``00_graphics``
+^^^^^^^^^^^^^^^
+
+Three programs covering the drawing API: ``graphic_examples``
+(C++/Python/MATLAB) goes through a wide variety of drawing functions, colors and
+styles; ``graphic_animation`` (C++/Python) redraws a figure in a loop, clearing
+it between frames; ``graphic_colors`` (C++/Python) displays the predefined
+colors of the library.
+
+These are the sources the :ref:`sec-graphics-2d-example` page points at.
+The reference pages for what they use are :ref:`sec-graphics-functions` and
+:ref:`sec-graphics-colors`.
+
+``06_graphics_3D``
+^^^^^^^^^^^^^^^^^^
+
+The 3D counterpart, in C++, Python and MATLAB, covering the drawing functions of
+``Figure3D``. As the source says:
+
+ The generated ``.obj`` files can be visualized on https://3dviewer.net
+
+See :ref:`sec-graphics-3d` and :ref:`sec-graphics-3d-example`.
+
+
+Set inversion and paving
+------------------------
+
+``01_batman`` *(C++)*
+^^^^^^^^^^^^^^^^^^^^^
+
+The set inversion that produces the Batman logo. This is the example
+:ref:`the C++ installation page ` suggests running first to
+check an installation.
+
+It is also, at the moment, the only place where the set-membership functions are
+shown at work: half of the logo is described as a ``SetFunction`` combining
+``inverse()`` of four ``AnalyticFunction`` objects with ``&``, ``|`` and
+``not``, the other half is its image by the symmetry ``OctaSym({-1,2})``, and the
+separator of the whole is obtained with ``create_sep()``. See
+:ref:`sec-tools-octasym`.
+
+``03_sivia`` *(C++/Python/MATLAB)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The shortest possible set inversion, and a good first program to read: five lines
+to characterize :math:`\{\mathbf{x} \mid x_1^2\sin(x_1^2+x_2^2)-x_2^2 \geqslant
+0\}` with the ``sivia`` function, then draw the resulting paving. See
+:ref:`sec-intro-pavings`.
+
+``02_centered_form`` *(C++/Python/MATLAB)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The equation system of the home page of this manual, solved with
+``CtcInverse``. From the source:
+
+ Example from the publication:
+ https://www.ensta-bretagne.fr/jaulin/paper_centeredActa.pdf
+
+The directory holds two variants that its own ``CMakeLists.txt`` does not build,
+and that are meant to be compiled by hand: ``main_rump.cpp``, from
+https://www.tuhh.de/ti3/rump/intlab/demos/html/dglobal.html#1, and
+``main_evans.cpp``. ``main_parabolas`` (C++/Python) applies the same centered
+form to a family of parabolas.
+
+``07_centered_2D`` and ``08_centered_3D`` *(C++)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Representation of the centered form with zonotopes, in the plane (on Fermat's
+spiral) and in space (on a torus-like surface). See :ref:`sec-zonotope` and
+:ref:`sec-functions-parallelepiped-eval`.
+
+``16_visibility`` *(C++/Python)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Paving of ``SepVisible``: from an observation point and a list of obstacle
+segments, the set of points that can be seen. See :ref:`sec-ctc-geom-ctcvisible`.
+
+``13_qinter`` *(C++/Python)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Robust localization from three distance measurements, one of which may be an
+outlier, using ``SepQInter``. From the source:
+
+ | Example from:
+ | Robust Localisation Using Separators
+ | Luc Jaulin and Benoît Desrochers
+
+.. note::
+
+ The meaning of the parameter ``q`` changed in version 2.1.1: it is now the
+ number of constraints that are *allowed to be violated*, where it used to be
+ the number that had to be satisfied. See :ref:`sec-dev-changelog`.
+
+``custom_sep`` *(Python)*
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Three short scripts showing how to extend the catalog from Python rather than
+from C++, by deriving from the ``Sep`` and ``Ctc`` base classes.
+``custom_sep.py`` defines a separator as the complement of another one --
+returning a ``BoxPair`` with the inner and outer boxes permuted; ``custom_ctc.py``
+does the same for a contractor.
+
+``coloration.py`` goes further and is the one example that shows what a paving is
+made of: a custom contractor is paired with two inverse contractors in a
+``SepCtcPair``, the resulting paving is queried for its connected subsets, and its
+tree is then walked with a visitor that recolors each node in place.
+
+
+Dynamical systems
+-----------------
+
+``14_lohner`` *(C++/Python)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Guaranteed integration of :math:`\dot{\mathbf{x}} = (-x_1, -\sin(x_2))` with
+``CtcLohner``, on two tubes built on time partitions of different samplings, which
+shows the effect of the sampling on the width of the result. See
+:ref:`sec-ctc-dynamic-ctclohner` and :ref:`sec-domains-tubes`.
+
+``05_capd_solver`` *(C++, needs CAPD)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Integration through the CAPD interface. From the source:
+
+ | Author: Maël Godard
+ | Adapted from CAPD examples
+
+See :ref:`sec-extensions-capd`.
+
+``10_lie_groups`` *(C++, needs CAPD)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+From the source:
+
+ | Codac example - Integration using Lie symmetries
+ |
+ | Author: Simon Rohou (2025), from the thesis of Julien Damers
+ |
+ | Reference: *Lie symmetries applied to interval integration*, Julien Damers,
+ Luc Jaulin, Simon Rohou. Automatica, Volume 144, October 2022
+
+``09_robot_simu`` *(C++/Python)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Simulation of a robot following a list of waypoints with ``RobotSimulator``,
+producing the state and input trajectories, then drawing the tank and its path.
+
+``04_explored_area`` *(C++/Python)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+From the source:
+
+ Example: A sampled trajectory, ``sampled_f`` (composed of time-stamped
+ positions with linear interpolation between them), is first obtained by
+ discretizing an analytical expression (the function ``f``, which represents a
+ Lissajous curve) and then appending an additional position. This trajectory is
+ subsequently used in another analytical expression (function ``h``). The
+ projection of an inverse separator is then employed to validate the result.
+
+
+Wrapping and enclosures
+-----------------------
+
+``11_peibos`` *(C++/Python/MATLAB)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The PEIBOS algorithm in 2D (on the Hénon map) and in 3D, run on several threads
+with ``set_nb_threads(max_threads())``. See :ref:`sec-functions-peibos` and
+:ref:`sec-tools-threading`.
+
+``12_peibos_capd`` *(C++, needs CAPD)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+PEIBOS applied to the flow of a differential equation integrated with CAPD. See
+:ref:`sec-extensions-capd-peibos`.
+
+``ellipsoid_example`` *(C++/Python)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The figures of :ref:`sec-ellipsoids`, in one program: linear and nonlinear
+mappings of an ellipsoid, projections of a 3D ellipsoid onto the three planes,
+the singular and degenerate cases, and a stability analysis on a pendulum.
+
+
+Symbolic computation
+--------------------
+
+``15_sympy`` *(C++/Python)*
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Partial differentiation of an ``AnalyticFunction`` through SymPy, with
+``sympy_partial_diff``. See :ref:`sec-extensions-sympy`.
diff --git a/doc/manual/manual/functions/analytic/index.rst b/doc/manual/manual/functions/analytic/index.rst
index 82496722e..152e0f364 100644
--- a/doc/manual/manual/functions/analytic/index.rst
+++ b/doc/manual/manual/functions/analytic/index.rst
@@ -1,3 +1,5 @@
+:orphan:
+
.. _sec-functions-analytic:
Analytic inclusion functions
@@ -7,5 +9,6 @@ Analytic inclusion functions
analytic_functions.rst
analytic_operators.rst
- Extension to custom expressions
- Temporal functions
\ No newline at end of file
+
+.. Extension to custom expressions
+.. Temporal functions
\ No newline at end of file
diff --git a/doc/manual/manual/functions/index.rst b/doc/manual/manual/functions/index.rst
index b70ce037d..cef76dfd8 100644
--- a/doc/manual/manual/functions/index.rst
+++ b/doc/manual/manual/functions/index.rst
@@ -9,4 +9,5 @@ Inclusion functions
analytic/analytic_operators.rst
parallelepiped/parallelepiped_eval.rst
peibos/peibos.rst
- .. Set-membership functions
\ No newline at end of file
+
+.. Set-membership functions
\ No newline at end of file
diff --git a/doc/manual/manual/intervals/IntervalVector_class.rst b/doc/manual/manual/intervals/IntervalVector_class.rst
index f2e160a6e..456824463 100644
--- a/doc/manual/manual/intervals/IntervalVector_class.rst
+++ b/doc/manual/manual/intervals/IntervalVector_class.rst
@@ -134,6 +134,8 @@ Common predicates include:
:end-before: [intervalvector-class-4-end]
:dedent: 4
+.. _sec-manual-intervals-operations:
+
Other operations
----------------
diff --git a/doc/manual/manual/intervals/index.rst b/doc/manual/manual/intervals/index.rst
index 368899992..28d4d8de0 100644
--- a/doc/manual/manual/intervals/index.rst
+++ b/doc/manual/manual/intervals/index.rst
@@ -15,10 +15,11 @@ Codac provides data structures for handling basic interval sets. These structure
:hidden:
Interval_class.rst
- .. Vector_class.rst
IntervalVector_class.rst
BoolInterval_class.rst
+.. Vector_class.rst
+
.. What is an interval?
The Interval class
Boolean intervals
diff --git a/doc/manual/manual/references/logos.rst b/doc/manual/manual/references/logos.rst
index 419547286..e18ebbea0 100644
--- a/doc/manual/manual/references/logos.rst
+++ b/doc/manual/manual/references/logos.rst
@@ -1,3 +1,5 @@
+:orphan:
+
.. _sec-ref-codac-logos:
Codac Logos
diff --git a/doc/manual/manual/visualization/3d_visualization.rst b/doc/manual/manual/visualization/3d_visualization.rst
index 8c2ee2766..3da603a4f 100644
--- a/doc/manual/manual/visualization/3d_visualization.rst
+++ b/doc/manual/manual/visualization/3d_visualization.rst
@@ -56,6 +56,8 @@ Paving
- Subpaving
+.. doxygenfunction:: codac2::Figure3D::draw_axes(double, const Vector&)
+ :project: codac
Note that only the stroke color is used in all of the supported drawing functions.
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index bab5e84ba..cd3c68f44 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -64,7 +64,11 @@
execute_process(COMMAND ${PYTHON_EXECUTABLE}
${PROJECT_SOURCE_DIR}/scripts/doxygen/doxygen2docstring.py
${CMAKE_CURRENT_BINARY_DIR}/../doc/api/xml/
- ${CMAKE_CURRENT_BINARY_DIR}/docstring)
+ ${CMAKE_CURRENT_BINARY_DIR}/docstring
+ RESULT_VARIABLE DOCSTRING_RESULT)
+ if(NOT DOCSTRING_RESULT EQUAL 0)
+ message(FATAL_ERROR "doxygen2docstring.py failed (exit code ${DOCSTRING_RESULT}) while generating the Python docstring headers.")
+ endif()
endif()
diff --git a/scripts/CMakeModules/FindSphinx.cmake b/scripts/CMakeModules/FindSphinx.cmake
index 6190fa010..bf1036215 100644
--- a/scripts/CMakeModules/FindSphinx.cmake
+++ b/scripts/CMakeModules/FindSphinx.cmake
@@ -1,9 +1,9 @@
include(FindPackageHandleStandardArgs)
# We are likely to find Sphinx near the Python interpreter
-find_package(PythonInterp)
-if(PYTHONINTERP_FOUND)
- get_filename_component(_PYTHON_DIR "${PYTHON_EXECUTABLE}" DIRECTORY)
+find_package(Python COMPONENTS Interpreter)
+if(Python_Interpreter_FOUND)
+ get_filename_component(_PYTHON_DIR "${Python_EXECUTABLE}" DIRECTORY)
set(
_PYTHON_PATHS
"${_PYTHON_DIR}"