1 // Boost.Geometry Index
3 // R-tree OpenGL drawing visitor implementation
5 // Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
7 // This file was modified by Oracle on 2019-2020.
8 // Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
9 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
11 // Use, modification and distribution is subject to the Boost Software License,
12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
13 // http://www.boost.org/LICENSE_1_0.txt)
15 #ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
16 #define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP
18 #include <boost/geometry/core/static_assert.hpp>
20 namespace boost { namespace geometry { namespace index { namespace detail {
26 template <typename Point, size_t Dimension>
30 template <typename Point>
31 struct gl_draw_point<Point, 2>
33 static inline void apply(Point const& p, typename coordinate_type<Point>::type z)
35 typename coordinate_type<Point>::type const& x = geometry::get<0>(p);
36 typename coordinate_type<Point>::type const& y = geometry::get<1>(p);
41 glVertex3f(x+1, y, z);
42 glVertex3f(x, y+1, z);
43 glVertex3f(x-1, y, z);
44 glVertex3f(x, y-1, z);
49 template <typename Box, size_t Dimension>
53 template <typename Box>
54 struct gl_draw_box<Box, 2>
56 static inline void apply(Box const& b, typename coordinate_type<Box>::type z)
58 glBegin(GL_LINE_LOOP);
59 glVertex3f(geometry::get<min_corner, 0>(b), geometry::get<min_corner, 1>(b), z);
60 glVertex3f(geometry::get<max_corner, 0>(b), geometry::get<min_corner, 1>(b), z);
61 glVertex3f(geometry::get<max_corner, 0>(b), geometry::get<max_corner, 1>(b), z);
62 glVertex3f(geometry::get<min_corner, 0>(b), geometry::get<max_corner, 1>(b), z);
67 template <typename Segment, size_t Dimension>
68 struct gl_draw_segment
71 template <typename Segment>
72 struct gl_draw_segment<Segment, 2>
74 static inline void apply(Segment const& s, typename coordinate_type<Segment>::type z)
77 glVertex3f(geometry::get<0, 0>(s), geometry::get<0, 1>(s), z);
78 glVertex3f(geometry::get<1, 0>(s), geometry::get<1, 1>(s), z);
83 template <typename Indexable, typename Tag>
84 struct gl_draw_indexable
86 BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
87 "Not implemented for this Indexable type.",
91 template <typename Box>
92 struct gl_draw_indexable<Box, box_tag>
93 : gl_draw_box<Box, geometry::dimension<Box>::value>
96 template <typename Point>
97 struct gl_draw_indexable<Point, point_tag>
98 : gl_draw_point<Point, geometry::dimension<Point>::value>
101 template <typename Segment>
102 struct gl_draw_indexable<Segment, segment_tag>
103 : gl_draw_segment<Segment, geometry::dimension<Segment>::value>
106 } // namespace dispatch
108 template <typename Indexable> inline
109 void gl_draw_indexable(Indexable const& i, typename coordinate_type<Indexable>::type z)
111 dispatch::gl_draw_indexable<
113 typename tag<Indexable>::type
117 } // namespace utilities
119 namespace rtree { namespace utilities {
123 template <typename MembersHolder>
125 : public MembersHolder::visitor_const
127 typedef typename MembersHolder::box_type box_type;
128 typedef typename MembersHolder::translator_type translator_type;
130 typedef typename MembersHolder::internal_node internal_node;
131 typedef typename MembersHolder::leaf leaf;
133 inline gl_draw(translator_type const& t,
134 size_t level_first = 0,
135 size_t level_last = (std::numeric_limits<size_t>::max)(),
136 typename coordinate_type<box_type>::type z_coord_level_multiplier = 1
139 , level_f(level_first)
140 , level_l(level_last)
141 , z_mul(z_coord_level_multiplier)
145 inline void operator()(internal_node const& n)
147 typedef typename rtree::elements_type<internal_node>::type elements_type;
148 elements_type const& elements = rtree::elements(n);
150 if ( level_f <= level )
152 size_t level_rel = level - level_f;
154 if ( level_rel == 0 )
155 glColor3f(0.75f, 0.0f, 0.0f);
156 else if ( level_rel == 1 )
157 glColor3f(0.0f, 0.75f, 0.0f);
158 else if ( level_rel == 2 )
159 glColor3f(0.0f, 0.0f, 0.75f);
160 else if ( level_rel == 3 )
161 glColor3f(0.75f, 0.75f, 0.0f);
162 else if ( level_rel == 4 )
163 glColor3f(0.75f, 0.0f, 0.75f);
164 else if ( level_rel == 5 )
165 glColor3f(0.0f, 0.75f, 0.75f);
167 glColor3f(0.5f, 0.5f, 0.5f);
169 for (typename elements_type::const_iterator it = elements.begin();
170 it != elements.end(); ++it)
172 detail::utilities::gl_draw_indexable(it->first, level_rel * z_mul);
176 size_t level_backup = level;
179 if ( level < level_l )
181 for (typename elements_type::const_iterator it = elements.begin();
182 it != elements.end(); ++it)
184 rtree::apply_visitor(*this, *it->second);
188 level = level_backup;
191 inline void operator()(leaf const& n)
193 typedef typename rtree::elements_type<leaf>::type elements_type;
194 elements_type const& elements = rtree::elements(n);
196 if ( level_f <= level )
198 size_t level_rel = level - level_f;
200 glColor3f(0.25f, 0.25f, 0.25f);
202 for (typename elements_type::const_iterator it = elements.begin();
203 it != elements.end(); ++it)
205 detail::utilities::gl_draw_indexable(tr(*it), level_rel * z_mul);
210 translator_type const& tr;
213 typename coordinate_type<box_type>::type z_mul;
218 } // namespace visitors
220 template <typename Rtree> inline
221 void gl_draw(Rtree const& tree,
222 size_t level_first = 0,
223 size_t level_last = (std::numeric_limits<size_t>::max)(),
224 typename coordinate_type<
225 typename Rtree::bounds_type
226 >::type z_coord_level_multiplier = 1
229 typedef utilities::view<Rtree> RTV;
234 glColor3f(0.75f, 0.75f, 0.75f);
235 detail::utilities::gl_draw_indexable(tree.bounds(), 0);
239 typename RTV::members_holder
240 > gl_draw_v(rtv.translator(), level_first, level_last, z_coord_level_multiplier);
242 rtv.apply_visitor(gl_draw_v);
245 }} // namespace rtree::utilities
247 }}}} // namespace boost::geometry::index::detail
249 #endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_UTILITIES_GL_DRAW_HPP