// Boost.Geometry Index // // R-tree OpenGL drawing visitor implementation // // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. // // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP #include namespace boost { namespace geometry { namespace index { namespace detail { namespace utilities { namespace dispatch { template struct gl_draw_point {}; template struct gl_draw_point { static inline void apply(Point const& p, typename coordinate_type::type z) { typename coordinate_type::type const& x = geometry::get<0>(p); typename coordinate_type::type const& y = geometry::get<1>(p); /*glBegin(GL_POINT); glVertex3f(x, y, z); glEnd();*/ glBegin(GL_QUADS); glVertex3f(x+1, y, z); glVertex3f(x, y+1, z); glVertex3f(x-1, y, z); glVertex3f(x, y-1, z); glEnd(); } }; template struct gl_draw_box {}; template struct gl_draw_box { static inline void apply(Box const& b, typename coordinate_type::type z) { glBegin(GL_LINE_LOOP); glVertex3f(geometry::get(b), geometry::get(b), z); glVertex3f(geometry::get(b), geometry::get(b), z); glVertex3f(geometry::get(b), geometry::get(b), z); glVertex3f(geometry::get(b), geometry::get(b), z); glEnd(); } }; template struct gl_draw_segment {}; template struct gl_draw_segment { static inline void apply(Segment const& s, typename coordinate_type::type z) { glBegin(GL_LINES); glVertex3f(geometry::get<0, 0>(s), geometry::get<0, 1>(s), z); glVertex3f(geometry::get<1, 0>(s), geometry::get<1, 1>(s), z); glEnd(); } }; template struct gl_draw_indexable { BOOST_MPL_ASSERT_MSG((false), NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag)); }; template struct gl_draw_indexable : gl_draw_box::value> {}; template struct gl_draw_indexable : gl_draw_point::value> {}; template struct gl_draw_indexable : gl_draw_segment::value> {}; } // namespace dispatch template inline void gl_draw_indexable(Indexable const& i, typename coordinate_type::type z) { dispatch::gl_draw_indexable< Indexable, typename tag::type >::apply(i, z); } } // namespace utilities namespace rtree { namespace utilities { namespace visitors { template struct gl_draw : public rtree::visitor::type { typedef typename rtree::internal_node::type internal_node; typedef typename rtree::leaf::type leaf; inline gl_draw(Translator const& t, size_t level_first = 0, size_t level_last = (std::numeric_limits::max)(), typename coordinate_type::type z_coord_level_multiplier = 1 ) : tr(t) , level_f(level_first) , level_l(level_last) , z_mul(z_coord_level_multiplier) , level(0) {} inline void operator()(internal_node const& n) { typedef typename rtree::elements_type::type elements_type; elements_type const& elements = rtree::elements(n); if ( level_f <= level ) { size_t level_rel = level - level_f; if ( level_rel == 0 ) glColor3f(0.75f, 0.0f, 0.0f); else if ( level_rel == 1 ) glColor3f(0.0f, 0.75f, 0.0f); else if ( level_rel == 2 ) glColor3f(0.0f, 0.0f, 0.75f); else if ( level_rel == 3 ) glColor3f(0.75f, 0.75f, 0.0f); else if ( level_rel == 4 ) glColor3f(0.75f, 0.0f, 0.75f); else if ( level_rel == 5 ) glColor3f(0.0f, 0.75f, 0.75f); else glColor3f(0.5f, 0.5f, 0.5f); for (typename elements_type::const_iterator it = elements.begin(); it != elements.end(); ++it) { detail::utilities::gl_draw_indexable(it->first, level_rel * z_mul); } } size_t level_backup = level; ++level; if ( level < level_l ) { for (typename elements_type::const_iterator it = elements.begin(); it != elements.end(); ++it) { rtree::apply_visitor(*this, *it->second); } } level = level_backup; } inline void operator()(leaf const& n) { typedef typename rtree::elements_type::type elements_type; elements_type const& elements = rtree::elements(n); if ( level_f <= level ) { size_t level_rel = level - level_f; glColor3f(0.25f, 0.25f, 0.25f); for (typename elements_type::const_iterator it = elements.begin(); it != elements.end(); ++it) { detail::utilities::gl_draw_indexable(tr(*it), level_rel * z_mul); } } } Translator const& tr; size_t level_f; size_t level_l; typename coordinate_type::type z_mul; size_t level; }; } // namespace visitors template inline void gl_draw(Rtree const& tree, size_t level_first = 0, size_t level_last = (std::numeric_limits::max)(), typename coordinate_type< typename Rtree::bounds_type >::type z_coord_level_multiplier = 1 ) { typedef utilities::view RTV; RTV rtv(tree); if ( !tree.empty() ) { glColor3f(0.75f, 0.75f, 0.75f); detail::utilities::gl_draw_indexable(tree.bounds(), 0); } visitors::gl_draw< typename RTV::value_type, typename RTV::options_type, typename RTV::translator_type, typename RTV::box_type, typename RTV::allocators_type > gl_draw_v(rtv.translator(), level_first, level_last, z_coord_level_multiplier); rtv.apply_visitor(gl_draw_v); } }} // namespace rtree::utilities }}}} // namespace boost::geometry::index::detail #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP