Question

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?

Was it helpful?

Solution

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!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top