带有自定义 属性 地图的 CGAL 中的 2D AABBTree
2D AABBTree in CGAL with custom property map
我正在尝试创建一个 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);
}
尝试以下操作:
#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>
来获得准确的谓词。
我正在尝试创建一个 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);
}
尝试以下操作:
#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>
来获得准确的谓词。