Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
MeshNodeDeprecatedT.cc
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39  * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43  * *
44  * $Revision$ *
45  * $Author$ *
46  * $Date$ *
47  * *
48 \*===========================================================================*/
49 
50 
51 
52 
53 //=============================================================================
54 //
55 // CLASS MeshNodeDeprecatedT - IMPLEMENTATION
56 //
57 //=============================================================================
58 
59 #ifndef DOXY_IGNORE_THIS
60 #define ACG_MESHNODE_C
61 
62 //== INCLUDES =================================================================
63 
64 
65 #include "MeshNodeDeprecatedT.hh"
66 #include "ShaderNode.hh"
67 #include "DrawModes.hh"
68 #include <ACG/GL/gl.hh>
69 #include <ACG/GL/GLError.hh>
70 #include <ACG/GL/ColorTranslator.hh>
71 
73 #include <OpenMesh/Core/Utils/Property.hh>
74 
75 #include <algorithm>
76 
77 //== NAMESPACES ==============================================================
78 
79 
80 namespace ACG {
81 namespace SceneGraph {
82 
83 
84 //== IMPLEMENTATION ==========================================================
85 
86 
87 template<class Mesh>
88 MeshNodeDeprecatedT<Mesh>::
89 MeshNodeDeprecatedT(const Mesh& _mesh,
90  BaseNode* _parent,
91  std::string _name)
92  : BaseNode(_parent, _name),
93  mesh_(_mesh),
94  enabled_arrays_(0),
95  face_index_buffer_(0),
96  vertex_buffer_(0),
97  normal_buffer_(0),
98  vertexBufferInitialized_(false),
99  normalBufferInitialized_(false),
100  faceIndexBufferInitialized_(false),
101  textureMap_(0),
102  propertyMap_(0),
103  default_halfedge_textcoord_property_("h:texcoords2D"),
104  indexPropertyName_("f:textureindex"),
105  updateFaceList_(true),
106  updateVertexList_(true),
107  updateEdgeList_(true),
108  updateAnyList_(true),
109  faceBaseIndex_(0),
110  vertexBaseIndex_(0),
111  edgeBaseIndex_(0),
112  anyBaseIndex_(0),
113  bbMin_(FLT_MAX, FLT_MAX, FLT_MAX),
114  bbMax_(-FLT_MAX, -FLT_MAX, -FLT_MAX)
115 {
116  faceList_ = glGenLists (1);
117  vertexList_ = glGenLists (1);
118  edgeList_ = glGenLists (1);
119  anyList_ = glGenLists (3);
120 }
121 
122 
123 //----------------------------------------------------------------------------
124 
125 
126 template<class Mesh>
127 MeshNodeDeprecatedT<Mesh>::
128 ~MeshNodeDeprecatedT()
129 {
130  if (vertex_buffer_)
131  glDeleteBuffersARB(1, (GLuint*) &vertex_buffer_);
132 
133  if (normal_buffer_)
134  glDeleteBuffersARB(1, (GLuint*) &normal_buffer_);
135 
136  if (face_index_buffer_)
137  glDeleteBuffersARB(1, (GLuint*) &face_index_buffer_ );
138 
139  if (faceList_)
140  glDeleteLists (faceList_, 1);
141 
142  if (vertexList_)
143  glDeleteLists (vertexList_, 1);
144 
145  if (edgeList_)
146  glDeleteLists (edgeList_, 1);
147 
148  if (anyList_)
149  glDeleteLists (anyList_, 3);
150 }
151 
152 
153 //----------------------------------------------------------------------------
154 
155 
156 template<class Mesh>
157 void
158 MeshNodeDeprecatedT<Mesh>::
159 boundingBox(Vec3d& _bbMin, Vec3d& _bbMax)
160 {
161  _bbMin.minimize(bbMin_);
162  _bbMax.maximize(bbMax_);
163 }
164 
165 
166 //----------------------------------------------------------------------------
167 
168 
169 template<class Mesh>
170 DrawModes::DrawMode
171 MeshNodeDeprecatedT<Mesh>::
172 availableDrawModes() const
173 {
174  DrawModes::DrawMode drawModes(DrawModes::NONE);
175 
176  drawModes |= DrawModes::POINTS;
177  drawModes |= DrawModes::WIREFRAME;
178  drawModes |= DrawModes::HIDDENLINE;
179  drawModes |= DrawModes::SOLID_SHADER;
180 
181  if (mesh_.has_vertex_normals())
182  {
183  drawModes |= DrawModes::POINTS_SHADED;
184  drawModes |= DrawModes::SOLID_SMOOTH_SHADED;
185  drawModes |= DrawModes::SOLID_PHONG_SHADED;
186  }
187 
188  if (mesh_.has_vertex_colors())
189  {
190  drawModes |= DrawModes::POINTS_COLORED;
191  drawModes |= DrawModes::SOLID_POINTS_COLORED;
192  }
193 
194  if (mesh_.has_face_normals())
195  drawModes |= DrawModes::SOLID_FLAT_SHADED;
196 
197  if (mesh_.has_face_colors())
198  {
199  drawModes |= DrawModes::SOLID_FACES_COLORED;
200 
201  if( mesh_.has_face_normals() )
202  drawModes |= DrawModes::SOLID_FACES_COLORED_FLAT_SHADED;
203  }
204 
205  if (mesh_.has_vertex_texcoords1D())
206  {
207  drawModes |= DrawModes::SOLID_1DTEXTURED;
208 
209  if (mesh_.has_vertex_normals())
210  drawModes |= DrawModes::SOLID_1DTEXTURED_SHADED;
211  }
212 
213  if (mesh_.has_vertex_texcoords2D())
214  {
215  drawModes |= DrawModes::SOLID_TEXTURED;
216 
217  if (mesh_.has_vertex_normals())
218  drawModes |= DrawModes::SOLID_TEXTURED_SHADED;
219  }
220 
221  if (mesh_.has_vertex_texcoords3D())
222  {
223  drawModes |= DrawModes::SOLID_3DTEXTURED;
224 
225  if (mesh_.has_vertex_normals())
226  drawModes |= DrawModes::SOLID_3DTEXTURED_SHADED;
227  }
228 
229  if (mesh_.has_halfedge_texcoords2D())
230  {
231  drawModes |= DrawModes::SOLID_2DTEXTURED_FACE;
232  if (mesh_.has_face_normals())
233  drawModes |= DrawModes::SOLID_2DTEXTURED_FACE_SHADED;
234  }
235 
236  return drawModes;
237 }
238 
239 
240 //----------------------------------------------------------------------------
241 
242 
243 template<class Mesh>
244 void
245 MeshNodeDeprecatedT<Mesh>::
246 enable_arrays(unsigned int _arrays)
247 {
248  // special case: VBO
249  // only use for float data, otherwise it's terribly slow!
250  typedef typename Mesh::Point Point;
251  typedef typename Point::value_type PointScalar;
252  typedef typename Mesh::Normal Normal;
253  typedef typename Normal::value_type NormalScalar;
254 
255  bool use_vbo =
256  ((_arrays == VERTEX_ARRAY || _arrays == (VERTEX_ARRAY | NORMAL_ARRAY)) &&
257  (vertexBufferInitialized_ && normalBufferInitialized_) ) ;
258 // omlog() << "Use VBO: " << use_vbo << std::endl;
259 
260 
261 
262  // unbind VBO buffers
263  if (!use_vbo && vertex_buffer_)
264  ACG::GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
265 
266 
267 
268  if (_arrays & VERTEX_ARRAY)
269  {
270  if (!(enabled_arrays_ & VERTEX_ARRAY))
271  {
272  enabled_arrays_ |= VERTEX_ARRAY;
273  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
274 
275  if (use_vbo )
276  {
277  ACG::GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buffer_);
278 
279  // As we ensure that buffers are converted to float before using them, use Float here
280  ACG::GLState::vertexPointer(3, GL_FLOAT, 0, 0);
281  }
282  else
283  {
284  ACG::GLState::vertexPointer(mesh_.points());
285  }
286  }
287  }
288  else if (enabled_arrays_ & VERTEX_ARRAY)
289  {
290  enabled_arrays_ &= ~VERTEX_ARRAY;
291  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
292  }
293 
294 
295  if (_arrays & NORMAL_ARRAY)
296  {
297  if (!(enabled_arrays_ & NORMAL_ARRAY))
298  {
299  enabled_arrays_ |= NORMAL_ARRAY;
300  ACG::GLState::enableClientState(GL_NORMAL_ARRAY);
301 
302  if (use_vbo)
303  {
304  ACG::GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, normal_buffer_);
305 
306  // As we ensure that buffers are converted to float before using them, use Float here
307  ACG::GLState::normalPointer(GL_FLOAT, 0 , 0);
308  }
309  else
310  {
311  ACG::GLState::normalPointer(mesh_.vertex_normals());
312  }
313  }
314  }
315  else if (enabled_arrays_ & NORMAL_ARRAY)
316  {
317  enabled_arrays_ &= ~NORMAL_ARRAY;
318  ACG::GLState::disableClientState(GL_NORMAL_ARRAY);
319  }
320 
321 
322  if (_arrays & COLOR_ARRAY)
323  {
324  if (!(enabled_arrays_ & COLOR_ARRAY))
325  {
326  enabled_arrays_ |= COLOR_ARRAY;
327  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
328  ACG::GLState::colorPointer(mesh_.vertex_colors());
329  }
330  }
331  else if (enabled_arrays_ & COLOR_ARRAY)
332  {
333  enabled_arrays_ &= ~COLOR_ARRAY;
334  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
335  }
336 
337 
338  if (_arrays & TEXTURE_COORD_1D_ARRAY)
339  {
340  if (!(enabled_arrays_ & TEXTURE_COORD_1D_ARRAY))
341  {
342  enabled_arrays_ |= TEXTURE_COORD_1D_ARRAY;
343  ACG::GLState::enableClientState(GL_TEXTURE_COORD_ARRAY);
344  ACG::GLState::texcoordPointer(mesh_.texcoords1D());
345  }
346  }
347  else if (enabled_arrays_ & TEXTURE_COORD_1D_ARRAY)
348  {
349  enabled_arrays_ &= ~TEXTURE_COORD_1D_ARRAY;
350  ACG::GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);
351  }
352 
353 
354  if (_arrays & TEXTURE_COORD_2D_ARRAY)
355  {
356  if (!(enabled_arrays_ & TEXTURE_COORD_2D_ARRAY))
357  {
358  enabled_arrays_ |= TEXTURE_COORD_2D_ARRAY;
359  ACG::GLState::enableClientState(GL_TEXTURE_COORD_ARRAY);
360  ACG::GLState::texcoordPointer(mesh_.texcoords2D());
361  }
362  }
363  else if (enabled_arrays_ & TEXTURE_COORD_2D_ARRAY)
364  {
365  enabled_arrays_ &= ~TEXTURE_COORD_2D_ARRAY;
366  ACG::GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);
367  }
368 
369 
370  if (_arrays & TEXTURE_COORD_3D_ARRAY)
371  {
372  if (!(enabled_arrays_ & TEXTURE_COORD_3D_ARRAY))
373  {
374  enabled_arrays_ |= TEXTURE_COORD_3D_ARRAY;
375  ACG::GLState::enableClientState(GL_TEXTURE_COORD_ARRAY);
376  ACG::GLState::texcoordPointer(mesh_.texcoords3D());
377  }
378  }
379  else if (enabled_arrays_ & TEXTURE_COORD_3D_ARRAY)
380  {
381  enabled_arrays_ &= ~TEXTURE_COORD_3D_ARRAY;
382  ACG::GLState::disableClientState(GL_TEXTURE_COORD_ARRAY);
383  }
384 
385 
386  glCheckErrors();
387 }
388 
389 
390 //----------------------------------------------------------------------------
391 
392 
393 template<class Mesh>
394 void
395 MeshNodeDeprecatedT<Mesh>::
396 update_geometry()
397 {
398  updateFaceList_ = true;
399  updateVertexList_ = true;
400  updateEdgeList_ = true;
401  updateAnyList_ = true;
402 
403  bbMin_ = Vec3d(FLT_MAX, FLT_MAX, FLT_MAX);
404  bbMax_ = Vec3d(-FLT_MAX, -FLT_MAX, -FLT_MAX);
405  typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
406  v_end(mesh_.vertices_end());
407 
408  for (; v_it!=v_end; ++v_it)
409  {
410  bbMin_.minimize(mesh_.point(*v_it));
411  bbMax_.maximize(mesh_.point(*v_it));
412  }
413 
414  if (GLEW_ARB_vertex_buffer_object) {
415  typedef typename Mesh::Point Point;
416  typedef typename Point::value_type PointScalar;
417  typedef typename Mesh::Normal Normal;
418  typedef typename Normal::value_type NormalScalar;
419 
420  //===================================================================
421  // Generate a vertex buffer on the GPU
422  //===================================================================
423 
424  if (!vertex_buffer_) glGenBuffersARB(1, (GLuint*) &vertex_buffer_);
425 
426  ACG::GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, vertex_buffer_);
427  vertexBufferInitialized_ = false;
428 
429  //Check if using floats otherwise convert to internal float array
430  if ( sizeof(PointScalar) == 4 ) {
431 
432  glBufferDataARB(GL_ARRAY_BUFFER_ARB,
433  3 * mesh_.n_vertices() * sizeof(PointScalar),
434  mesh_.points(),
435  GL_STATIC_DRAW_ARB);
436 
437  vertexBufferInitialized_ = true;
438 
439  } else {
440 
441  vertices_.clear();
442  typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
443  v_end(mesh_.vertices_end());
444 
445  for ( ; v_it != v_end ; ++v_it )
446  vertices_.push_back( ACG::Vec3f(mesh_.point(*v_it)) );
447 
448  if ( !vertices_.empty() ) {
449 
450  glBufferDataARB(GL_ARRAY_BUFFER_ARB,
451  3 * mesh_.n_vertices() * sizeof(float),
452  &vertices_[0],
453  GL_STATIC_DRAW_ARB);
454  vertexBufferInitialized_ = true;
455 
456  }
457  }
458 
459  //===================================================================
460  // Generate a normal buffer on the GPU
461  //===================================================================
462 
463  if (!normal_buffer_) glGenBuffersARB(1, (GLuint*) &normal_buffer_);
464  ACG::GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, normal_buffer_);
465  normalBufferInitialized_ = false;
466 
467  // Check if using floats otherwise convert to internal float array
468  if ( sizeof(NormalScalar) == 4) {
469 
470  glBufferDataARB(GL_ARRAY_BUFFER_ARB,
471  3 * mesh_.n_vertices() * sizeof(NormalScalar),
472  mesh_.vertex_normals(),
473  GL_STATIC_DRAW_ARB);
474 
475  normalBufferInitialized_ = true;
476 
477  } else {
478  normals_.clear();
479  typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
480  v_end(mesh_.vertices_end());
481 
482  for ( ; v_it != v_end ; ++v_it )
483  normals_.push_back( ACG::Vec3f(mesh_.normal(*v_it)) );
484 
485  if ( !normals_.empty() ) {
486 
487  glBufferDataARB(GL_ARRAY_BUFFER_ARB,
488  3 * mesh_.n_vertices() * sizeof(float),
489  &normals_[0],
490  GL_STATIC_DRAW_ARB);
491  normalBufferInitialized_ = true;
492  }
493 
494  }
495 
496  // unbind buffers
497  ACG::GLState::bindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
498 
499  } else omlog() << "MeshNodeDeprecatedT: VBO not supported on this machine\n";
500 }
501 
502 
503 //----------------------------------------------------------------------------
504 
505 
506 template<class Mesh>
507 void
508 MeshNodeDeprecatedT<Mesh>::
509 update_topology()
510 {
511  updateFaceList_ = true;
512  updateVertexList_ = true;
513 
514  if (mesh_.is_trimesh())
515  {
516  typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()),
517  f_end(mesh_.faces_end());
518  typename Mesh::ConstFaceVertexIter fv_it;
519 
520  try
521  {
522  indices_.clear();
523  std::vector<unsigned int>().swap(indices_);
524  indices_.reserve(mesh_.n_faces()*3);
525 
526  for (; f_it!=f_end; ++f_it)
527  {
528  fv_it = mesh_.cfv_iter( *f_it );
529  indices_.push_back(fv_it->idx()); ++fv_it;
530  indices_.push_back(fv_it->idx()); ++fv_it;
531  indices_.push_back(fv_it->idx());
532  }
533  }
534  catch (...)
535  {
536  indices_.clear();
537  std::vector<unsigned int>().swap(indices_);
538  omerr() << "Topology caching failed\n";
539  }
540 
541  //===================================================================
542  // Generate an index buffer on the GPU
543  //===================================================================
544  faceIndexBufferInitialized_ = false;
545 
546  if ( GLEW_ARB_vertex_buffer_object && !indices_.empty() ) {
547 
548  // generate buffer
549  if (!face_index_buffer_) glGenBuffersARB(1, (GLuint*) &face_index_buffer_);
550 
551  // index buffer
552  ACG::GLState::bindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, face_index_buffer_);
553 
554  glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
555  indices_.size() * sizeof(unsigned int),
556  &indices_[0],
557  GL_STATIC_DRAW_ARB);
558 
559  faceIndexBufferInitialized_ = true;
560 
561  // unbind buffer
562  ACG::GLState::bindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
563 
564  }
565 
566  }
567 
568 }
569 
570 
571 //----------------------------------------------------------------------------
572 
573 
574 template<class Mesh>
575 void
576 MeshNodeDeprecatedT<Mesh>::
577 draw(GLState& _state, const DrawModes::DrawMode& _drawMode)
578 {
579  GLenum prev_depth = _state.depthFunc();
580 
581  if (_drawMode & DrawModes::POINTS)
582  {
583  enable_arrays(VERTEX_ARRAY);
584  ACG::GLState::disable(GL_LIGHTING);
585  ACG::GLState::shadeModel(GL_FLAT);
586  draw_vertices();
587  }
588 
589 
590  if ( ( _drawMode & DrawModes::POINTS_COLORED ) && mesh_.has_vertex_colors())
591  {
592  enable_arrays(VERTEX_ARRAY | COLOR_ARRAY);
593  ACG::GLState::disable(GL_LIGHTING);
594  ACG::GLState::shadeModel(GL_FLAT);
595  draw_vertices();
596  }
597 
598 
599  if ( ( _drawMode & DrawModes::POINTS_SHADED ) && mesh_.has_vertex_normals())
600  {
601  enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY);
602  ACG::GLState::enable(GL_LIGHTING);
603  ACG::GLState::shadeModel(GL_FLAT);
604  draw_vertices();
605  }
606 
607 
608  if (_drawMode & DrawModes::WIREFRAME)
609  {
610  glPushAttrib(GL_ENABLE_BIT);
611 
612  ACG::GLState::disable( GL_CULL_FACE );
613 
614  enable_arrays(VERTEX_ARRAY);
615  ACG::GLState::disable(GL_LIGHTING);
616  ACG::GLState::shadeModel(GL_FLAT);
617  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
618  draw_faces(PER_VERTEX);
619  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
620 
621  glPopAttrib();
622  }
623 
624 
625  if (_drawMode & DrawModes::HIDDENLINE)
626  {
627  enable_arrays(VERTEX_ARRAY);
628 
629  Vec4f clear_color = _state.clear_color();
630  Vec4f base_color = _state.base_color();
631  clear_color[3] = 1.0;
632 
633  ACG::GLState::disable(GL_LIGHTING);
634  ACG::GLState::shadeModel(GL_FLAT);
635  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
636  _state.set_base_color(clear_color);
637 
638  ACG::GLState::depthRange(0.01, 1.0);
639  draw_faces(PER_VERTEX);
640  ACG::GLState::depthRange(0.0, 1.0);
641 
642  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
643  ACG::GLState::depthFunc(GL_LEQUAL);
644  _state.set_base_color(base_color);
645  draw_faces(PER_VERTEX);
646  ACG::GLState::depthFunc(prev_depth);
647  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
648  }
649 
650 
651  if ( ( _drawMode & DrawModes::SOLID_FLAT_SHADED ) && mesh_.has_face_normals())
652  {
653  ACG::GLState::enable(GL_LIGHTING);
654  ACG::GLState::shadeModel(GL_FLAT);
655  ACG::GLState::depthRange(0.01, 1.0);
656  draw_faces(FACE_NORMALS);
657  ACG::GLState::depthRange(0.0, 1.0);
658  }
659 
660 
661  if ( ( _drawMode & DrawModes::SOLID_SMOOTH_SHADED ) && mesh_.has_vertex_normals())
662  {
663  enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY);
664  ACG::GLState::enable(GL_LIGHTING);
665  ACG::GLState::shadeModel(GL_SMOOTH);
666  ACG::GLState::depthRange(0.01, 1.0);
667  draw_faces(PER_VERTEX);
668  ACG::GLState::depthRange(0.0, 1.0);
669  }
670 
671  if ( ( _drawMode & DrawModes::SOLID_PHONG_SHADED ) && mesh_.has_vertex_normals() )
672  {
673 // if ( parent() != 0 ) {
674 // if ( parent()->className() == "ShaderNode" ) {
675 //
676 // ShaderNode* node = dynamic_cast< ShaderNode* > ( parent() );
677 //
678 // GLSL::PtrProgram program = node->getShader( DrawModes::SOLID_PHONG_SHADED );
679 //
680 // // Enable own Phong shader
681 // program->use();
682 
683  enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY);
684  ACG::GLState::enable(GL_LIGHTING);
685  ACG::GLState::shadeModel(GL_SMOOTH);
686  ACG::GLState::depthRange(0.01, 1.0);
687  draw_faces(PER_VERTEX);
688  ACG::GLState::depthRange(0.0, 1.0);
689 
690  //disable own Phong shader
691 // program->disable();
692 // }
693 // }
694  }
695 
696  if ( ( _drawMode & DrawModes::SOLID_ENV_MAPPED ) && mesh_.has_vertex_normals())
697  {
698  enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY);
699  ACG::GLState::enable(GL_LIGHTING);
700  ACG::GLState::shadeModel(GL_SMOOTH);
701  ACG::GLState::depthRange(0.01, 1.0);
702  draw_faces(PER_VERTEX);
703  ACG::GLState::depthRange(0.0, 1.0);
704  }
705 
706 
707  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED )&& mesh_.has_face_colors())
708  {
709  Vec4f base_color_backup = _state.base_color();
710 
711  ACG::GLState::disable(GL_LIGHTING);
712  ACG::GLState::shadeModel(GL_FLAT);
713  ACG::GLState::depthRange(0.01, 1.0);
714  draw_faces(FACE_COLORS);
715  ACG::GLState::depthRange(0.0, 1.0);
716 
717  _state.set_base_color(base_color_backup);
718  }
719 
720 
721  if ( ( _drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED ) && mesh_.has_face_colors() && mesh_.has_face_normals())
722  {
723  Vec4f base_color_backup = _state.base_color();
724  ACG::GLState::enable(GL_LIGHTING);
725 
726  ACG::GLState::shadeModel(GL_FLAT);
727  ACG::GLState::depthRange(0.01, 1.0);
728  draw_faces(FACE_NORMALS_COLORS);
729  ACG::GLState::depthRange(0.0, 1.0);
730 
731  _state.set_base_color(base_color_backup);
732  }
733 
734 
735  if ( ( _drawMode & DrawModes::SOLID_POINTS_COLORED ) && mesh_.has_vertex_colors())
736  {
737  Vec4f base_color_backup = _state.base_color();
738 
739  enable_arrays(VERTEX_ARRAY | COLOR_ARRAY);
740  ACG::GLState::disable(GL_LIGHTING);
741  ACG::GLState::shadeModel(GL_SMOOTH);
742  ACG::GLState::depthRange(0.01, 1.0);
743  draw_faces(PER_VERTEX);
744  ACG::GLState::depthRange(0.0, 1.0);
745 
746  _state.set_base_color(base_color_backup);
747  }
748 
749 
750  if ( ( _drawMode & DrawModes::SOLID_TEXTURED ) && mesh_.has_vertex_texcoords2D())
751  {
752  enable_arrays(VERTEX_ARRAY | TEXTURE_COORD_2D_ARRAY);
753  ACG::GLState::enable(GL_TEXTURE_2D);
754  ACG::GLState::disable(GL_LIGHTING);
755  ACG::GLState::shadeModel(GL_FLAT);
756  ACG::GLState::depthRange(0.01, 1.0);
757  draw_faces(PER_VERTEX);
758  ACG::GLState::depthRange(0.0, 1.0);
759  ACG::GLState::disable(GL_TEXTURE_2D);
760  }
761 
762 
763  if ( ( _drawMode & DrawModes::SOLID_TEXTURED_SHADED ) && mesh_.has_vertex_texcoords2D() && mesh_.has_vertex_normals())
764  {
765  enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY | TEXTURE_COORD_2D_ARRAY);
766  ACG::GLState::enable(GL_TEXTURE_2D);
767  ACG::GLState::enable(GL_LIGHTING);
768  ACG::GLState::shadeModel(GL_SMOOTH);
769  ACG::GLState::depthRange(0.01, 1.0);
770  draw_faces(PER_VERTEX);
771  ACG::GLState::depthRange(0.0, 1.0);
772  ACG::GLState::disable(GL_TEXTURE_2D);
773  }
774 
775 
776  if ( ( _drawMode & DrawModes::SOLID_1DTEXTURED ) && mesh_.has_vertex_texcoords1D())
777  {
778  enable_arrays(VERTEX_ARRAY | TEXTURE_COORD_1D_ARRAY);
779  ACG::GLState::enable(GL_TEXTURE_1D);
780  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
781  ACG::GLState::disable(GL_LIGHTING);
782  ACG::GLState::shadeModel(GL_SMOOTH);
783  ACG::GLState::depthRange(0.01, 1.0);
784  draw_faces(PER_VERTEX);
785  ACG::GLState::depthRange(0.0, 1.0);
786  ACG::GLState::disable(GL_TEXTURE_1D);
787  }
788 
789 
790  if ( ( _drawMode & DrawModes::SOLID_1DTEXTURED_SHADED ) && mesh_.has_vertex_texcoords1D() && mesh_.has_vertex_normals())
791  {
792  // store and change colors
793  const Vec4f ambient = _state.ambient_color();
794  const Vec4f diffuse = _state.diffuse_color();
795  const Vec4f specular = _state.specular_color();
796  _state.set_ambient_color (Vec4f(0.1, 0.1, 0.1, 1.0));
797  _state.set_diffuse_color (Vec4f(0.8, 0.8, 0.8, 1.0));
798  _state.set_specular_color (Vec4f(1.0, 1.0, 1.0, 1.0));
799 
800  // store and change texture mode
801  GLint texmode;
802  glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &texmode);
803  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
804 
805  enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY | TEXTURE_COORD_1D_ARRAY);
806  ACG::GLState::enable(GL_TEXTURE_1D);
807  ACG::GLState::enable(GL_LIGHTING);
808  ACG::GLState::shadeModel(GL_SMOOTH);
809  ACG::GLState::depthRange(0.01, 1.0);
810  draw_faces(PER_VERTEX);
811  ACG::GLState::depthRange(0.0, 1.0);
812  ACG::GLState::disable(GL_TEXTURE_1D);
813 
814  // restore colors
815  _state.set_ambient_color(ambient);
816  _state.set_diffuse_color(diffuse);
817  _state.set_specular_color(specular);
818 
819  // restore texture mode
820  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, texmode);
821  }
822 
823 
824 
825  if ( ( _drawMode & DrawModes::SOLID_3DTEXTURED ) && mesh_.has_vertex_texcoords3D())
826  {
827  enable_arrays(VERTEX_ARRAY | TEXTURE_COORD_3D_ARRAY);
828  ACG::GLState::enable(GL_TEXTURE_3D);
829  ACG::GLState::disable(GL_LIGHTING);
830  ACG::GLState::shadeModel(GL_FLAT);
831  ACG::GLState::depthRange(0.01, 1.0);
832  draw_faces(PER_VERTEX);
833  ACG::GLState::depthRange(0.0, 1.0);
834  ACG::GLState::disable(GL_TEXTURE_3D);
835  }
836 
837 
838  if ( ( _drawMode & DrawModes::SOLID_3DTEXTURED_SHADED ) && mesh_.has_vertex_texcoords3D() && mesh_.has_vertex_normals())
839  {
840  enable_arrays(VERTEX_ARRAY | NORMAL_ARRAY | TEXTURE_COORD_3D_ARRAY);
841  ACG::GLState::enable(GL_TEXTURE_3D);
842  ACG::GLState::enable(GL_LIGHTING);
843  ACG::GLState::shadeModel(GL_SMOOTH);
844  ACG::GLState::depthRange(0.01, 1.0);
845  draw_faces(PER_VERTEX);
846  ACG::GLState::depthRange(0.0, 1.0);
847  ACG::GLState::disable(GL_TEXTURE_3D);
848  }
849 
850  // Textured by using coordinates stored in halfedges
851  // TODO: Check not only mesh_.has_halfedge_texcoords2D but check if custom property is available
852  if ( ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE ) && mesh_.has_halfedge_texcoords2D())
853  {
854  ACG::GLState::enable(GL_TEXTURE_2D);
855  ACG::GLState::disable(GL_LIGHTING);
856  ACG::GLState::shadeModel(GL_FLAT);
857  ACG::GLState::depthRange(0.01, 1.0);
858  draw_faces(FACE_HALFEDGE_TEXTURED);
859  ACG::GLState::depthRange(0.0, 1.0);
860  ACG::GLState::disable(GL_TEXTURE_2D);
861  }
862 
863  // Textured by using coordinates stored in halfedges
864  // TODO: Check not only mesh_.has_halfedge_texcoords2D but check if custom property is available
865  if ( ( _drawMode & DrawModes::SOLID_2DTEXTURED_FACE_SHADED ) && mesh_.has_halfedge_texcoords2D() && mesh_.has_face_normals())
866  {
867  ACG::GLState::enable(GL_TEXTURE_2D);
868  ACG::GLState::enable(GL_LIGHTING);
869 
870  ACG::GLState::shadeModel(GL_FLAT);
871  ACG::GLState::depthRange(0.01, 1.0);
872  draw_faces(FACE_HALFEDGE_TEXTURED);
873  ACG::GLState::depthRange(0.0, 1.0);
874  ACG::GLState::disable(GL_TEXTURE_2D);
875 
876  }
877 
878  // If in shader mode, just draw, as the shader has to be set by a shadernode above this node
879  if ( (_drawMode & DrawModes::SOLID_SHADER ) ) {
880 
881  if ( mesh_.has_face_normals() )
882  enable_arrays( VERTEX_ARRAY | NORMAL_ARRAY);
883  else
884  enable_arrays( VERTEX_ARRAY );
885 
886  ACG::GLState::enable(GL_LIGHTING);
887  ACG::GLState::shadeModel(GL_SMOOTH);
888  ACG::GLState::depthRange(0.01, 1.0);
889  draw_faces(PER_VERTEX);
890  ACG::GLState::depthRange(0.0, 1.0);
891  }
892 
893 
894  enable_arrays(0);
895 }
896 
897 
898 //----------------------------------------------------------------------------
899 
900 
901 template<class Mesh>
902 void
903 MeshNodeDeprecatedT<Mesh>::
904 draw_vertices()
905 {
906  glDrawArrays(GL_POINTS, 0, mesh_.n_vertices());
907 }
908 
909 
910 //----------------------------------------------------------------------------
911 
912 
913 template<class Mesh>
914 void
915 MeshNodeDeprecatedT<Mesh>::
916 draw_faces(FaceMode _mode)
917 {
918  typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()),
919  f_end(mesh_.faces_end());
920  typename Mesh::ConstFaceVertexIter fv_it;
921  typename Mesh::ConstFaceHalfedgeIter fh_it;
922 
923  switch (_mode)
924  {
925  case FACE_NORMALS:
926  {
927  if (mesh_.is_trimesh())
928  {
929  glBegin(GL_TRIANGLES);
930  for (; f_it!=f_end; ++f_it)
931  {
932  glNormal(mesh_.normal(*f_it));
933 
934  fv_it=mesh_.cfv_iter(*f_it);
935  glVertex(mesh_.point(*fv_it)); ++fv_it;
936  glVertex(mesh_.point(*fv_it)); ++fv_it;
937  glVertex(mesh_.point(*fv_it));
938  }
939  glEnd();
940  }
941  else
942  {
943  for (; f_it!=f_end; ++f_it)
944  {
945  glBegin(GL_POLYGON);
946  glNormal(mesh_.normal(*f_it));
947  for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
948  glVertex(mesh_.point(*fv_it));
949  glEnd();
950  }
951  }
952  break;
953  }
954 
955 
956  case FACE_COLORS:
957  {
958  if (mesh_.is_trimesh())
959  {
960  glBegin(GL_TRIANGLES);
961  for (; f_it!=f_end; ++f_it)
962  {
963  glColor(mesh_.color(*f_it));
964 
965  fv_it=mesh_.cfv_iter(*f_it);
966  glVertex(mesh_.point(*fv_it)); ++fv_it;
967  glVertex(mesh_.point(*fv_it)); ++fv_it;
968  glVertex(mesh_.point(*fv_it));
969  }
970  glEnd();
971  }
972  else
973  {
974  for (; f_it!=f_end; ++f_it)
975  {
976  glBegin(GL_POLYGON);
977  glColor(mesh_.color(*f_it));
978  for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
979  glVertex(mesh_.point(*fv_it));
980  glEnd();
981  }
982  }
983  break;
984  }
985 
986 
987  case FACE_NORMALS_COLORS:
988  {
989  if (mesh_.is_trimesh())
990  {
991  glBegin(GL_TRIANGLES);
992  for (; f_it!=f_end; ++f_it)
993  {
994  glColor(mesh_.color(*f_it));
995  glNormal(mesh_.normal(*f_it));
996 
997  fv_it=mesh_.cfv_iter(*f_it);
998  glVertex(mesh_.point(*fv_it)); ++fv_it;
999  glVertex(mesh_.point(*fv_it)); ++fv_it;
1000  glVertex(mesh_.point(*fv_it));
1001  }
1002  glEnd();
1003  }
1004  else
1005  {
1006  for (; f_it!=f_end; ++f_it)
1007  {
1008  glBegin(GL_POLYGON);
1009  glColor(mesh_.color(*f_it));
1010  glNormal(mesh_.normal(*f_it));
1011  for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
1012  glVertex(mesh_.point(*fv_it));
1013  glEnd();
1014  }
1015  }
1016  break;
1017  }
1018 
1019 
1020  // propertyMap_ maps between an int index stored in the Mesh describing which texture to use
1021  // and a property name giving 2D Texture coordinates for halfedges ( texcoords for to vertex )
1022 
1023  case FACE_HALFEDGE_TEXTURED:
1024  {
1025  if (mesh_.is_trimesh())
1026  {
1027 
1028  OpenMesh::FPropHandleT< int > texture_index_property;
1029  if ( !mesh_.get_property_handle(texture_index_property,indexPropertyName_) ) {
1030  if( indexPropertyName_ != "No Texture Index")
1031  std::cerr << "Unable to get per face texture Index property named " << indexPropertyName_ << std::endl;
1032  if ( !mesh_.get_property_handle(texture_index_property,"f:textureindex") ) {
1033  std::cerr << "Unable to get standard per face texture Index property" << std::endl;
1034  texture_index_property.reset();
1035  }
1036  }
1037 
1038  // textureMap_ maps between an int index stored in the Mesh describing which texture to use
1039  // and the GluInt bound by the TextureNode. If such a map is not available, assume TextureNode
1040  // has already bound a texture and we use only one texture.
1041  // Additionally if we do not have an texture index property, we do not know which textures
1042  // should be used .. therefore do not switch textures if this property is missing.
1043  if ( !textureMap_ || !texture_index_property.is_valid() ) {
1044 
1045  // Get texture coords property
1047  if ( !mesh_.get_property_handle(texture_coord_property,default_halfedge_textcoord_property_) ) {
1048  std::cerr << "Error: Unable to get per face texture coordinate property named "
1049  << default_halfedge_textcoord_property_ << std::endl;
1050  std::cerr << "Unable to texture without texture coordinates" << std::endl;
1051  return;
1052  }
1053 
1054  typename Mesh::Point point;
1055  typename Mesh::TexCoord2D tex2d;
1056  glBegin(GL_TRIANGLES);
1057  for (; f_it!=f_end; ++f_it) {
1058  glNormal(mesh_.normal(*f_it));
1059  for (fh_it = mesh_.cfh_iter(*f_it);fh_it.is_valid();++fh_it)
1060  {
1061  point = mesh_.point(mesh_.to_vertex_handle(*fh_it));
1062  tex2d = mesh_.property(texture_coord_property,*fh_it);
1063  glTexCoord2f(tex2d[0], tex2d[1]);
1064  glVertex(point);
1065  }
1066  }
1067  glEnd();
1068  } else {
1069 
1071  int last_texture = -1;
1072 
1073  typename Mesh::Point point;
1074  typename Mesh::TexCoord2D tex2d;
1075 
1076  for (; f_it!=f_end; ++f_it)
1077  {
1078  int texture = mesh_.property(texture_index_property,*f_it);
1079 
1080  if (texture == -1)
1081  continue;
1082 
1083  if ( last_texture != texture ) {
1084 
1085  if ( textureMap_->find(texture) == textureMap_->end() ) {
1086  std::cerr << "Illegal texture index ... trying to access " << texture << std::endl;
1087  last_texture = -1;
1088  continue;
1089  }
1090 
1091  // Get texture coords property
1092  if ( !propertyMap_ || !mesh_.get_property_handle(texture_coord_property,(*propertyMap_)[texture]) ) {
1093  if ( propertyMap_)
1094  std::cerr << "Error: Unable to get per face texture coordinate property named "
1095  << (*propertyMap_)[texture] << std::endl;
1096  if ( !mesh_.get_property_handle(texture_coord_property,"h:texcoords2D") ) {
1097  std::cerr << "Fallback: Unable to get standard Property for per halfedge texcoords" << std::endl;
1098  std::cerr << "Unable to texture face without texture coordinates" << std::endl;
1099  last_texture = -1;
1100  continue;
1101  }
1102  }
1103 
1104  ACG::GLState::bindTexture( GL_TEXTURE_2D, (*textureMap_)[texture] );
1105 
1106  // Remember active texture to skip extra switches
1107  last_texture = texture;
1108 
1109  }
1110 
1111  glBegin(GL_TRIANGLES);
1112 
1113  glNormal(mesh_.normal(*f_it));
1114  glColor(mesh_.color(*f_it));
1115 
1116  for (fh_it = mesh_.cfh_iter(*f_it);fh_it.is_valid();++fh_it)
1117  {
1118  point = mesh_.point(mesh_.to_vertex_handle(*fh_it));
1119  tex2d = mesh_.property(texture_coord_property,*fh_it);
1120  glTexCoord2f(tex2d[0], tex2d[1]);
1121  glVertex(point);
1122  }
1123 
1124  glEnd();
1125 
1126  }
1127  }
1128  }
1129  else
1130  {
1131  // NOT IMPLEMENTED
1132  }
1133  break;
1134  }
1135 
1136 
1137  case PER_VERTEX:
1138  {
1139  if (mesh_.is_trimesh())
1140  {
1141  // try cached triangle indices
1142  if (!indices_.empty())
1143  {
1144 
1145  // If we have an index buffer on the GPU, use it
1146  if ( faceIndexBufferInitialized_ ) {
1147 
1148  // As we have a list of all faces on the GPU bind it
1149  ACG::GLState::bindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,face_index_buffer_);
1150 
1151  // Draw it
1152  glDrawElements(GL_TRIANGLES,
1153  indices_.size(),
1154  GL_UNSIGNED_INT,
1155  0);
1156 
1157  // And unbind it again
1158  ACG::GLState::bindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB,0);
1159 
1160  } else {
1161 
1162  glDrawElements(GL_TRIANGLES,
1163  indices_.size(),
1164  GL_UNSIGNED_INT,
1165  &indices_[0]);
1166  }
1167 
1168 
1169  }
1170 
1171  // otherwise use immediate mode
1172  else
1173  {
1174  glBegin(GL_TRIANGLES);
1175  for (; f_it!=f_end; ++f_it)
1176  {
1177 
1178  fv_it=mesh_.cfv_iter(*f_it);
1179  glArrayElement(fv_it->idx()); ++fv_it;
1180  glArrayElement(fv_it->idx()); ++fv_it;
1181  glArrayElement(fv_it->idx());
1182  }
1183  glEnd();
1184  }
1185  }
1186  else
1187  {
1188  for (; f_it!=f_end; ++f_it)
1189  {
1190  glBegin(GL_POLYGON);
1191  for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
1192  glArrayElement(fv_it->idx());
1193  glEnd();
1194  }
1195  }
1196  break;
1197  }
1198  }
1199 }
1200 
1201 
1202 //----------------------------------------------------------------------------
1203 
1204 
1205 template<class Mesh>
1206 void
1207 MeshNodeDeprecatedT<Mesh>::
1208 pick(GLState& _state, PickTarget _target)
1209 {
1210  switch (_target)
1211  {
1212  case PICK_VERTEX:
1213  {
1214  pick_vertices(_state);
1215  break;
1216  }
1217  case PICK_FRONT_VERTEX:
1218  {
1219  pick_vertices(_state, true);
1220  break;
1221  }
1222 
1223  case PICK_ANYTHING:
1224  {
1225  pick_any(_state);
1226  break;
1227  }
1228  case PICK_FACE:
1229  {
1230  pick_faces(_state);
1231  break;
1232  }
1233 
1234  case PICK_EDGE:
1235  {
1236  pick_edges(_state);
1237  break;
1238  }
1239 
1240  case PICK_FRONT_EDGE:
1241  {
1242  pick_edges(_state, true);
1243  break;
1244  }
1245 
1246  default:
1247  break;
1248  }
1249 }
1250 
1251 
1252 //----------------------------------------------------------------------------
1253 
1254 
1255 template<class Mesh>
1256 void
1257 MeshNodeDeprecatedT<Mesh>::
1258 pick_vertices(GLState& _state, bool _front)
1259 {
1260  GLenum prev_depth = _state.depthFunc();
1261 
1262  typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
1263  v_end(mesh_.vertices_end());
1264  GLuint idx(0);
1265 
1266  if (!_state.pick_set_maximum (mesh_.n_vertices()))
1267  {
1268  omerr() << "MeshNode::pick_vertices: color range too small, "
1269  << "picking failed\n";
1270  return;
1271  }
1272 
1273  if (_front)
1274  {
1275  enable_arrays(VERTEX_ARRAY);
1276 
1277  Vec4f clear_color = _state.clear_color();
1278  Vec4f base_color = _state.base_color();
1279  clear_color[3] = 1.0;
1280 
1281  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1282  _state.set_base_color(clear_color);
1283 
1284  ACG::GLState::depthRange(0.01, 1.0);
1285  draw_faces(PER_VERTEX);
1286  ACG::GLState::depthRange(0.0, 1.0);
1287 
1288  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1289  ACG::GLState::depthFunc(GL_LEQUAL);
1290  _state.set_base_color(base_color);
1291 
1292  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1293 
1294  enable_arrays(0);
1295  }
1296 
1297 
1298  if (vertexList_ && !updateVertexList_ && _state.pick_current_index () == vertexBaseIndex_)
1299  {
1300  glCallList (vertexList_);
1301  ACG::GLState::depthFunc(prev_depth);
1302  return;
1303  }
1304 
1305  if (vertexList_)
1306  {
1307  glNewList (vertexList_, GL_COMPILE);
1308  updateVertexList_ = false;
1309  vertexBaseIndex_ = _state.pick_current_index ();
1310  }
1311 
1312  if (_state.color_picking ())
1313  {
1314  update_pick_buffers ();
1315 
1316  for (; v_it!=v_end; ++v_it, ++idx)
1317  {
1318  pickColorBuf_[idx] = _state.pick_get_name_color (idx);
1319  pickVertexBuf_[idx] = mesh_.point(*v_it);
1320  }
1321 
1322  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1323  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1324 
1325  ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1326  ACG::GLState::colorPointer(&pickColorBuf_[0]);
1327 
1328  glDrawArrays(GL_POINTS, 0, mesh_.n_vertices());
1329 
1330  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1331  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1332  }
1333  else
1334  {
1335  for (; v_it!=v_end; ++v_it, ++idx)
1336  {
1337  _state.pick_set_name (idx);
1338  glBegin(GL_POINTS);
1339  glVertex(mesh_.point(*v_it));
1340  glEnd();
1341  }
1342  }
1343 
1344  if (vertexList_)
1345  {
1346  glEndList ();
1347  glCallList (vertexList_);
1348  }
1349 
1350  ACG::GLState::depthFunc(prev_depth);
1351 }
1352 
1353 
1354 //----------------------------------------------------------------------------
1355 
1356 
1357 template<class Mesh>
1358 void
1359 MeshNodeDeprecatedT<Mesh>::
1360 pick_faces(GLState& _state)
1361 {
1362  typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()),
1363  f_end(mesh_.faces_end());
1364  typename Mesh::ConstFaceVertexIter fv_it;
1365 
1366 
1367  if ( mesh_.n_faces() > 0 )
1368  {
1369  if (!_state.pick_set_maximum (mesh_.n_faces()))
1370  {
1371  omerr() << "MeshNode::pick_faces: color range too small, "
1372  << "picking failed\n";
1373  return;
1374  }
1375  }
1376  else
1377  {
1378  if (!_state.pick_set_maximum (1))
1379  {
1380  omerr() << "Strange pickSetMAximum failed for index 1 in MeshNode\n";
1381  return;
1382  }
1383  }
1384 
1385  if (faceList_ && !updateFaceList_ && _state.pick_current_index () == faceBaseIndex_)
1386  {
1387  glCallList (faceList_);
1388  return;
1389  }
1390 
1391  if (faceList_)
1392  {
1393  glNewList (faceList_, GL_COMPILE);
1394  updateFaceList_ = false;
1395  faceBaseIndex_ = _state.pick_current_index ();
1396  }
1397 
1398  if (_state.color_picking ())
1399  {
1400  update_pick_buffers ();
1401  unsigned int idx = 0;
1402 
1403  if (mesh_.is_trimesh())
1404  {
1405  for (; f_it!=f_end; ++f_it)
1406  {
1407  pickColorBuf_[idx] = _state.pick_get_name_color (f_it->idx());
1408  pickColorBuf_[idx+1] = _state.pick_get_name_color (f_it->idx());
1409  pickColorBuf_[idx+2] = _state.pick_get_name_color (f_it->idx());
1410 
1411  fv_it=mesh_.cfv_iter(*f_it);
1412  pickVertexBuf_[idx] = mesh_.point(*fv_it); ++fv_it;
1413  pickVertexBuf_[idx+1] = mesh_.point(*fv_it); ++fv_it;
1414  pickVertexBuf_[idx+2] = mesh_.point(*fv_it);
1415  idx += 3;
1416  }
1417 
1418  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1419  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1420 
1421  ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1422  ACG::GLState::colorPointer(&pickColorBuf_[0]);
1423 
1424  glDrawArrays(GL_TRIANGLES, 0, mesh_.n_faces() * 3);
1425 
1426  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1427  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1428 
1429  }
1430  else
1431  {
1432  unsigned int face = 0;
1433  std::vector <GLint> first;
1434  std::vector <GLsizei> count;
1435 
1436  first.resize (mesh_.n_faces());
1437  count.resize (mesh_.n_faces());
1438 
1439  for (; f_it!=f_end; ++f_it, ++face)
1440  {
1441  unsigned int cnt = 0;
1442  first[face] = idx;
1443 
1444 
1445  for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it, ++idx, ++cnt)
1446  {
1447  pickVertexBuf_[idx] = mesh_.point(*fv_it);
1448  pickColorBuf_[idx] = _state.pick_get_name_color (f_it->idx());
1449  }
1450  count[face] = cnt;
1451  }
1452  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1453  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1454 
1455  ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1456  ACG::GLState::colorPointer(&pickColorBuf_[0]);
1457 
1458  glMultiDrawArrays(GL_POLYGON, &first[0], &count[0], mesh_.n_faces());
1459 
1460  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1461  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1462  }
1463  }
1464  else
1465  {
1466 
1467  if (mesh_.is_trimesh())
1468  {
1469  for (; f_it!=f_end; ++f_it)
1470  {
1471  // set index
1472  _state.pick_set_name (f_it->idx());
1473 
1474  glBegin(GL_TRIANGLES);
1475 
1476  fv_it=mesh_.cfv_iter(*f_it);
1477  glVertex(mesh_.point(*fv_it)); ++fv_it;
1478  glVertex(mesh_.point(*fv_it)); ++fv_it;
1479  glVertex(mesh_.point(*fv_it));
1480  glEnd();
1481  }
1482  }
1483  else
1484  {
1485  for (; f_it!=f_end; ++f_it)
1486  {
1487  // set index
1488  _state.pick_set_name (f_it->idx());
1489 
1490  glBegin(GL_POLYGON);
1491 
1492  for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
1493  glVertex(mesh_.point(*fv_it));
1494 
1495  glEnd();
1496  }
1497  }
1498  }
1499 
1500  if (faceList_)
1501  {
1502  glEndList ();
1503  glCallList (faceList_);
1504  }
1505 }
1506 
1507 //----------------------------------------------------------------------------
1508 
1509 
1510 template<class Mesh>
1511 void
1512 MeshNodeDeprecatedT<Mesh>::
1513 pick_edges(GLState& _state, bool _front)
1514 {
1515  typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()),
1516  e_end(mesh_.edges_end());
1517 
1518  GLenum prev_depth = _state.depthFunc();
1519 
1520  if (!_state.pick_set_maximum (mesh_.n_edges()))
1521  {
1522  omerr() << "MeshNode::pick_edges: color range too small, "
1523  << "picking failed\n";
1524  return;
1525  }
1526 
1527  if (_front)
1528  {
1529  enable_arrays(VERTEX_ARRAY);
1530 
1531  Vec4f clear_color = _state.clear_color();
1532  Vec4f base_color = _state.base_color();
1533  clear_color[3] = 1.0;
1534 
1535  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1536  _state.set_base_color(clear_color);
1537 
1538  ACG::GLState::depthRange(0.01, 1.0);
1539  draw_faces(PER_VERTEX);
1540  ACG::GLState::depthRange(0.0, 1.0);
1541 
1542  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
1543  ACG::GLState::depthFunc(GL_LEQUAL);
1544  _state.set_base_color(base_color);
1545 
1546  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
1547 
1548  enable_arrays(0);
1549  }
1550 
1551  if (edgeList_ && !updateEdgeList_ && _state.pick_current_index () == edgeBaseIndex_)
1552  {
1553  glCallList (edgeList_);
1554  ACG::GLState::depthFunc(prev_depth);
1555  return;
1556  }
1557 
1558  if (edgeList_)
1559  {
1560  glNewList (edgeList_, GL_COMPILE);
1561  updateEdgeList_ = false;
1562  edgeBaseIndex_ = _state.pick_current_index ();
1563  }
1564 
1565  if (_state.color_picking ())
1566  {
1567  unsigned int idx = 0;
1568  update_pick_buffers ();
1569 
1570  for (; e_it!=e_end; ++e_it)
1571  {
1572  pickColorBuf_[idx] = _state.pick_get_name_color (e_it->idx());
1573  pickColorBuf_[idx+1] = _state.pick_get_name_color (e_it->idx());
1574  pickVertexBuf_[idx] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0)));
1575  pickVertexBuf_[idx+1] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1)));
1576  idx += 2;
1577  }
1578 
1579  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1580  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1581 
1582  ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1583  ACG::GLState::colorPointer(&pickColorBuf_[0]);
1584 
1585  glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
1586 
1587  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1588  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1589  }
1590  else
1591  {
1592  for (; e_it!=e_end; ++e_it)
1593  {
1594  _state.pick_set_name (e_it->idx());
1595  glBegin(GL_LINES);
1596  glVertex(mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0))));
1597  glVertex(mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1))));
1598  glEnd();
1599  }
1600  }
1601 
1602  if (edgeList_)
1603  {
1604  glEndList ();
1605  glCallList (edgeList_);
1606  }
1607 
1608  ACG::GLState::depthFunc(prev_depth);
1609 }
1610 
1611 //----------------------------------------------------------------------------
1612 
1613 
1614 template<class Mesh>
1615 void
1616 MeshNodeDeprecatedT<Mesh>::
1617 pick_any(GLState& _state)
1618 {
1619  GLenum prev_depth = _state.depthFunc();
1620 
1621  unsigned int numElements = mesh_.n_faces() + mesh_.n_edges() + mesh_.n_vertices();
1622 
1623  // nothing to pick ?
1624  if (numElements == 0)
1625  return;
1626 
1627  if (!_state.pick_set_maximum (numElements))
1628  {
1629  omerr() << "MeshNode::pick_any: color range too small, "
1630  << "picking failed\n";
1631  return;
1632  }
1633 
1634  if (anyList_ && !updateAnyList_ && _state.pick_current_index () == anyBaseIndex_)
1635  {
1636  glCallList (anyList_);
1637  glCallList (anyList_+1);
1638  glCallList (anyList_+2);
1639  return;
1640  }
1641 
1642  if (anyList_)
1643  {
1644  glNewList (anyList_, GL_COMPILE);
1645  updateAnyList_ = false;
1646  anyBaseIndex_ = _state.pick_current_index ();
1647  }
1648 
1649  // faces
1650  typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()),
1651  f_end(mesh_.faces_end());
1652  typename Mesh::ConstFaceVertexIter fv_it;
1653 
1654  // edges
1655  typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()),
1656  e_end(mesh_.edges_end());
1657 
1658  // vertices
1659  typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()),
1660  v_end(mesh_.vertices_end());
1661  GLuint vidx(mesh_.n_faces() + mesh_.n_edges());
1662 
1663 
1664 
1665  if (_state.color_picking ())
1666  {
1667  update_pick_buffers ();
1668 
1669  ACG::GLState::enableClientState(GL_VERTEX_ARRAY);
1670  ACG::GLState::enableClientState(GL_COLOR_ARRAY);
1671 
1672  // faces
1673  unsigned int idx = 0;
1674  if (mesh_.is_trimesh())
1675  {
1676  for (; f_it!=f_end; ++f_it)
1677  {
1678  pickColorBuf_[idx] = _state.pick_get_name_color (f_it->idx());
1679  pickColorBuf_[idx+1] = _state.pick_get_name_color (f_it->idx());
1680  pickColorBuf_[idx+2] = _state.pick_get_name_color (f_it->idx());
1681 
1682  fv_it=mesh_.cfv_iter(*f_it);
1683  pickVertexBuf_[idx] = mesh_.point(*fv_it); ++fv_it;
1684  pickVertexBuf_[idx+1] = mesh_.point(*fv_it); ++fv_it;
1685  pickVertexBuf_[idx+2] = mesh_.point(*fv_it);
1686  idx += 3;
1687  }
1688 
1689  ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1690  ACG::GLState::colorPointer(&pickColorBuf_[0]);
1691 
1692  glDrawArrays(GL_TRIANGLES, 0, mesh_.n_faces() * 3);
1693 
1694  }
1695  else
1696  {
1697  unsigned int face = 0;
1698  std::vector <GLint> first;
1699  std::vector <GLsizei> count;
1700 
1701  first.resize (mesh_.n_faces());
1702  count.resize (mesh_.n_faces());
1703 
1704  for (; f_it!=f_end; ++f_it, ++face)
1705  {
1706  unsigned int cnt = 0;
1707  first[face] = idx;
1708 
1709 
1710  for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it, ++idx, ++cnt)
1711  {
1712  pickVertexBuf_[idx] = mesh_.point(*fv_it);
1713  pickColorBuf_[idx] = _state.pick_get_name_color (f_it->idx());
1714  }
1715  count[face] = cnt;
1716  }
1717 
1718  ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1719  ACG::GLState::colorPointer(&pickColorBuf_[0]);
1720 
1721  glMultiDrawArrays(GL_POLYGON, &first[0], &count[0], mesh_.n_faces());
1722 
1723  }
1724 
1725  if (anyList_)
1726  {
1727  glEndList ();
1728  glNewList (anyList_+1, GL_COMPILE);
1729  }
1730 
1731  ACG::GLState::depthFunc(GL_LEQUAL);
1732 
1733  // edges
1734  idx = 0;
1735  for (; e_it!=e_end; ++e_it)
1736  {
1737  pickColorBuf_[idx] = _state.pick_get_name_color (mesh_.n_faces() + e_it->idx());
1738  pickColorBuf_[idx+1] = _state.pick_get_name_color (mesh_.n_faces() + e_it->idx());
1739  pickVertexBuf_[idx] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0)));
1740  pickVertexBuf_[idx+1] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1)));
1741  idx += 2;
1742  }
1743 
1744  ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1745  ACG::GLState::colorPointer(&pickColorBuf_[0]);
1746 
1747  glDrawArrays(GL_LINES, 0, mesh_.n_edges() * 2);
1748 
1749  if (anyList_)
1750  {
1751  ACG::GLState::depthFunc(prev_depth);
1752  glEndList ();
1753  glNewList (anyList_+2, GL_COMPILE);
1754  ACG::GLState::depthFunc(GL_LEQUAL);
1755  }
1756 
1757  // vertices
1758  idx = 0;
1759  for (; v_it!=v_end; ++v_it, ++idx, ++vidx)
1760  {
1761  pickColorBuf_[idx] = _state.pick_get_name_color (vidx);
1762  pickVertexBuf_[idx] = mesh_.point(*v_it);
1763  }
1764 
1765  ACG::GLState::vertexPointer (&pickVertexBuf_[0]);
1766  ACG::GLState::colorPointer(&pickColorBuf_[0]);
1767 
1768  glDrawArrays(GL_POINTS, 0, mesh_.n_vertices());
1769 
1770  ACG::GLState::disableClientState(GL_COLOR_ARRAY);
1771  ACG::GLState::disableClientState(GL_VERTEX_ARRAY);
1772  }
1773  else
1774  {
1775  // faces
1776  if (mesh_.is_trimesh())
1777  {
1778  for (; f_it!=f_end; ++f_it)
1779  {
1780  // set index
1781  _state.pick_set_name (f_it->idx());
1782 
1783  glBegin(GL_TRIANGLES);
1784 
1785  fv_it=mesh_.cfv_iter(*f_it);
1786  glVertex(mesh_.point(*fv_it)); ++fv_it;
1787  glVertex(mesh_.point(*fv_it)); ++fv_it;
1788  glVertex(mesh_.point(*fv_it));
1789  glEnd();
1790  }
1791  }
1792  else
1793  {
1794  for (; f_it!=f_end; ++f_it)
1795  {
1796  // set index
1797  _state.pick_set_name (f_it->idx());
1798 
1799  glBegin(GL_POLYGON);
1800 
1801  for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
1802  glVertex(mesh_.point(*fv_it));
1803 
1804  glEnd();
1805  }
1806  }
1807 
1808  if (anyList_)
1809  {
1810  ACG::GLState::depthFunc(prev_depth);
1811  glEndList ();
1812  glNewList (anyList_+1, GL_COMPILE);
1813  }
1814 
1815  ACG::GLState::depthFunc(GL_LEQUAL);
1816 
1817  // edges
1818  for (; e_it!=e_end; ++e_it)
1819  {
1820  _state.pick_set_name (mesh_.n_faces() + e_it->idx());
1821  glBegin(GL_LINES);
1822  glVertex(mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0))));
1823  glVertex(mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1))));
1824  glEnd();
1825  }
1826 
1827  if (anyList_)
1828  {
1829  ACG::GLState::depthFunc(prev_depth);
1830  glEndList ();
1831  glNewList (anyList_+2, GL_COMPILE);
1832  ACG::GLState::depthFunc(GL_LEQUAL);
1833  }
1834 
1835  // vertices
1836  for (; v_it!=v_end; ++v_it, ++vidx)
1837  {
1838  _state.pick_set_name (vidx);
1839  glBegin(GL_POINTS);
1840  glVertex(mesh_.point(*v_it));
1841  glEnd();
1842  }
1843  }
1844 
1845  ACG::GLState::depthFunc(prev_depth);
1846 
1847  if (anyList_)
1848  {
1849  glEndList ();
1850  glCallList (anyList_);
1851  glCallList (anyList_+1);
1852  glCallList (anyList_+2);
1853  }
1854 }
1855 
1856 //----------------------------------------------------------------------------
1857 
1858 template<class Mesh>
1859 void
1860 MeshNodeDeprecatedT<Mesh>::
1861 update_pick_buffers ()
1862 {
1863  unsigned int nfv = 0;
1864  if (mesh_.is_trimesh())
1865  nfv = mesh_.n_faces() * 3;
1866  else
1867  {
1868  // count number of vertices we need for faces in our buffer
1869  typename Mesh::ConstFaceIter f_it(mesh_.faces_sbegin()),
1870  f_end(mesh_.faces_end());
1871  typename Mesh::ConstFaceVertexIter fv_it;
1872  for (; f_it!=f_end; ++f_it)
1873  {
1874  for (fv_it=mesh_.cfv_iter(*f_it); fv_it.is_valid(); ++fv_it)
1875  nfv++;
1876  }
1877  }
1878 
1879  pickVertexBuf_.resize (std::max(mesh_.n_vertices(), std::max(mesh_.n_edges() * 2, size_t(nfv))));
1880  pickColorBuf_.resize (std::max(mesh_.n_vertices(), std::max(mesh_.n_edges() * 2, size_t(nfv))));
1881 }
1882 
1883 //=============================================================================
1884 } // namespace SceneGraph
1885 } // namespace ACG
1886 #endif // DOXY_IGNORE_THIS
1887 //=============================================================================
Kernel::ConstFaceVertexIter ConstFaceVertexIter
Circulator.
Definition: PolyMeshT.hh:180
static void enable(GLenum _cap)
replaces glEnable, but supports locking
Definition: GLState.cc:1490
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
void swap(VectorT< Scalar, DIM > &_v1, VectorT< Scalar, DIM > &_v2) noexcept(noexcept(_v1.swap(_v2)))
Definition: Vector11T.hh:715
static bool is_trimesh()
Determine whether this is a PolyMeshT or TriMeshT ( This function does not check the per face vertex ...
Definition: TriMeshT.hh:110
picks faces (should be implemented for all nodes)
Definition: BaseNode.hh:104
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
Definition: GLState.cc:1812
static void colorPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glColorPointer, supports locking
Definition: GLState.cc:1906
bool is_valid() const
The handle is valid iff the index is not equal to -1.
Definition: Handles.hh:77
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:115
static void depthRange(GLclampd _zNear, GLclampd _zFar)
replaces glDepthRange, supports locking
Definition: GLState.cc:1728
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
void glColor(const Vec3f &_v)
Wrapper: glColor for Vec3f.
Definition: gl.hh:146
picks verices (may not be implemented for all nodes)
Definition: BaseNode.hh:108
Kernel::TexCoord2D TexCoord2D
TexCoord2D type.
Definition: PolyMeshT.hh:123
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
Definition: GLState.cc:1541
picks edges (may not be implemented for all nodes)
Definition: BaseNode.hh:106
picks only visible front verices (may not be implemented for all nodes)
Definition: BaseNode.hh:115
Kernel::ConstFaceHalfedgeIter ConstFaceHalfedgeIter
Circulator.
Definition: PolyMeshT.hh:181
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Definition: GLState.cc:1700
static void normalPointer(GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glNormalPointer, supports locking
Definition: GLState.cc:1884
static void texcoordPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glTexcoordPointer, supports locking
Definition: GLState.cc:1928
void glNormal(const Vec3f &_n)
Wrapper: glNormal for Vec3f.
Definition: gl.hh:137
void glCheckErrors()
Definition: GLError.hh:105
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
Definition: GLState.cc:1555
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
Definition: GLState.cc:1862
Add normals to mesh item (vertices/faces)
Definition: Attributes.hh:87
static void disable(GLenum _cap)
replaces glDisable, but supports locking
Definition: GLState.cc:1504
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
Definition: GLState.cc:937
static void bindBufferARB(GLenum _target, GLuint _buffer)
same function as bindBuffer
Definition: GLState.hh:576
void glVertex(const Vec2i &_v)
Wrapper: glVertex for Vec2i.
Definition: gl.hh:97
void reset()
reset handle to be invalid
Definition: Handles.hh:80
picks only visible front edges (may not be implemented for all nodes)
Definition: BaseNode.hh:113
Kernel::Normal Normal
Normal type.
Definition: PolyMeshT.hh:117