Я пытаюсь создать AABBTree для проверки того, в каком треугольнике 2D-сетки находятся некоторые точки. Для этого я использую CGAL, в частности, пакет Polygon_mesh_processing и функции определения местоположения. Однако мне кажется, что это невыполнимая задача.

Поскольку я хочу проверить несколько моментов и забочусь о производительности, я не хочу сначала создавать AABB. Для этого мне нужна функция PMP::build_AABB_tree, которая получает сетку и AABBTree.

В этом конкретном случае сетка имеет тип CGAL::Surface_mesh<K::Point_2> с ядром Simple_cartersian. Точки запроса также двухмерные. Согласно документации, мне нужно предоставить ReadablePropertyMap, который преобразует мои 2D-точки в 3D-точки.

Я делаю это следующим образом:

struct Point3VPM {
        using key_type = Mesh::Vertex_index;
        using value_type = VNCS::Sim2D::Kernel::K::Point_3;
        using reference = value_type;
        using category = boost::readable_property_map_tag;

        Point3VPM(const Mesh &m)
            : mesh(std::cref(m))
        {
        }

        friend Point3VPM::value_type get(const Point3VPM &map, Mesh::Vertex_index idx)
        {
            Point p = map.mesh.get().point(idx);
            return {p[0], p[1], 0};
        }

        std::reference_wrapper<const Mesh> mesh;
    };

Здесь начинается мой первый выпуск. Мой тип AABBTree следующий:

    using AABBTreeTraits =
        CGAL::AABB_traits<VNCS::Sim2D::Kernel::K, CGAL::AABB_face_graph_triangle_primitive<Mesh, Point3VPM>>;
    using AABBTree = CGAL::AABB_tree<AABBTreeTraits>;

Как я могу построить свой AABBTree? Моему Point3VPM нужен SurfaceMesh, чтобы можно было преобразовать Vertex_index в Point_3, но я не могу найти способ построить AABBTreeTraits с SurfaceMesh. CGAL ожидает конструктора по умолчанию для карты свойств, но поскольку моя карта свойств не может работать без этой сетки, мне нужно как-то предоставить сетку. Как я могу это исправить?

Любая помощь, пытающаяся выполнить эту работу, будет очень признательна

Здесь вы можете найти код для минимального примера:

#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
#include <CGAL/Polygon_mesh_processing/locate.h>

namespace
{
using K = CGAL::Simple_cartesian<double>;
using Point2 = K::Point_2;
using Point3 = K::Point_3;
using Mesh = CGAL::Surface_mesh<Point2>;
namespace PMP = CGAL::Polygon_mesh_processing;

struct Point3VPM {
    using key_type = Mesh::Vertex_index;
    using value_type = Point3;
    using reference = value_type;
    using category = boost::readable_property_map_tag;

    Point3VPM(const Mesh &m)
        : mesh(std::cref(m))
    {
    }

    friend Point3VPM::value_type get(const Point3VPM &map, Mesh::Vertex_index idx)
    {
        Point2 p = map.mesh.get().point(idx);
        return {p[0], p[1], 0};
    }

    std::reference_wrapper<const Mesh> mesh;
};

using AABBTreeTraits = CGAL::AABB_traits<K, CGAL::AABB_face_graph_triangle_primitive<Mesh, Point3VPM>>;
using AABBTree = CGAL::AABB_tree<AABBTreeTraits>;
}  // namespace

int main()
{
    Mesh mesh;

    AABBTree tree;
    PMP::build_AABB_tree(mesh, tree);
    auto location = PMP::locate_with_AABB_tree({0, 0}, tree, mesh);
}
0
jjcasmar 22 Фев 2021 в 02:36

1 ответ

Лучший ответ

Попробуйте следующее:

#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
#include <CGAL/Polygon_mesh_processing/locate.h>

namespace
{
using K = CGAL::Simple_cartesian<double>;
using Point2 = K::Point_2;
using Point3 = K::Point_3;
using Mesh = CGAL::Surface_mesh<Point2>;
namespace PMP = CGAL::Polygon_mesh_processing;

struct Point3VPM {
    using key_type = Mesh::Vertex_index;
    using value_type = Point3;
    using reference = value_type;
    using category = boost::readable_property_map_tag;

    Point3VPM()
        : mesh_ptr(nullptr)
    {}

    Point3VPM(const Mesh &m)
        : mesh_ptr(&m)
    {}

    friend Point3VPM::value_type get(const Point3VPM &map, Mesh::Vertex_index idx)
    {
        Point2 p = map.mesh_ptr->point(idx);
        return {p[0], p[1], 0};
    }

    const Mesh* mesh_ptr;
};

using AABBTreeTraits = CGAL::AABB_traits<K, CGAL::AABB_face_graph_triangle_primitive<Mesh, Point3VPM>>;
using AABBTree = CGAL::AABB_tree<AABBTreeTraits>;
}  // namespace

int main()
{
    Mesh mesh;
    Point3VPM vpm(mesh);
  
    AABBTree tree;
    PMP::build_AABB_tree(mesh, tree, CGAL::parameters::vertex_point_map(vpm));
    auto location = PMP::locate_with_AABB_tree({0, 0}, tree, mesh);
}

Обратите внимание, что для получения точных предикатов следует использовать CGAL::Exact_predicates_inexact_constructions_kernel вместо Simple_cartesian<double>.

1
sloriot 23 Фев 2021 в 07:47