1 // Boost.Geometry Index
3 // R-tree OpenGL drawing visitor implementation
5 // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
7 // Use, modification and distribution is subject to the Boost Software License,
8 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
9 // http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
12 #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
14 #include <boost/mpl/assert.hpp>
16 namespace boost { namespace geometry { namespace index { namespace detail {
22 template <typename Point, size_t Dimension>
26 template <typename Point>
27 struct gl_draw_point<Point, 2>
29 static inline void apply(Point const& p, typename coordinate_type<Point>::type z)
31 typename coordinate_type<Point>::type const& x = geometry::get<0>(p);
32 typename coordinate_type<Point>::type const& y = geometry::get<1>(p);
37 glVertex3f(x+1, y, z);
38 glVertex3f(x, y+1, z);
39 glVertex3f(x-1, y, z);
40 glVertex3f(x, y-1, z);
45 template <typename Box, size_t Dimension>
49 template <typename Box>
50 struct gl_draw_box<Box, 2>
52 static inline void apply(Box const& b, typename coordinate_type<Box>::type z)
54 glBegin(GL_LINE_LOOP);
55 glVertex3f(geometry::get<min_corner, 0>(b), geometry::get<min_corner, 1>(b), z);
56 glVertex3f(geometry::get<max_corner, 0>(b), geometry::get<min_corner, 1>(b), z);
57 glVertex3f(geometry::get<max_corner, 0>(b), geometry::get<max_corner, 1>(b), z);
58 glVertex3f(geometry::get<min_corner, 0>(b), geometry::get<max_corner, 1>(b), z);
63 template <typename Segment, size_t Dimension>
64 struct gl_draw_segment
67 template <typename Segment>
68 struct gl_draw_segment<Segment, 2>
70 static inline void apply(Segment const& s, typename coordinate_type<Segment>::type z)
73 glVertex3f(geometry::get<0, 0>(s), geometry::get<0, 1>(s), z);
74 glVertex3f(geometry::get<1, 0>(s), geometry::get<1, 1>(s), z);
79 template <typename Indexable, typename Tag>
80 struct gl_draw_indexable
82 BOOST_MPL_ASSERT_MSG((false), NOT_IMPLEMENTED_FOR_THIS_TAG, (Tag));
85 template <typename Box>
86 struct gl_draw_indexable<Box, box_tag>
87 : gl_draw_box<Box, geometry::dimension<Box>::value>
90 template <typename Point>
91 struct gl_draw_indexable<Point, point_tag>
92 : gl_draw_point<Point, geometry::dimension<Point>::value>
95 template <typename Segment>
96 struct gl_draw_indexable<Segment, segment_tag>
97 : gl_draw_segment<Segment, geometry::dimension<Segment>::value>
100 } // namespace dispatch
102 template <typename Indexable> inline
103 void gl_draw_indexable(Indexable const& i, typename coordinate_type<Indexable>::type z)
105 dispatch::gl_draw_indexable<
107 typename tag<Indexable>::type
111 } // namespace utilities
113 namespace rtree { namespace utilities {
117 template <typename Value, typename Options, typename Translator, typename Box, typename Allocators>
118 struct gl_draw : public rtree::visitor<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag, true>::type
120 typedef typename rtree::internal_node<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type internal_node;
121 typedef typename rtree::leaf<Value, typename Options::parameters_type, Box, Allocators, typename Options::node_tag>::type leaf;
123 inline gl_draw(Translator const& t,
124 size_t level_first = 0,
125 size_t level_last = (std::numeric_limits<size_t>::max)(),
126 typename coordinate_type<Box>::type z_coord_level_multiplier = 1
129 , level_f(level_first)
130 , level_l(level_last)
131 , z_mul(z_coord_level_multiplier)
135 inline void operator()(internal_node const& n)
137 typedef typename rtree::elements_type<internal_node>::type elements_type;
138 elements_type const& elements = rtree::elements(n);
140 if ( level_f <= level )
142 size_t level_rel = level - level_f;
144 if ( level_rel == 0 )
145 glColor3f(0.75f, 0.0f, 0.0f);
146 else if ( level_rel == 1 )
147 glColor3f(0.0f, 0.75f, 0.0f);
148 else if ( level_rel == 2 )
149 glColor3f(0.0f, 0.0f, 0.75f);
150 else if ( level_rel == 3 )
151 glColor3f(0.75f, 0.75f, 0.0f);
152 else if ( level_rel == 4 )
153 glColor3f(0.75f, 0.0f, 0.75f);
154 else if ( level_rel == 5 )
155 glColor3f(0.0f, 0.75f, 0.75f);
157 glColor3f(0.5f, 0.5f, 0.5f);
159 for (typename elements_type::const_iterator it = elements.begin();
160 it != elements.end(); ++it)
162 detail::utilities::gl_draw_indexable(it->first, level_rel * z_mul);
166 size_t level_backup = level;
169 if ( level < level_l )
171 for (typename elements_type::const_iterator it = elements.begin();
172 it != elements.end(); ++it)
174 rtree::apply_visitor(*this, *it->second);
178 level = level_backup;
181 inline void operator()(leaf const& n)
183 typedef typename rtree::elements_type<leaf>::type elements_type;
184 elements_type const& elements = rtree::elements(n);
186 if ( level_f <= level )
188 size_t level_rel = level - level_f;
190 glColor3f(0.25f, 0.25f, 0.25f);
192 for (typename elements_type::const_iterator it = elements.begin();
193 it != elements.end(); ++it)
195 detail::utilities::gl_draw_indexable(tr(*it), level_rel * z_mul);
200 Translator const& tr;
203 typename coordinate_type<Box>::type z_mul;
208 } // namespace visitors
210 template <typename Rtree> inline
211 void gl_draw(Rtree const& tree,
212 size_t level_first = 0,
213 size_t level_last = (std::numeric_limits<size_t>::max)(),
214 typename coordinate_type<
215 typename Rtree::bounds_type
216 >::type z_coord_level_multiplier = 1
219 typedef utilities::view<Rtree> RTV;
224 glColor3f(0.75f, 0.75f, 0.75f);
225 detail::utilities::gl_draw_indexable(tree.bounds(), 0);
229 typename RTV::value_type,
230 typename RTV::options_type,
231 typename RTV::translator_type,
232 typename RTV::box_type,
233 typename RTV::allocators_type
234 > gl_draw_v(rtv.translator(), level_first, level_last, z_coord_level_multiplier);
236 rtv.apply_visitor(gl_draw_v);
239 }} // namespace rtree::utilities
241 }}}} // namespace boost::geometry::index::detail
243 #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP