snark
ShapeReader.h
1 // This file is part of snark, a generic and flexible library
2 // for robotics research.
3 //
4 // Copyright (C) 2011 The University of Sydney
5 //
6 // snark is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // snark is distributed in the hope that it will be useful, but WITHOUT ANY
12 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 // for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with snark. If not, see <http://www.gnu.org/licenses/>.
18 
20 
21 #ifndef SNARK_GRAPHICS_APPLICATIONS_VIEWPOINTS_SHAPE_READER_H_
22 #define SNARK_GRAPHICS_APPLICATIONS_VIEWPOINTS_SHAPE_READER_H_
23 
24 #ifdef WIN32
25 #include <winsock2.h>
26 
27 //#include <windows.h>
28 #endif
29 
30 #include "./Reader.h"
31 #include "./ShapeWithId.h"
32 
33 namespace snark { namespace graphics { namespace View {
34 
35 template< typename S >
36 class ShapeReader : public Reader
37 {
38  public:
39  ShapeReader( QGLView& viewer, comma::csv::options& options, std::size_t size, coloured* c, unsigned int pointSize, const std::string& label );
40 
41  void start();
42  void update( const Eigen::Vector3d& offset );
43  const Eigen::Vector3d& somePoint() const;
44  bool readOnce();
45  void render( QGLPainter *painter = NULL );
46  bool empty() const;
47 
48  private:
49  typedef std::deque< ShapeWithId< S > > DequeType;
50  DequeType m_deque;
51  mutable boost::mutex m_mutex;
52  boost::scoped_ptr< comma::csv::input_stream< ShapeWithId< S > > > m_stream;
53  qt3d::vertex_buffer m_buffer;
54  std::vector< std::pair< QVector3D, std::string > > m_labels;
55  unsigned int m_labelIndex;
56  unsigned int m_labelSize;
57 };
58 
59 
60 template< typename S >
61 ShapeReader< S >::ShapeReader( QGLView& viewer, comma::csv::options& options, std::size_t size, coloured* c, unsigned int pointSize, const std::string& label ):
62  Reader( viewer, options, size, c, pointSize, label ),
63  m_buffer( size * Shapetraits< S >::size ),
64  m_labels( size ),
65  m_labelIndex( 0 ),
66  m_labelSize( 0 )
67 {
68 }
69 
70 template< typename S >
71 inline void ShapeReader< S >::start()
72 {
73  m_thread.reset( new boost::thread( boost::bind( &Reader::read, boost::ref( *this ) ) ) );
74 }
75 
76 template< typename S >
77 inline void ShapeReader< S >::update( const Eigen::Vector3d& offset )
78 {
79  boost::mutex::scoped_lock lock( m_mutex );
80  for( typename DequeType::iterator it = m_deque.begin(); it != m_deque.end(); ++it )
81  {
82  Shapetraits< S >::update( it->shape, offset, it->color, it->block, m_buffer, m_extents );
83  }
84  m_deque.clear();
85  updatePoint( offset );
86 }
87 
88 template< typename S >
89 inline bool ShapeReader< S >::empty() const
90 {
91  boost::mutex::scoped_lock lock( m_mutex );
92  return m_deque.empty();
93 }
94 
95 template< typename S >
96 inline const Eigen::Vector3d& ShapeReader< S >::somePoint() const
97 {
98  boost::mutex::scoped_lock lock( m_mutex );
99  return Shapetraits< S >::somePoint( m_deque.front().shape );
100 }
101 
102 template< typename S >
103 inline void ShapeReader< S >::render( QGLPainter* painter )
104 {
105  painter->setStandardEffect(QGL::FlatPerVertexColor);
106  painter->clearAttributes();
107  painter->setVertexAttribute(QGL::Position, m_buffer.points() );
108  painter->setVertexAttribute(QGL::Color, m_buffer.color() );
109 
110  Shapetraits< S >::draw( painter, m_buffer.size(), m_buffer.index() );
111  for( unsigned int i = 0; i < m_labelSize; i++ )
112  {
113  drawLabel( painter, m_labels[ i ].first, m_labels[ i ].second );
114  }
115  if( !m_label.empty() )
116  {
117  drawLabel( painter, m_translation );
118  }
119 }
120 
121 template< typename S >
122 inline bool ShapeReader< S >::readOnce()
123 {
124  try
125  {
126  if( !m_stream ) // quick and dirty: handle named pipes
127  {
128  if( !m_istream() )
129  {
130 #ifndef WIN32
131  // HACK poll on blocking pipe
132  ::usleep( 1000 );
133 #endif
134  return true;
135  }
136  m_stream.reset( new comma::csv::input_stream< ShapeWithId< S > >( *m_istream(), options ) );
137  }
138  const ShapeWithId< S >* p = m_stream->read();
139  if( p == NULL )
140  {
141  m_shutdown = true;
142  return false;
143  }
144  ShapeWithId< S > v = *p;
145  Eigen::Vector3d center = Shapetraits< S >::center( v.shape );
146  if( !v.label.empty() )
147  {
148  m_labels[ m_labelIndex ] = std::make_pair( QVector3D( center.x(), center.y(), center.z() ) , v.label );
149  m_labelIndex++;
150  if( m_labelSize < m_labels.size() )
151  {
152  m_labelSize++;
153  }
154  if( m_labelIndex > m_labels.size() )
155  {
156  m_labelIndex = 0;
157  }
158  }
159  v.color = m_colored->color( center, p->id, p->scalar, p->color );
160  boost::mutex::scoped_lock lock( m_mutex );
161  m_deque.push_back( v );
162  m_point = Shapetraits< S >::somePoint( v.shape );
163  m_color = v.color;
164  return true;
165  }
166  catch( std::exception& ex ) { std::cerr << "view-points: " << ex.what() << std::endl; }
167  catch( ... ) { std::cerr << "view-points: unknown exception" << std::endl; }
168  return false;
169 }
170 
171 } } } // namespace snark { namespace graphics { namespace View {
172 
173 #endif // SNARK_GRAPHICS_APPLICATIONS_VIEWPOINTS_SHAPE_READER_H_