I am trying to make the orthogonal_k_neighbors _search (or any kdtree based search) in cgal with points defined in a Point_set object.
The idea would be to fetch a point and associated vector near a given point. However I am having issue about the correctness of the Traits adaptation for this specific case.
I think The Traits definition is not the expected one since though the following code does build it raises the following issue.
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Search_traits_3.h>
#include <CGAL/Search_traits_adapter.h>
#include <CGAL/property_map.h>
#include <CGAL/Orthogonal_k_neighbor_search.h>
using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using Point_3 = Kernel::Point_3 ;
using Vector_3 = Kernel::Vector_3 ;
using Point_set = CGAL::Point_set_3<Point_3, Vector_3>;
using Search_base = CGAL::Search_traits_3<Kernel>;
using Traits = CGAL::Search_traits_adapter<Point_set::Index,
Point_set::Property_map<Point_3>,
Search_base> ;
using K_neighbor_search = CGAL::Orthogonal_k_neighbor_search<Traits>;
using Tree = K_neighbor_search::Tree;
using Splitter = Tree::Splitter;
using Distance = K_neighbor_search::Distance;
int main()
{
Point_set pSet;
pSet.add_normal_map();
pSet.insert(Point_3(0,0,0), Vector_3(0,1,0));
pSet.insert(Point_3(0.1,0,0), Vector_3(0,1,0));
pSet.insert(Point_3(0.2,0,0), Vector_3(0,1,0));
pSet.insert(Point_3(0.3,0,0), Vector_3(0,1,0));
pSet.insert(Point_3(0.4,0,0), Vector_3(0,1,0));
pSet.insert(Point_3(0.5,0,0), Vector_3(0,1,0));
Tree tree(pSet.begin(), pSet.end());//, Splitter(), Traits(Point_set::Property_map<Point_3>()));
Point_3 query(0.1, 0.15, 0);
K_neighbor_search search(tree, query, 3);
}
Raising this error
terminate called after throwing an instance of 'CGAL::Assertion_exception'
what(): CGAL ERROR: assertion violation!
Expr: parray_ != nullptr
File: .../cgal/Surface_mesh/include/CGAL/Surface_mesh/Properties.h
Line: 614
Aborted (core dumped)
I did try to modify the Traits to get the expected comportment though I'm not really sure what the Key and PointPropertyMap shall really point to in my case. Any recommendation is welcomed.
You should write:
Traits traits(pSet.point_map());
Tree tree(pSet.begin(), pSet.end(), Splitter(), traits);
Point_3 query(0.1, 0.15, 0);
K_neighbor_search search(tree, query, 3, 0, true, Distance(pSet.point_map()));
Basically, you have to pass the point map to the traits and to the distance. The default point map is not valid as it needs a reference to the point set.
The API is not very intuitive, sorry about that. I'll try to improve it so that it's getting less confusing.