Search code examples
intersectioncgalraytracingaabb

Get primitive from AABB tree intersection


This code contains an AABB Tree which is build using a Polyhedron_3 mesh. It is possible to verify if an intersection occures but not what primitive the intersection hit. How can I retrieve the primitive?

typedef CGAL::Polyhedron_3<Kernel>         Polyhedron;
const Polyhedron& mesh;
tree(faces(_mesh).first, faces(_mesh).second, _mesh);

boost::optional<Primitive_id> intersection = tree.first_intersected_primitive(ray);

if(intersection)
{
//how to get the primitive?
}

Edit:

faces(mesh, tree);
faces(*mesh, tree);

faces(hit, tree);
faces(*hit, tree);

Does not work too.

Edit2:

                CGAL::internal::In_place_list_iterator<CGAL::HalfedgeDS_in_place_list_face<CGAL::I_Polyhedron_facet<CGAL::HalfedgeDS_face_base<CGAL::HalfedgeDS_list_types<CGAL::Simple_cartesian<double>, CGAL::I_Polyhedron_derived_items_3<CGAL::Polyhedron_items_3>, std::allocator<int> >, CGAL::Boolean_tag<true>, CGAL::Plane_3<CGAL::Simple_cartesian<double> > > > >, std::allocator<CGAL::HalfedgeDS_in_place_list_face<CGAL::I_Polyhedron_facet<CGAL::HalfedgeDS_face_base<CGAL::HalfedgeDS_list_types<CGAL::Simple_cartesian<double>, CGAL::I_Polyhedron_derived_items_3<CGAL::Polyhedron_items_3>, std::allocator<int> >, CGAL::Boolean_tag<true>, CGAL::Plane_3<CGAL::Simple_cartesian<double> > > > > > > it = *hit;

                CGAL::I_Polyhedron_facet<CGAL::HalfedgeDS_face_base<CGAL::HalfedgeDS_list_types<CGAL::Simple_cartesian<double>, CGAL::I_Polyhedron_derived_items_3<CGAL::Polyhedron_items_3>, std::allocator<int> >, CGAL::Boolean_tag<true>, CGAL::Plane_3<CGAL::Simple_cartesian<double> > > >::Halfedge_around_facet_circulator ipfacet = it->facet_begin();

Gets you an iterrator and I_Polyhedron_facet.


Solution

  • Cgal is realy missing some documentation.

    Here is the solution: Get the iterator around the face verticess primitive_id->facet_begin(); . And then do this.

                Ray_intersection hit = tree.first_intersection(rays[this->transformCoordinates(y,x)]);
                if(hit)
                {
                    const Point& point =  boost::get<Point>(hit->first);
                    const Primitive_id& primitive_id = boost::get<Primitive_id>(hit->second);
    
                    Polyhedron::Halfedge_around_facet_circulator facerunner = primitive_id->facet_begin();
    
                    Point p1;
                    Point p2;
                    Point p3;
    
                    p1 = facerunner->vertex()->point();
                    facerunner++;
                    p2 = facerunner->vertex()->point();
                    facerunner++;
                    p3 = facerunner->vertex()->point();
    
                    Vector v1(p1,p2);
                    Vector v2(p1,p3);
    
                    Vector n = CGAL::cross_product(v1,v2);
                    n = n/ std::sqrt(n.squared_length());
        }
    

    Answer from the cgal mailinglist:

    what are you looking for that is not available here:

    https://doc.cgal.org/latest/AABB_tree/index.html#title6

    Also note that from here: https://doc.cgal.org/latest/AABB_tree/classCGAL_1_1AABB__face__graph__triangle__primitive.html

    you have: typedef boost::graph_traits< FaceGraph >::face_descriptor Id

    From that same page, you see that the graph type is model of FaceGraph:

    https://doc.cgal.org/latest/BGL/classFaceGraph.html

    Depending on the type of graph chosen, you have access to the precise documentation of what face_descriptor corresponds to:

    https://doc.cgal.org/latest/BGL/group__PkgBGLTraits.html

    Then you can refer to the documentation of the class to know how to iterate over the vertex of the face.

    There is even a generic helper function to do it:

    for ( boost::graph_traits<Graph>::vertex_descriptor v :
          CGAL::vertices_around_face(halfedge(f, g), g))
    {
      Point_3 p = get(boost::vertex_index, v, g);
    }
    

    I'm not saying it is easy to get but reading the doc gives you the information required. It's not like reading vtk doc where you have to guess or read the source code to understand things.

    Anyway, we are always looking to improve our doc and we'll be soon having some cross-packages tutorials and one about manipulation of surface meshes in CGAL will surely be added.