From ea2d785e0af8e9d3a1895838dfefa278d69d880f Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Mon, 8 Jun 2026 01:55:54 -0700 Subject: [PATCH] Improve quality of `maxhullvert` coarse convex hulls using Qhull's `Q9` option. PiperOrigin-RevId: 928417339 Change-Id: I59ecd454f063f2e32e1c3ce08eb4a18506ddf8c8 --- doc/changelog.rst | 8 +++++--- src/user/user_mesh.cc | 3 ++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index 82259ed9..e7bd560a 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -7,15 +7,17 @@ Upcoming version (not yet released) General ^^^^^^^ +- Added :ref:`mju_threadpool`, a new function for creating a thread pool on an ``mjData`` instance. When a thread pool + is initialized, parts of the simulation pipeline, such as collision detection and constraint solving across islands, + are parallelized. The thread pool is automatically destroyed when the ``mjData`` is freed. - Improved primal solver convergence under float32. Improvements initially proposed by :github:user:`n3b` in :issue:`2313` and :github:user:`denzeler-nvidia` in :doc:`MJWarp ` pull request `1374 `__. - Added :ref:`mjs_makeFlex`, a new C API function equivalent to the :ref:`flexcomp` element for programmatically creating flex objects with auto-generated bodies, joints, and equality constraints. Exposed as ``body.make_flex()`` in Python. -- Added :ref:`mju_threadpool`, a new function for creating a thread pool on an ``mjData`` instance. When a thread pool - is initialized, parts of the simulation pipeline, such as collision detection and constraint solving across islands, - are parallelized. The thread pool is automatically destroyed when the ``mjData`` is freed. +- Significantly improved the quality of coarse convex hulls produced by the :ref:`maxhullvert` + attribute by invoking Qhull's `Q9 `__ option. .. admonition:: Breaking API changes :class: attention diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index b1a1e7c3..d74d97b9 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -1730,8 +1730,9 @@ void mjCMesh::MakeGraph(const double* dvert) { std::string qhopt = "qhull Qt"; if (maxhullvert_ > -1) { + // qhull "Q9" picks the furthest of all furthest points across facets. // qhull "TA" actually means "number of vertices added after the initial simplex" - qhopt += " TA" + std::to_string(maxhullvert_ - 4); + qhopt += " Q9 TA" + std::to_string(maxhullvert_ - 4); } // graph not needed for small meshes