Orfeo Toolbox  3.16
otbVectorDataGlComponent.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ORFEO Toolbox
4  Language: C++
5  Date: $Date$
6  Version: $Revision$
7 
8 
9  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
10  See OTBCopyright.txt for details.
11 
12 
13  This software is distributed WITHOUT ANY WARRANTY; without even
14  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  PURPOSE. See the above copyright notices for more information.
16 
17 =========================================================================*/
18 #ifndef __otbVectorDataGlComponent_txx
19 #define __otbVectorDataGlComponent_txx
20 
22 
23 // We need this include to get NodeType enum right.
24 #include "otbDataNode.h"
25 #include "itkTimeProbe.h"
26 
27 namespace otb
28 {
29 template <class TVectorData>
31 ::VectorDataGlComponent() : m_VectorData(), m_Spacing(), m_Origin(), m_GluTesselator(),
32  m_Color(), m_LineWidth(1.5), m_CrossWidth(10), m_RenderPolygonBoundariesOnly(false)
33 {
34  // Default color is red
35  m_Color.Fill(0);
36  m_Color[0] = 1.;
37  m_Color[3] = 0.75;
38 
39  // Intialize origin and spacing
40  m_Origin.Fill(0.);
41  m_Spacing.Fill(1.);
42 
43  // Create the tesselator
44  m_GluTesselator = gluNewTess();
45 
46  // Setting up the tesselator callbacks
47  gluTessCallback(m_GluTesselator, GLU_TESS_BEGIN, (FunctionPointerType) BeginCallback);
48  gluTessCallback(m_GluTesselator, GLU_TESS_END, (FunctionPointerType) EndCallback);
49  gluTessCallback(m_GluTesselator, GLU_TESS_ERROR, (FunctionPointerType) TesselationErrorCallback);
50  gluTessCallback(m_GluTesselator, GLU_TESS_VERTEX, (FunctionPointerType) VertexCallback);
51  gluTessCallback(m_GluTesselator, GLU_TESS_COMBINE, (FunctionPointerType) TesselationCombineCallback);
52 }
53 
54 template <class TVectorData>
57 {
58  // Delete the tesselator
59  gluDeleteTess(m_GluTesselator);
60 }
61 
62 template <class TVectorData>
63 void
65 ::Render(const RegionType& extent, const AffineTransformType * space2ScreenTransform)
66 {
67  if (m_VectorData.IsNull())
68  {
69  // nothing to render, return
70  return;
71  }
72 
73  // Set up blending and color
74  glEnable(GL_BLEND);
75  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
76  glColor4d(m_Color[0], m_Color[1], m_Color[2], m_Color[3]);
77 
78  // Set up line width
79  double previousWidth = 0.;
80  glGetDoublev(GL_LINE_WIDTH, &previousWidth);
81 
82  // convert line width to screen line width
83  VectorType imageLineWidth;
84  imageLineWidth.Fill(m_LineWidth);
85  VectorType screenLineWidth = space2ScreenTransform->TransformVector(imageLineWidth);
86  glLineWidth(screenLineWidth[0]);
87  // Do we need to render boundaries only (for polygons)
88  gluTessProperty(m_GluTesselator, GLU_TESS_BOUNDARY_ONLY, m_RenderPolygonBoundariesOnly);
89 
90  // Enabling line antialiasing
91  glEnable(GL_LINE_SMOOTH);
92  // Trigger recursive rendering
93  InternalTreeNodeType * inputRoot = const_cast<InternalTreeNodeType *>(m_VectorData->GetDataTree()->GetRoot());
94 
95  itk::TimeProbe chrono;
96  chrono.Start();
97  this->Render(inputRoot, extent, space2ScreenTransform);
98  chrono.Stop();
99  otbMsgDevMacro(<< "VectorData component rendered in " << chrono.GetMeanTime() << " s.");
100 
101  glDisable(GL_LINE_SMOOTH);
102  glDisable(GL_BLEND);
103  glLineWidth(previousWidth);
104 }
105 template <class TVectorData>
106 void
108 ::RenderPoint(DataNodePointerType dataNode, const RegionType& /*extent*/, const AffineTransformType * transform)
109 {
110  // Take into account pixel spacing and origin
111  PointType spacePoint = dataNode->GetPoint();
112  spacePoint[0] -= m_Origin[0];
113  spacePoint[1] -= m_Origin[1];
114  spacePoint[0] /= m_Spacing[0];
115  spacePoint[1] /= m_Spacing[1];
116 
117  // Transform to a screen point
118  PointType screenPoint = transform->TransformPoint(spacePoint);
119 
120  glBegin(GL_LINES);
121  // Draw a cross
122  glVertex2d(screenPoint[0] - m_CrossWidth, screenPoint[1]);
123  glVertex2d(screenPoint[0] + m_CrossWidth, screenPoint[1]);
124  glVertex2d(screenPoint[0], screenPoint[1] - m_CrossWidth);
125  glVertex2d(screenPoint[0], screenPoint[1] + m_CrossWidth);
126  glEnd();
127 }
128 
129 template <class TVectorData>
130 void
132 ::RenderLine(DataNodePointerType dataNode, const RegionType& /*extent*/, const AffineTransformType * transform)
133 {
134  const LineType * l = dataNode->GetLine();
135  // Iterate on the line
136  typename LineType::VertexListType::ConstIterator vIt = l->GetVertexList()->Begin();
137 
138  glBegin(GL_LINE_STRIP);
139 
140  while (vIt != l->GetVertexList()->End())
141  {
142  // Take into account pixel spacing and origin
143  PointType spacePoint = vIt.Value();
144  spacePoint[0] -= m_Origin[0];
145  spacePoint[1] -= m_Origin[1];
146  spacePoint[0] /= m_Spacing[0];
147  spacePoint[1] /= m_Spacing[1];
148 
149  // Transform to a screen point
150  PointType screenPoint = transform->TransformPoint(spacePoint);
151 
152  // Add a point to the rendered line
153  glVertex2d(screenPoint[0], screenPoint[1]);
154  ++vIt;
155  }
156  glEnd();
157 }
158 
159 template <class TVectorData>
160 void
162 ::RenderPolygon(DataNodePointerType dataNode, const RegionType& /*extent*/, const AffineTransformType * transform)
163 {
164  const PolygonType * extRing = dataNode->GetPolygonExteriorRing();
165  const PolygonListType * intRings = dataNode->GetPolygonInteriorRings();
166  typedef std::vector<GLdouble *> VertexVectorType;
167 
168  // A buffer to hold vertex until they are rendered
169  VertexVectorType vertexBuffer;
170 
171  // Begin a new polygon
172  gluTessBeginPolygon(m_GluTesselator, NULL);
173 
174  // Render the outer boundary
175  gluTessBeginContour(m_GluTesselator);
176 
177  // Iterate on the polygon
178  typename PolygonType::VertexListType::ConstIterator vIt = extRing->GetVertexList()->Begin();
179 
180  while (vIt != extRing->GetVertexList()->End())
181  {
182  // Take into account pixel spacing and origin
183 
184  PointType spacePoint = vIt.Value();
185  spacePoint[0] -= m_Origin[0];
186  spacePoint[1] -= m_Origin[1];
187  spacePoint[0] /= m_Spacing[0];
188  spacePoint[1] /= m_Spacing[1];
189  // Transform to a screen point
190  PointType screenPoint = transform->TransformPoint(spacePoint);
191 
192  // Convert to double array
193  GLdouble * glp = new GLdouble[3];
194  glp[0] = screenPoint[0];
195  glp[1] = screenPoint[1];
196  glp[2] = 0.;
197  vertexBuffer.push_back(glp);
198 
199  // Add a point to the outer boundary
200  gluTessVertex(m_GluTesselator, glp, glp);
201  ++vIt;
202  }
203 
204  // End the outer boundary contour
205  gluTessEndContour(m_GluTesselator);
206 
207  // Render remaining inner boundaries
208  typename PolygonListType::ConstIterator pIt = intRings->Begin();
209 
210  // For each inner boundary
211  while (pIt != intRings->End())
212  {
213  vIt = pIt.Get()->GetVertexList()->Begin();
214 
215  // Begin a new contour
216  gluTessBeginContour(m_GluTesselator);
217 
218  // Render each of its vertex
219  while (vIt != pIt.Get()->GetVertexList()->End())
220  {
221  // Take into account pixel spacing and origin
222  PointType spacePoint = vIt.Value();
223  spacePoint[0] -= m_Origin[0];
224  spacePoint[1] -= m_Origin[1];
225  spacePoint[0] /= m_Spacing[0];
226  spacePoint[1] /= m_Spacing[1];
227 
228  // Transform to a screen point
229  PointType screenPoint = transform->TransformPoint(spacePoint);
230 
231  // Convert to double array
232  GLdouble * glp = new GLdouble[3];
233  glp[0] = screenPoint[0];
234  glp[1] = screenPoint[1];
235  glp[2] = 0.;
236  vertexBuffer.push_back(glp);
237 
238  // Add a point to the outer boundary
239  gluTessVertex(m_GluTesselator, glp, glp);
240  ++vIt;
241  }
242 
243  // End the contour
244  gluTessEndContour(m_GluTesselator);
245  ++pIt;
246  }
247 
248  // End the polygon
249  gluTessEndPolygon(m_GluTesselator);
250 
251  // // Do not forget to free all the vertex
252  for (typename VertexVectorType::iterator it = vertexBuffer.begin();
253  it != vertexBuffer.end(); ++it)
254  {
255  delete[] (*it);
256  }
257 }
258 
259 template <class TVectorData>
260 void
262 ::Render(InternalTreeNodeType * node, const RegionType& extent, const AffineTransformType * space2ScreenTransform)
263 {
264  // Render the current node
265  switch (node->Get()->GetNodeType())
266  {
267  case FEATURE_POINT:
268  {
269 // this->RenderPoint(node->Get()->GetPoint(), extent, space2ScreenTransform);
270  this->RenderPoint(node->Get(), extent, space2ScreenTransform);
271  break;
272 
273  }
274  case FEATURE_LINE:
275  {
276  this->RenderLine(node->Get(), extent, space2ScreenTransform);
277  break;
278  }
279  case FEATURE_POLYGON:
280  {
281  this->RenderPolygon(node->Get(), extent, space2ScreenTransform);
282  break;
283  }
284  default:
285  {
286  // discard
287  break;
288  }
289  }
290 
291  // Get the children list from the input node
292  ChildrenListType children = node->GetChildrenList();
293 
294  // Render each child
295  for (typename ChildrenListType::iterator it = children.begin(); it != children.end(); ++it)
296  {
297 
298  this->Render(*it, extent, space2ScreenTransform);
299  }
300 }
301 
302 }
303 #endif

Generated at Sun Feb 3 2013 00:54:01 for Orfeo Toolbox with doxygen 1.8.1.1