Используя некоторые идеи из ответа Слориота, я смог решить свою проблему.
Поскольку документация do_intersect () не показывает перегрузки для Sphere_3 и Triangle_3, неудивительно, что дерево AABB не поддерживает запросы со Sphere_3.
Однако дерево AABB поддерживает запросы с BBox_3, что не упомянуто в документе do_intersect ().
Вызов all_intersected_primitives () с Bbox_3 возвращает все примитивы дерева AABB, которые содержатся или пересекаются Bbox_3. Это первое хорошее предположение, чтобы получить реальные пересечения со сферой.
С помощью этой оптимизации я мог бы сократить время запроса с 20 мс (простая грубая сила) до 3 мс для сетки с 100k гранями, где один запрос возвращает примерно 10 граней.
Вот соответствующий код:
double r = CGAL::sqrt(patch_radius_squared);
CGAL::Bbox_3 query(
sphere_center.x() - r,
sphere_center.y() - r,
sphere_center.z() - r,
sphere_center.x() + r,
sphere_center.y() + r,
sphere_center.z() + r);
std::list<Tree::Primitive_id> primitives;
tree.all_intersected_primitives(query, std::back_inserter(primitives));
std::vector<Triangle_3> intersected_facets;
for (const Tree::Primitive_id& p : primitives)
{
// intersection with bb gives only a good first guess -> check actual intersection
if (CGAL::squared_distance(*p, sphere_center) <= patch_radius_squared)
{
intersected_facets.push_back(*p);
}
}