I am trying to create a STL map of type map<int,CGAL::AABB_tree<Traits>>
(map of AABB tree's) when I try to assign a value to the map, for example (this code is only for demonstration purposes):
//CGAL includes begin
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Polyhedron_incremental_builder_3.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
//CGAL includes end
/*
* CGAL typedef's for initialization
*/
typedef CGAL::Simple_cartesian<double> K;
typedef K::FT FT;
typedef K::Point_3 Point_3;
typedef K::Segment_3 Segment;
typedef CGAL::Polyhedron_3<K> Polyhedron;
typedef Polyhedron::HalfedgeDS HalfedgeDS;
typedef Polyhedron::Vertex_const_iterator Vertex_const_iterator;
typedef Polyhedron::Facet_const_iterator Facet_const_iterator;
typedef Polyhedron::Halfedge_around_facet_const_circulator Halfedge_around_facet_const_circulator;
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
typedef CGAL::AABB_traits<K, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> Tree;
typedef Tree::Point_and_primitive_id Point_and_primitive_id;
//end of typedef's
BuildMesh<HalfedgeDS> mesh(V, F);
polyhedron.delegate( mesh);
myMap[someInt] = Tree(polyhedron.facets_begin(),polyhedron.facets_end(),polyhedron);
I get the following error:
error C2248: 'CGAL::AABB_tree< AABBTraits >::operator =' : cannot access private member declared in class 'CGAL::AABB_tree< AABBTraits>'
I tried looking in the source code of CGAL and found in CGAL\AABB_tree.h the following lines:
private:
// Disabled copy constructor & assignment operator
typedef AABB_tree<AABBTraits> Self;
AABB_tree(const Self& src);
Self& operator=(const Self& src);
this means that the copy and assignment constructors are private, thus it's not possible to create stl containers of type Tree.
I tried to use pointers instead I changed my map to map<int,CGAL::AABB_tree < Traits > * >
and tried:
BuildMesh<HalfedgeDS> mesh(V, F);
polyhedron.delegate( mesh);
myMap[someInt] = new Tree(polyhedron.facets_begin(),polyhedron.facets_end(),polyhedron);
but then it crashed my code.
Is there any way around it so it will be possible to create an STL container of this type?
UPDATE 14/3/2014
I tried using Drop's solution as suggested but I got the following error:
error C2248: 'CGAL::AABB_tree::AABB_tree' : cannot access private member declared in class 'CGAL::AABB_tree'
UPDATE 17/3/2014
Here is a sample code that doesn't compile:
#include <iostream>
#include <map>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
using std::map;
typedef CGAL::Simple_cartesian<double> K;
typedef K::FT FT;
typedef K::Point_3 Point;
typedef K::Segment_3 Segment;
typedef CGAL::Polyhedron_3<K> Polyhedron;
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
typedef CGAL::AABB_traits<K, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> Tree;
typedef Tree::Point_and_primitive_id Point_and_primitive_id;
int main()
{
map<int,Tree> myMap;
Point p(1.0, 0.0, 0.0);
Point q(0.0, 1.0, 0.0);
Point r(0.0, 0.0, 1.0);
Point s(0.0, 0.0, 0.0);
Polyhedron polyhedron;
polyhedron.make_tetrahedron(p, q, r, s);
// here i get the error
myMap.emplace(
std::piecewise_construct,
std::forward_as_tuple(1),
std::forward_as_tuple(polyhedron.facets_begin(), polyhedron.facets_end(),polyhedron));
myMap[1].accelerate_distance_queries();
// query point
Point query(0.0, 0.0, 3.0);
// computes squared distance from query
FT sqd = myMap[1].squared_distance(query);
std::cout << "squared distance: " << sqd << std::endl;
// computes closest point
Point closest = myMap[1].closest_point(query);
std::cout << "closest point: " << closest << std::endl;
// computes closest point and primitive id
Point_and_primitive_id pp = myMap[1].closest_point_and_primitive(query);
Point closest_point = pp.first;
Polyhedron::Face_handle f = pp.second; // closest primitive id
std::cout << "closest point: " << closest_point << std::endl;
std::cout << "closest triangle: ( "
<< f->halfedge()->vertex()->point() << " , "
<< f->halfedge()->next()->vertex()->point() << " , "
<< f->halfedge()->next()->next()->vertex()->point()
<< " )" << std::endl;
return EXIT_SUCCESS;
}
Any ideas?
Use std::map::emplace()
method, std::pair's piecewise constructor and perfect forwarding, to construct your non-copyable and non-assignable data in-place:
myMap.emplace(
std::piecewise_construct, // disambiguation hint
std::forward_as_tuple(someInt), // perfectly forward arguments to key_type constructor
std::forward_as_tuple(polyhedron.facets_begin(), polyhedron.facets_end(),
polyhedron)); // perfectly forward arguments to value_type constructor
Solution is very verbose, but fully C++11 standard compliant.
Working example: Coliru Viewer
Edit:
Use std::make_tuple
instead of std::forward_as_tuple
if your compiler does not support it (#include <tuple>
).
Edit2:
After reviewing code snipped added, I found that errors was triggered not by map::emplace
method (can be easily verified by commenting it out), but by later usage of map::operator[]
. Internally, map::operator[]
uses map::insert
(check it's source code). Just use map::at()
instead to fix issues. Example:
FT sqd = myMap.at(1).squared_distance(query);
Note, that map::at()
throws exception if key not found. You could be interested (depending on performance demands) in reassuring key by checking with map::find()
before accessing to value.
Note also, that you are receiving verbose warnings, because of CGAL internals usage of "unsafe" string functions. They are not errors and could be disabled by adding -D_SCL_SECURE_NO_WARNINGS
compiler flag.
Hope it helps. Happy coding!