Updating CGAL program to use AABB_face_graph_triangle_primitive - c++

I have a C++ program that uses the CGAL 4.5.2_0 library, installed using macports. Recently, I have been getting compile-time warnings that the CGAL/AABB_polyhedron_triangle_primitive.h header is deprecated and that I now should start using CGAL/AABB_face_graph_triangle_primitive.h, so I naively switched the header name and also added the CGAL/boost/graph/graph_traits_Polyhedron_3.h header file which now seems to be necessary to interface with the Boost Graph Library. I noticed also from examples in the CGAL documentation that one of my typedefs needed to be updated from
typedef CGAL::AABB_polyhedron_triangle_primitive<K,Polyhedron> Primitive;
to
typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
And so far, that is the extent of what I have done. But now I am getting two new errors at compile time:
In file included from ./Particle.h:44:
/opt/local/include/CGAL/AABB_tree.h:810:27: error: no matching conversion for functional-style cast from 'CGAL::internal::In_place_list_iterator<CGAL::HalfedgeDS_in_place_list_face<CGAL::I_Polyhedron_facet<My_facet<CGAL::HalfedgeDS_list_types<CGAL::Epick, CGAL::I_Polyhedron_derived_items_3<My_items>, std::__1::allocator<int> >, CGAL::Boolean_tag<true>, CGAL::Vector_3<CGAL::Epick> > > >, std::__1::allocator<CGAL::HalfedgeDS_in_place_list_face<CGAL::I_Polyhedron_facet<My_facet<CGAL::HalfedgeDS_list_types<CGAL::Epick, CGAL::I_Polyhedron_derived_items_3<My_items>, std::__1::allocator<int> >, CGAL::Boolean_tag<true>, CGAL::Vector_3<CGAL::Epick> > > > > >' to 'Primitive' (aka 'CGAL::AABB_face_graph_triangle_primitive<CGAL::Polyhedron_3<CGAL::Epick, My_items, HalfedgeDS_default, std::__1::allocator<int> >, CGAL::Default, CGAL::Boolean_tag<true>, CGAL::Boolean_tag<false> >')
m_primitives.push_back(Primitive(first));
In file included from ./Particle.h:45:
/opt/local/include/CGAL/AABB_traits.h:63:33: error: no matching member function for call to 'construct_shared_data'
m_primitive_data=Primitive::construct_shared_data();
~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
/opt/local/include/CGAL/AABB_tree.h:268:15: note: in instantiation of member function 'CGAL::internal::AABB_tree::AABB_traits_base<CGAL::AABB_face_graph_triangle_primitive<CGAL::Polyhedron_3<CGAL::Epick, My_items, HalfedgeDS_default, std::__1::allocator<int> >, CGAL::Default, CGAL::Boolean_tag<true>, CGAL::Boolean_tag<false> >, true>::set_shared_data' requested here
{m_traits.set_shared_data();}
^
If anyone has experience switching from the deprecated header file to the new one, I will be grateful for any advice you might have about how I should proceed.
I can post the header file for the Particle class that seems to be the problem, but it is 3282 lines long and I'm not sure which part(s) I should post.
In response to comment, here is the code that is used to insert primitives in the tree:
// The next chunk creates the 3D polyhedron, storing it in surface_poly
Polyhedron surface_poly = getSurfacePolyhedronFromImage(fname,centroid,xBB,yBB,zBB);
// First translate its centroid to the origin
// CartesianVector is a typedef of CGAL's Vector_3
const CartesianVector translation_vector(-centroid[0],-centroid[1],-centroid[2]);
Aff_transformation_3 transl(CGAL::TRANSLATION, translation_vector);
transform(surface_poly.points_begin(),surface_poly.points_end(),
surface_poly.points_begin(),transl);
// Now the centroid is the origin
centroid.resize(3,0.0);
CartesianPoint origin(0.0,0.0,0.0);
// Construct the AABB tree for quick intersection queries
cout << "Creating AABB tree from polyhedron" << endl;
cout.flush();
Tree tree(surface_poly.facets_begin(),surface_poly.facets_end());
// Object intersection will hold the point of intersection with the surface
boost::optional<Object_and_primitive_id> intersection;

The syntax for the Tree constructor is incorrect for the Polyhedron_3 in the code above. The correct syntax should be
Tree tree(faces(surface_poly).first, faces(surface_poly).second, surface_poly);
Updating the syntax to the correct form fixes the compile-time errors.

Related

Why does std::list<string> work but not std::list<int>

I'm using templates while implementing AVL trees on Ubuntu.
The file will not compile when I write template class AVLTree<std::list<int> >;, it tells me:
undefined reference to `AVLTree < std::__cxx11::list < std::__cxx11::basic_string < char, std::char_traits < char>, std::allocator < char> >, std::allocator < std::__cxx11::basic_string < char, std::char_traits < char>, std::allocator < char> > > > >::insert(std::__cxx11::basic_string < char, std::char_traits < char>, std::allocator < char> >)'
And I don't get what it doesn't have the reference to.
But it compiles just fine when I write template class AVLTree<std::list<string> >;
I need to let AVLTree store linked lists that store string values.
Why does one compile and the other doesn't? How to solve my problem?
PS: I've included <list>, <string>, and <iostream>, along with my own header file.
Examining the error message closely shows that linker cannot find the AVLTree::insert(string) method.
Based on the sparse information that you posted, my best hypothesis is that you changed the template parameter in the following line from list<string> to list<int>:
template class AVLTree<std::list<string>>;
This line of code explicitly tells the compiler to instantiate a version of the AVLTree template using list<string> as the template parameter. Thus, when you try to compile the code after the change it gives you the error message that it cannot find the AVLTree::insert(string) function because the compiler is now generating the code for list<int> instead.
Your program contains other code that is referencing AVLTree<list<string>>. At a minimum you will have to update that code to use list<int> as well.
Plus, if you simplify the problem down to something you can post the code for on this site, then you will either find the issue during that process or at least have a change of getting a good answer.

Eclipse CDT cannot display stl::map information

I had a problem when using Eclipse CDT with detecting stl information. I got in-editor errors like "symbol vector could not be resolved". I have solved this using the solution described here:
https://stackoverflow.com/a/13524483/613173
However, it seems that stl::map still has problems. For example, the line
std::map<int,int> a;
Gets the "invalid template arguments" error. Also,
a.begin();
Gives "method 'begin' could not be resolved" error.
However, with default parameters given explicitly:
std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > > b;
I got none of those errors. This does not happen with other classes such as std::vector whose template also has more than one argument but I get no complaints over
std::vector<int> a;
Another problem regards iterators. Even if the map was defined with all parameters given explicitly, the "first" and "second" fields give an error:
std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >::iterator i_b = b.begin();
i_b->first;
This gives "Field 'first' could not be resolved".
Compilation works without problems, obviously, but I still want to be able to use Eclipse's static error detection and auto completion.
Eclipse 4.4.2, CDT 8.6.

C++ unordered_map errors when pointing to a vector

I am having some issues using the unordered map below:
unordered_map<string, vector<string>> FriendHash;
When I compile my code I get the following errors:
usr/lib/c++/v1/type_traits:922:38: Implicit instantiation of undefined template 'std::__1::hash<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >'
usr/lib/c++/v1/unordered_map:360:71: No member named 'value' in 'std::__1::is_empty<std::__1::hash<std::__1::basic_string<char> > >'
Hoping someone can point me in the right direction.
Whatever you use needs to be defined. You need to include string here possibly along with other dependencies.
#include <string>

Compile error with boost.graph 1.56.0 and g++ 4.6.4

Got a savage few compile errors while trying to use Boost.Graph. The error is a regression as it is not present when compiling 1.55.0. I've dug a bit but can't fix it, does anyone know what is going wrong here?
Notes:
Using the -std=c++0x compile flag
Code that will generate the errors.
#include "boost/graph/adjacency_list.hpp"
int main(int argc, char** argv)
{
using boost::adjacency_list;
using boost::vecS;
using boost::directedS;
typedef adjacency_list<vecS, vecS, directedS, boost::default_color_type> Graph;
std::vector< std::pair<int, int> > testVec;
auto graph = Graph( begin(testVec), end(testVec), testVec.size());
return 0;
}
Errors copied out of my IDE
/usr/include/c++/4.6/bits/vector.tcc:319: error: use of deleted
function ‘boost::detail::stored_edge_property::self&
boost::detail::stored_edge_property::operator=(boost::detail::stored_edge_property::self&&) [with Vertex = long unsigned int, Property =
boost::no_property, boost::detail::stored_edge_property::self = boost::detail::stored_edge_property]’
.../boost/boost/graph/detail/adjacency_list.hpp:318:
error: ‘boost::detail::stored_edge_property::self&
boost::detail::stored_edge_property::operator=(boost::detail::stored_edge_property::self&&) [with Vertex = long unsigned int, Property =
boost::no_property, boost::detail::stored_edge_property::self = boost::detail::stored_edge_property]’ is implicitly deleted because the default
definition would be ill-formed:
.../boost/boost/graph/detail/adjacency_list.hpp:318: error: base
‘boost::detail::stored_edge’ does not have a move
assignment operator or trivial copy assignment operator
/usr/include/c++/4.6/bits/stl_algobase.h:546: error: use of deleted
function ‘boost::detail::stored_edge_property::self&
boost::detail::stored_edge_property::operator=(boost::detail::stored_edge_property::self&&) [with Vertex = long unsigned int, Property =
boost::no_property, boost::detail::stored_edge_property::self = boost::detail::stored_edge_property]’
It appears that the implementation of stored_edge_property (a under-the-hood class to store edge properties) was updated for C++11 rvalue references between the version 1.55 to 1.56 (you can see it clearly by diff'ing the files). It appears that they forgot to provide a move-assignment operator for its base class stored_edge (and the default one is implicitly disabled by the presence of a copy-assignment operator).
This is definitely a bug and should be reported to Boost. I remember that they made a virtually identical mistake with shared_ptr around the 1.48 version. I guess people don't always learn from their own mistakes. The fix is trivial, but this really should have been caught before release (it seems like a very easy bug to catch in a unit-test). Please report your findings to their bug tracker.
N.B.: I use BGL a lot, but I have learned to distrust their adjacency_list implementation, especially after looking through it extensively. I now use my own implementation of it (see here) which cuts through a lot of the fat of the monstrous implementation that the BGL carries around.

Boost graph library causing errors when applying dijkstra's algorithm

I have been loosely following this example, this one, and this stack overflow post to try to apply Dijkstra's algorithm to find the cost of the shortest path between two nodes.
If I try to follow the first example, I get an error with the typedef statement for NameMap. This error is cryptic, verbose, and I don't quite know what to do with it.
If I try to follow the second example (copy-pasted from the Boost documentation!!) it does not compile. The error is even more cryptic and verbose.
The third one (the stack overflow post) relies on the same typedef as the first one.
Is this user error? It probably is, but how should I interpret an error message that spawns from the library code?
Update 1
I am using g++ (Debian 4.8.2-21) 4.8.2 from debian testing.
Update 2
Here is a condensed version of the source code that doesn't work. There are two lines prefaced by "// The following line causes an error" are the ones in question.
Update 3
I have changed
typedef adjacency_list<listS, vecS, directedS, allow_parallel_edge_tag, EdgeWeightProperty> Graph;
typedef adjacency_list<listS, vecS, directedS, no_property , EdgeWeightProperty> Graph;
Your first attempt didn't define a property with the vertex_name_t tag (or pass it as a adjacency_list template parameter), so when you try to create a property_map with that tag the compiler emits an error.
Your code:
typedef property<edge_weight_t, Weight> EdgeWeightProperty;
typedef boost::adjacency_list<listS, vecS, directedS, allow_parallel_edge_tag, EdgeWeightProperty> Graph;
// ^ What's this?
The example code you cited:
typedef boost::property<boost::edge_weight_t, Weight> WeightProperty;
typedef boost::property<boost::vertex_name_t, std::string> NameProperty; // <-- not in your code
typedef boost::adjacency_list < boost::listS, boost::vecS, boost::directedS, NameProperty, WeightProperty > Graph;
// ^ Used here
I have no idea why you are passing allow_parallel_edge_tag as a template parameter. If I'm reading the documentation correctly, that struct is designed for parallel_edge_traits specializations when you are using custom container types.
Edit: The second case is actually easy to diagnose once you have the code. Going through the error messages emitted by the compiler, we look for reasons why the compiler didn't select the 3-parameter overload for dijkstra_shortest_paths. A lot of the messages merely tells you that it rejected overloads with about a dozen parameters - as it should!
Now, this error message (emitted by g++ using Coliru) is pertinent, because it tells you why compiler rejected the three-parameter version:
In file included from main.cpp:5:0:
/usr/local/include/boost/graph/dijkstra_shortest_paths.hpp:602:3: note: void boost::
dijkstra_shortest_paths(const VertexListGraph&, typename boost::graph_traits<Graph>::
vertex_descriptor, const boost::bgl_named_params<T, Tag, Base>&) [ /* irrelevant stuff
telling you how it deduced the template parameters here */ ] <near match>
dijkstra_shortest_paths
^
/usr/local/include/boost/graph/dijkstra_shortest_paths.hpp:602:3: note: no known conversion for
argument 2 from 'long int [6]' to 'boost::graph_traits<boost::adjacency_list<boost::listS,
boost::vecS, boost::directedS, boost::no_property, boost::property<boost::edge_weight_t, long int> >
>::vertex_descriptor {aka long unsigned int}'
You passed s, the array containing source vertices, as the second parameter designating the starting vertex, when you should have passed v0, and the compiler is rightfully complaining that it cannot convert an array of longs to a single vertex.