【问题标题】:2D AABBTree in CGAL with custom property mapCGAL 中的 2D AABBTree 与自定义属性映射
【发布时间】:2021-05-24 06:13:24
【问题描述】:

我正在尝试创建一个 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,但我找不到使用SurfaceMesh 构建AABBTreeTraits 的方法。 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);
}

【问题讨论】:

  • 您应该上传一个显示编译问题的最小示例。以这种方式使用 AABB-tree 是可能的,但您可能遗漏了一部分,而且如果没有看到完整的代码就很难猜到。
  • 添加了一个小例子

标签: c++ cgal


【解决方案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&lt;double&gt; 来获取准确的谓词。

【讨论】:

  • 谢谢。精确谓词有什么好处?
  • 稳健性。见FAQ
猜你喜欢
  • 1970-01-01
  • 2015-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多