2014-03-13 48 views
4

我試圖創建一個類型爲map<int,CGAL::AABB_tree<Traits>>的STL映射(AABB tree's的地圖),例如,當我嘗試爲映射賦值時(例如,此代碼僅適用於演示目的):無法在CGAL中創建類型爲AABB樹的stl容器

//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); 

我得到以下錯誤:

error C2248: 'CGAL::AABB_tree< AABBTraits >::operator =' : cannot access private member declared in class 'CGAL::AABB_tree< AABBTraits>'

我試圖尋找在CGAL的源代碼,並在CGAL \ AABB_tree.h發現下面幾行:

private: 
     // Disabled copy constructor & assignment operator 
     typedef AABB_tree<AABBTraits> Self; 
     AABB_tree(const Self& src); 
     Self& operator=(const Self& src); 

這意味着複製和賦值構造函數是私有的,因此不可能創建類型樹的stl容器。

我試圖用指針來代替我改變了我的地圖map<int,CGAL::AABB_tree <Traits> * > 和嘗試:

BuildMesh<HalfedgeDS> mesh(V, F); 
polyhedron.delegate(mesh); 
myMap[someInt] = new Tree(polyhedron.facets_begin(),polyhedron.facets_end(),polyhedron); 

但隨後墜毀我的代碼。

有什麼辦法可以創建這種類型的STL容器嗎?

UPDATE 14/3/2014

我試着使用刪除的解決方案的建議,但我得到了以下錯誤:

error C2248: 'CGAL::AABB_tree::AABB_tree' : cannot access private member declared in class 'CGAL::AABB_tree'

UPDATE 17/3/2014

這裏是一個不能編譯的示例代碼:

#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; 
} 

任何想法?

+0

究竟是什麼「墜毀」?你使用調試器,不是嗎? (智能)指針的替代方法可以是添加一個間接級別:將數據放入包裝類並定義複製語義,然後創建一個包裝容器。 – Drop

+0

我在寫一個mex文件,所以調試很困難。我確實把數據放在一個包裝類中,但是不可能編寫複製語義,因爲AABB樹沒有複製語義,所以我不能複製它... – DontCareBear

回答

2

使用std::map::emplace() method, std::pair's piecewise constructorperfect forwarding,來構建你的不可複製和不可轉讓的數據就地:

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 

解決辦法很詳細,但完全C++ 11標準兼容。

工作例如:Coliru Viewer

編輯: 使用std::make_tuple而不是std::forward_as_tuple,如果你的編譯器不支持它(#include <tuple>)。

EDIT2:

審查代碼添加剪斷後,我發現,錯誤是由map::emplace方法(可以通過註釋掉它很容易地驗證)不會被觸發,但後來的map::operator[]使用。在內部,map::operator[]使用map::insert(檢查它的源代碼)。只需使用map::at()來解決問題。示例:

FT sqd = myMap.at(1).squared_distance(query); 

請注意,如果找不到密鑰,map::at()會引發異常。在訪問價值之前,您可以通過檢查map::find()來感興趣(取決於性能要求)安全密鑰。

還請注意,由於CGAL內部使用「不安全」字符串函數,您正在收到詳細警告。它們不是錯誤,可以通過添加-D_SCL_SECURE_NO_WARNINGS編譯器標誌來禁用。

希望它有幫助。快樂的編碼!

+0

當我使用你的方法時,出現以下錯誤: 錯誤C2248:'CGAL :: AABB_tree :: AABB_tree':無法訪問在類'CGAL :: AABB_tree ' – DontCareBear

+0

中聲明的私有成員檢查您的代碼:錯誤是否真的指向'emplace()'?檢查你的編譯器版本:它支持C++ 11嗎?我已經測試了MSVC 2013和GCC 4.8(請參閱工作示例,模仿非可複製和不可分配的類型) – Drop

+0

我使用visual studio 2012,因此它支持C++ 11.僅當我嘗試分配AABB樹價值的地圖。我想問題在於CGAL。我懷疑它實際上是CGAL中的一個錯誤......當你使用樹(Tree)構造函數而不是Tree a(...)(它工作正常)時會出現問題。 – DontCareBear

相關問題