Developer Documentation
MeshViewerWidgetT.cc
1 /* ========================================================================= *
2  * *
3  * OpenMesh *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openmesh.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenMesh. *
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  * $Date$ *
46  * *
47 \*===========================================================================*/
48 
49 #define OPENMESHAPPS_MESHVIEWERWIDGET_CC
50 
51 //== INCLUDES =================================================================
52 
53 #ifdef _MSC_VER
54 //# pragma warning(disable: 4267 4311)
55 #endif
56 
57 //
58 #include <iostream>
59 #include <fstream>
60 // --------------------
61 #include <QImage>
62 #include <QFileInfo>
63 #include <QKeyEvent>
64 // --------------------
65 #include <OpenMesh/Core/Utils/vector_cast.hh>
67 #include <OpenMesh/Apps/QtViewer/MeshViewerWidgetT.hh>
68 
69 using namespace OpenMesh;
70 using namespace Qt;
71 
72 #if defined(_MSC_VER)
73 # undef min
74 # undef max
75 #endif
76 
77 using namespace Qt;
78 //== IMPLEMENTATION ==========================================================
79 
80 
81 template <typename M>
82 bool
83 MeshViewerWidgetT<M>::open_mesh(const char* _filename, IO::Options _opt)
84 {
85  // load mesh
86  // calculate normals
87  // set scene center and radius
88 
89  mesh_.request_face_normals();
90  mesh_.request_face_colors();
91  mesh_.request_vertex_normals();
92  mesh_.request_vertex_colors();
93  mesh_.request_vertex_texcoords2D();
94 
95  std::cout << "Loading from file '" << _filename << "'\n";
96  if ( IO::read_mesh(mesh_, _filename, _opt ))
97  {
98  // store read option
99  opt_ = _opt;
100 
101  // update face and vertex normals
102  if ( ! opt_.check( IO::Options::FaceNormal ) )
103  mesh_.update_face_normals();
104  else
105  std::cout << "File provides face normals\n";
106 
107  if ( ! opt_.check( IO::Options::VertexNormal ) )
108  mesh_.update_vertex_normals();
109  else
110  std::cout << "File provides vertex normals\n";
111 
112 
113  // check for possible color information
114  if ( opt_.check( IO::Options::VertexColor ) )
115  {
116  std::cout << "File provides vertex colors\n";
117  add_draw_mode("Colored Vertices");
118  }
119  else
120  mesh_.release_vertex_colors();
121 
122  if ( _opt.check( IO::Options::FaceColor ) )
123  {
124  std::cout << "File provides face colors\n";
125  add_draw_mode("Solid Colored Faces");
126  add_draw_mode("Smooth Colored Faces");
127  }
128  else
129  mesh_.release_face_colors();
130 
131  if ( _opt.check( IO::Options::VertexTexCoord ) )
132  std::cout << "File provides texture coordinates\n";
133 
134 
135  // bounding box
136  typename Mesh::ConstVertexIter vIt(mesh_.vertices_begin());
137  typename Mesh::ConstVertexIter vEnd(mesh_.vertices_end());
138 
139  typedef typename Mesh::Point Point;
140  using OpenMesh::Vec3f;
141 
142  Vec3f bbMin, bbMax;
143 
144  bbMin = bbMax = OpenMesh::vector_cast<Vec3f>(mesh_.point(*vIt));
145 
146  for (size_t count=0; vIt!=vEnd; ++vIt, ++count)
147  {
148  bbMin.minimize( OpenMesh::vector_cast<Vec3f>(mesh_.point(*vIt)));
149  bbMax.maximize( OpenMesh::vector_cast<Vec3f>(mesh_.point(*vIt)));
150  }
151 
152 
153  // set center and radius
154  set_scene_pos( (bbMin+bbMax)*0.5, (bbMin-bbMax).norm()*0.5 );
155 
156  // for normal display
157  normal_scale_ = (bbMax-bbMin).min()*0.05f;
158 
159  // info
160  std::clog << mesh_.n_vertices() << " vertices, "
161  << mesh_.n_edges() << " edge, "
162  << mesh_.n_faces() << " faces\n";
163 
164  // base point for displaying face normals
165  {
167  t.start();
168  mesh_.add_property( fp_normal_base_ );
169  typename M::FaceIter f_it = mesh_.faces_begin();
170  typename M::FaceVertexIter fv_it;
171  for (;f_it != mesh_.faces_end(); ++f_it)
172  {
173  typename Mesh::Point v(0,0,0);
174  for( fv_it=mesh_.fv_iter(*f_it); fv_it.is_valid(); ++fv_it)
175  v += OpenMesh::vector_cast<typename Mesh::Normal>(mesh_.point(*fv_it));
176  v *= 1.0f/3.0f;
177  mesh_.property( fp_normal_base_, *f_it ) = v;
178  }
179  t.stop();
180  std::clog << "Computed base point for displaying face normals ["
181  << t.as_string() << "]" << std::endl;
182  }
183 
184  //
185  {
186  std::clog << "Computing strips.." << std::flush;
188  t.start();
189  compute_strips();
190  t.stop();
191  std::clog << "done [" << strips_.n_strips()
192  << " strips created in " << t.as_string() << "]\n";
193  }
194 
195  //
196 #if defined(WIN32)
197  updateGL();
198 #endif
199 
200  setWindowTitle(QFileInfo(_filename).fileName());
201 
202  // loading done
203  return true;
204  }
205  return false;
206 }
207 
208 
209 //-----------------------------------------------------------------------------
210 
211 template <typename M>
212 bool MeshViewerWidgetT<M>::open_texture( const char *_filename )
213 {
214  QImage texsrc;
215  QString fname = _filename;
216 
217  if (texsrc.load( fname ))
218  {
219  return set_texture( texsrc );
220  }
221  return false;
222 }
223 
224 
225 //-----------------------------------------------------------------------------
226 
227 template <typename M>
228 bool MeshViewerWidgetT<M>::set_texture( QImage& _texsrc )
229 {
230  if ( !opt_.vertex_has_texcoord() )
231  return false;
232 
233  {
234  // adjust texture size: 2^k * 2^l
235  int tex_w, w( _texsrc.width() );
236  int tex_h, h( _texsrc.height() );
237 
238  for (tex_w=1; tex_w <= w; tex_w <<= 1) {};
239  for (tex_h=1; tex_h <= h; tex_h <<= 1) {};
240  tex_w >>= 1;
241  tex_h >>= 1;
242  _texsrc = _texsrc.scaled( tex_w, tex_h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
243  }
244 
245  QImage texture( QGLWidget::convertToGLFormat ( _texsrc ) );
246 
247  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
248  glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
249  glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
250  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
251  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
252  glPixelStorei(GL_PACK_SKIP_ROWS, 0);
253  glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
254  glPixelStorei(GL_PACK_ALIGNMENT, 1);
255 
256  if ( tex_id_ > 0 )
257  {
258  glDeleteTextures(1, &tex_id_);
259  }
260  glGenTextures(1, &tex_id_);
261  glBindTexture(GL_TEXTURE_2D, tex_id_);
262 
263  // glTexGenfv( GL_S, GL_SPHERE_MAP, 0 );
264  // glTexGenfv( GL_T, GL_SPHERE_MAP, 0 );
265 
266  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
267  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
268  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
269  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
270 
271  glTexImage2D(GL_TEXTURE_2D, // target
272  0, // level
273  GL_RGBA, // internal format
274  texture.width(), // width (2^n)
275  texture.height(), // height (2^m)
276  0, // border
277  GL_RGBA, // format
278  GL_UNSIGNED_BYTE, // type
279  texture.bits() ); // pointer to pixels
280 
281  std::cout << "Texture loaded\n";
282  return true;
283 }
284 
285 
286 //-----------------------------------------------------------------------------
287 
288 template <typename M>
289 void
290 MeshViewerWidgetT<M>::draw_openmesh(const std::string& _draw_mode)
291 {
292  typename Mesh::ConstFaceIter fIt(mesh_.faces_begin()),
293  fEnd(mesh_.faces_end());
294 
295  typename Mesh::ConstFaceVertexIter fvIt;
296 
297 #if defined(OM_USE_OSG) && OM_USE_OSG
298  if (_draw_mode == "OpenSG Indices") // --------------------------------------
299  {
300  glEnableClientState(GL_VERTEX_ARRAY);
301  glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
302 
303  glEnableClientState(GL_NORMAL_ARRAY);
304  glNormalPointer(GL_FLOAT, 0, mesh_.vertex_normals());
305 
306  if ( tex_id_ && mesh_.has_vertex_texcoords2D() )
307  {
308  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
309  glTexCoordPointer(2, GL_FLOAT, 0, mesh_.texcoords2D());
310  glEnable(GL_TEXTURE_2D);
311  glBindTexture(GL_TEXTURE_2D, tex_id_);
312  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, tex_mode_);
313  }
314 
315  glDrawElements(GL_TRIANGLES,
316  mesh_.osg_indices()->size(),
317  GL_UNSIGNED_INT,
318  &mesh_.osg_indices()->getField()[0] );
319 
320  glDisableClientState(GL_VERTEX_ARRAY);
321  glDisableClientState(GL_NORMAL_ARRAY);
322  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
323  }
324  else
325 #endif
326 
327  if (_draw_mode == "Wireframe") // -------------------------------------------
328  {
329  glBegin(GL_TRIANGLES);
330  for (; fIt!=fEnd; ++fIt)
331  {
332  fvIt = mesh_.cfv_iter(*fIt);
333  glVertex3fv( &mesh_.point(*fvIt)[0] );
334  ++fvIt;
335  glVertex3fv( &mesh_.point(*fvIt)[0] );
336  ++fvIt;
337  glVertex3fv( &mesh_.point(*fvIt)[0] );
338  }
339  glEnd();
340  }
341 
342  else if (_draw_mode == "Solid Flat") // -------------------------------------
343  {
344  glBegin(GL_TRIANGLES);
345  for (; fIt!=fEnd; ++fIt)
346  {
347  glNormal3fv( &mesh_.normal(*fIt)[0] );
348 
349  fvIt = mesh_.cfv_iter(*fIt);
350  glVertex3fv( &mesh_.point(*fvIt)[0] );
351  ++fvIt;
352  glVertex3fv( &mesh_.point(*fvIt)[0] );
353  ++fvIt;
354  glVertex3fv( &mesh_.point(*fvIt)[0] );
355  }
356  glEnd();
357 
358  }
359 
360 
361  else if (_draw_mode == "Solid Smooth") // -----------------------------------
362  {
363  glEnableClientState(GL_VERTEX_ARRAY);
364  glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
365 
366  glEnableClientState(GL_NORMAL_ARRAY);
367  glNormalPointer(GL_FLOAT, 0, mesh_.vertex_normals());
368 
369  if ( tex_id_ && mesh_.has_vertex_texcoords2D() )
370  {
371  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
372  glTexCoordPointer(2, GL_FLOAT, 0, mesh_.texcoords2D());
373  glEnable(GL_TEXTURE_2D);
374  glBindTexture(GL_TEXTURE_2D, tex_id_);
375  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, tex_mode_);
376  }
377 
378  glBegin(GL_TRIANGLES);
379  for (; fIt!=fEnd; ++fIt)
380  {
381  fvIt = mesh_.cfv_iter(*fIt);
382  glArrayElement(fvIt->idx());
383  ++fvIt;
384  glArrayElement(fvIt->idx());
385  ++fvIt;
386  glArrayElement(fvIt->idx());
387  }
388  glEnd();
389 
390  glDisableClientState(GL_VERTEX_ARRAY);
391  glDisableClientState(GL_NORMAL_ARRAY);
392  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
393 
394  if ( tex_id_ && mesh_.has_vertex_texcoords2D() )
395  {
396  glDisable(GL_TEXTURE_2D);
397  }
398  }
399 
400  else if (_draw_mode == "Colored Vertices") // --------------------------------
401  {
402  glEnableClientState(GL_VERTEX_ARRAY);
403  glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
404 
405  glEnableClientState(GL_NORMAL_ARRAY);
406  glNormalPointer(GL_FLOAT, 0, mesh_.vertex_normals());
407 
408  if ( mesh_.has_vertex_colors() )
409  {
410  glEnableClientState( GL_COLOR_ARRAY );
411  glColorPointer(3, GL_UNSIGNED_BYTE, 0,mesh_.vertex_colors());
412  }
413 
414  glBegin(GL_TRIANGLES);
415  for (; fIt!=fEnd; ++fIt)
416  {
417  fvIt = mesh_.cfv_iter(*fIt);
418  glArrayElement(fvIt->idx());
419  ++fvIt;
420  glArrayElement(fvIt->idx());
421  ++fvIt;
422  glArrayElement(fvIt->idx());
423  }
424  glEnd();
425 
426  glDisableClientState(GL_VERTEX_ARRAY);
427  glDisableClientState(GL_NORMAL_ARRAY);
428  glDisableClientState(GL_COLOR_ARRAY);
429  }
430 
431 
432  else if (_draw_mode == "Solid Colored Faces") // -----------------------------
433  {
434  glEnableClientState(GL_VERTEX_ARRAY);
435  glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
436 
437  glEnableClientState(GL_NORMAL_ARRAY);
438  glNormalPointer(GL_FLOAT, 0, mesh_.vertex_normals());
439 
440  glBegin(GL_TRIANGLES);
441  for (; fIt!=fEnd; ++fIt)
442  {
443  glColor( *fIt );
444 
445  fvIt = mesh_.cfv_iter(*fIt);
446  glArrayElement(fvIt->idx());
447  ++fvIt;
448  glArrayElement(fvIt->idx());
449  ++fvIt;
450  glArrayElement(fvIt->idx());
451  }
452  glEnd();
453 
454  glDisableClientState(GL_VERTEX_ARRAY);
455  glDisableClientState(GL_NORMAL_ARRAY);
456  }
457 
458 
459  else if (_draw_mode == "Smooth Colored Faces") // ---------------------------
460  {
461  glEnableClientState(GL_VERTEX_ARRAY);
462  glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
463 
464  glEnableClientState(GL_NORMAL_ARRAY);
465  glNormalPointer(GL_FLOAT, 0, mesh_.vertex_normals());
466 
467  glBegin(GL_TRIANGLES);
468  for (; fIt!=fEnd; ++fIt)
469  {
470  glMaterial( *fIt );
471 
472  fvIt = mesh_.cfv_iter(*fIt);
473  glArrayElement(fvIt->idx());
474  ++fvIt;
475  glArrayElement(fvIt->idx());
476  ++fvIt;
477  glArrayElement(fvIt->idx());
478  }
479  glEnd();
480 
481  glDisableClientState(GL_VERTEX_ARRAY);
482  glDisableClientState(GL_NORMAL_ARRAY);
483  }
484 
485 
486  else if ( _draw_mode == "Strips'n VertexArrays" ) // ------------------------
487  {
488  glEnableClientState(GL_VERTEX_ARRAY);
489  glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
490 
491  glEnableClientState(GL_NORMAL_ARRAY);
492  glNormalPointer(GL_FLOAT, 0, mesh_.vertex_normals());
493 
494  if ( tex_id_ && mesh_.has_vertex_texcoords2D() )
495  {
496  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
497  glTexCoordPointer(2, GL_FLOAT, 0, mesh_.texcoords2D());
498  glEnable(GL_TEXTURE_2D);
499  glBindTexture(GL_TEXTURE_2D, tex_id_);
500  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, tex_mode_);
501  }
502 
503  typename MyStripifier::StripsIterator strip_it = strips_.begin();
504  typename MyStripifier::StripsIterator strip_last = strips_.end();
505 
506  // Draw all strips
507  for (; strip_it!=strip_last; ++strip_it)
508  {
509  glDrawElements(GL_TRIANGLE_STRIP,
510  static_cast<GLsizei>(strip_it->size()), GL_UNSIGNED_INT, &(*strip_it)[0] );
511  }
512 
513  glDisableClientState(GL_VERTEX_ARRAY);
514  glDisableClientState(GL_NORMAL_ARRAY);
515  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
516  }
517 
518 
519  else if (_draw_mode == "Show Strips" && strips_.is_valid() ) // -------------
520  {
521  typename MyStripifier::StripsIterator strip_it = strips_.begin();
522  typename MyStripifier::StripsIterator strip_last = strips_.end();
523 
524  float cmax = 256.0f;
525  int range = 220;
526  int base = (int)cmax-range;
527  int drcol = 13;
528  int dgcol = 31;
529  int dbcol = 17;
530 
531  int rcol=0, gcol=dgcol, bcol=dbcol+dbcol;
532 
533  // Draw all strips
534  for (; strip_it!=strip_last; ++strip_it)
535  {
536  typename MyStripifier::IndexIterator idx_it = strip_it->begin();
537  typename MyStripifier::IndexIterator idx_last = strip_it->end();
538 
539  rcol = (rcol+drcol) % range;
540  gcol = (gcol+dgcol) % range;
541  bcol = (bcol+dbcol) % range;
542 
543  glBegin(GL_TRIANGLE_STRIP);
544  glColor3f((rcol+base)/cmax, (gcol+base)/cmax, (bcol+base)/cmax);
545  for ( ;idx_it != idx_last; ++idx_it )
546  glVertex3fv(&mesh_.point( OM_TYPENAME Mesh::VertexHandle(*idx_it))[0]);
547  glEnd();
548  }
549  glColor3f(1.0, 1.0, 1.0);
550  }
551 
552 
553  else if( _draw_mode == "Points" ) // -----------------------------------------
554  {
555  glEnableClientState(GL_VERTEX_ARRAY);
556  glVertexPointer(3, GL_FLOAT, 0, mesh_.points());
557 
558  if (mesh_.has_vertex_colors() && use_color_)
559  {
560  glEnableClientState(GL_COLOR_ARRAY);
561  glColorPointer(3, GL_UNSIGNED_BYTE, 0, mesh_.vertex_colors());
562  }
563 
564  glDrawArrays( GL_POINTS, 0, static_cast<GLsizei>(mesh_.n_vertices()) );
565  glDisableClientState(GL_VERTEX_ARRAY);
566  glDisableClientState(GL_COLOR_ARRAY);
567  }
568 
569 
570 }
571 
572 
573 //-----------------------------------------------------------------------------
574 
575 
576 template <typename M>
577 void
578 MeshViewerWidgetT<M>::draw_scene(const std::string& _draw_mode)
579 {
580 
581  if ( ! mesh_.n_vertices() )
582  return;
583 
584 #if defined(OM_USE_OSG) && OM_USE_OSG
585  else if ( _draw_mode == "OpenSG Indices")
586  {
587  glEnable(GL_LIGHTING);
588  glShadeModel(GL_SMOOTH);
589  draw_openmesh( _draw_mode );
590  }
591  else
592 #endif
593  if ( _draw_mode == "Points" )
594  {
595  glDisable(GL_LIGHTING);
596  draw_openmesh(_draw_mode);
597  }
598  else if (_draw_mode == "Wireframe")
599  {
600  glDisable(GL_LIGHTING);
601  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
602  draw_openmesh(_draw_mode);
603  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
604  }
605 
606  else if ( _draw_mode == "Hidden-Line" )
607  {
608  glDisable(GL_LIGHTING);
609  glShadeModel(GL_FLAT);
610  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
611  glColor4f( 0.0f, 0.0f, 0.0f, 1.0f );
612  glDepthRange(0.01, 1.0);
613  draw_openmesh( "Wireframe" );
614 
615  glPolygonMode( GL_FRONT_AND_BACK, GL_LINE);
616  glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
617  glDepthRange( 0.0, 1.0 );
618  draw_openmesh( "Wireframe" );
619 
620  glPolygonMode( GL_FRONT_AND_BACK, GL_FILL);
621  }
622 
623  else if (_draw_mode == "Solid Flat")
624  {
625  glEnable(GL_LIGHTING);
626  glShadeModel(GL_FLAT);
627  draw_openmesh(_draw_mode);
628  }
629 
630  else if (_draw_mode == "Solid Smooth" ||
631  _draw_mode == "Strips'n VertexArrays" )
632  {
633  glEnable(GL_LIGHTING);
634  glShadeModel(GL_SMOOTH);
635  draw_openmesh(_draw_mode);
636  }
637 
638  else if (_draw_mode == "Show Strips")
639  {
640  glDisable(GL_LIGHTING);
641  draw_openmesh(_draw_mode);
642  }
643 
644  else if (_draw_mode == "Colored Vertices" )
645  {
646  glDisable(GL_LIGHTING);
647  glShadeModel(GL_SMOOTH);
648  draw_openmesh(_draw_mode);
649  }
650 
651  else if (_draw_mode == "Solid Colored Faces")
652  {
653  glDisable(GL_LIGHTING);
654  glShadeModel(GL_FLAT);
655  draw_openmesh(_draw_mode);
656  setDefaultMaterial();
657  }
658 
659  else if (_draw_mode == "Smooth Colored Faces" )
660  {
661  glEnable(GL_LIGHTING);
662  glShadeModel(GL_SMOOTH);
663  draw_openmesh(_draw_mode);
664  setDefaultMaterial();
665  }
666 
667  if (show_vnormals_)
668  {
669  typename Mesh::VertexIter vit;
670  glDisable(GL_LIGHTING);
671  glBegin(GL_LINES);
672  glColor3f(1.000f, 0.803f, 0.027f); // orange
673  for(vit=mesh_.vertices_begin(); vit!=mesh_.vertices_end(); ++vit)
674  {
675  glVertex( *vit );
676  glVertex( mesh_.point( *vit ) + normal_scale_*mesh_.normal( *vit ) );
677  }
678  glEnd();
679  }
680 
681  if (show_fnormals_)
682  {
683  typename Mesh::FaceIter fit;
684  glDisable(GL_LIGHTING);
685  glBegin(GL_LINES);
686  glColor3f(0.705f, 0.976f, 0.270f); // greenish
687  for(fit=mesh_.faces_begin(); fit!=mesh_.faces_end(); ++fit)
688  {
689  glVertex( mesh_.property(fp_normal_base_, *fit) );
690  glVertex( mesh_.property(fp_normal_base_, *fit) +
691  normal_scale_*mesh_.normal( *fit ) );
692  }
693  glEnd();
694  }
695 }
696 
697 
698 //-----------------------------------------------------------------------------
699 
700 template <typename M>
701 void
703 {
704  if (!f_strips_)
705  {
706  f_strips_ = true;
707  add_draw_mode("Strips'n VertexArrays");
708  add_draw_mode("Show Strips");
709  }
710 }
711 
712 //-----------------------------------------------------------------------------
713 
714 template <typename M>
715 void
717 {
718  if (f_strips_)
719  {
720  f_strips_ = false;
721  del_draw_mode("Show Strips");
722  del_draw_mode("Strip'n VertexArrays");
723  }
724 }
725 
726 
727 //-----------------------------------------------------------------------------
728 
729 #define TEXMODE( Mode ) \
730  tex_mode_ = Mode; std::cout << "Texture mode set to " << #Mode << std::endl
731 
732 template <typename M>
733 void
734 MeshViewerWidgetT<M>::keyPressEvent( QKeyEvent* _event)
735 {
736  switch( _event->key() )
737  {
738  case Key_D:
739  if ( mesh_.has_vertex_colors() && (current_draw_mode()=="Points") )
740  {
741  use_color_ = !use_color_;
742  std::cout << "use color: " << (use_color_?"yes\n":"no\n");
743  if (!use_color_)
744  glColor3f(1.0f, 1.0f, 1.0f);
745  updateGL();
746  }
747  break;
748 
749  case Key_N:
750  if ( _event->modifiers() & ShiftModifier )
751  {
752  show_fnormals_ = !show_fnormals_;
753  std::cout << "show face normals: " << (show_fnormals_?"yes\n":"no\n");
754  }
755  else
756  {
757  show_vnormals_ = !show_vnormals_;
758  std::cout << "show vertex normals: " << (show_vnormals_?"yes\n":"no\n");
759  }
760  updateGL();
761  break;
762 
763  case Key_I:
764  std::cout << "\n# Vertices : " << mesh_.n_vertices() << std::endl;
765  std::cout << "# Edges : " << mesh_.n_edges() << std::endl;
766  std::cout << "# Faces : " << mesh_.n_faces() << std::endl;
767  std::cout << "binary input : " << opt_.check(opt_.Binary) << std::endl;
768  std::cout << "swapped input : " << opt_.check(opt_.Swap) << std::endl;
769  std::cout << "vertex normal : "
770  << opt_.check(opt_.VertexNormal) << std::endl;
771  std::cout << "vertex texcoord: "
772  << opt_.check(opt_.VertexTexCoord) << std::endl;
773  std::cout << "vertex color : "
774  << opt_.check(opt_.VertexColor) << std::endl;
775  std::cout << "face normal : "
776  << opt_.check(opt_.FaceNormal) << std::endl;
777  std::cout << "face color : "
778  << opt_.check(opt_.FaceColor) << std::endl;
779  this->QGLViewerWidget::keyPressEvent( _event );
780  break;
781 
782  case Key_T:
783  switch( tex_mode_ )
784  {
785  case GL_MODULATE: TEXMODE(GL_DECAL); break;
786  case GL_DECAL: TEXMODE(GL_BLEND); break;
787  case GL_BLEND: TEXMODE(GL_REPLACE); break;
788  case GL_REPLACE: TEXMODE(GL_MODULATE); break;
789  }
790  updateGL();
791  break;
792 
793  default:
794  this->QGLViewerWidget::keyPressEvent( _event );
795  }
796 }
797 
798 #undef TEXMODE
799 
800 //=============================================================================
801 
Has (r) / store (w) texture coordinates.
Definition: Options.hh:111
void vector_cast(const src_t &_src, dst_t &_dst, GenProg::Int2Type< n >)
Cast vector type to another vector type by copying the vector elements.
Definition: vector_cast.hh:86
Has (r) / store (w) vertex normals.
Definition: Options.hh:109
virtual void draw_scene(const std::string &_draw_mode)
inherited drawing method
Has (r) / store (w) face normals.
Definition: Options.hh:113
void start(void)
Start measurement.
virtual void draw_openmesh(const std::string &_drawmode)
draw the mesh
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition: Vector11T.hh:562
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:104
Kernel::ConstFaceVertexIter ConstFaceVertexIter
Circulator.
Definition: PolyMeshT.hh:180
Set options for reader/writer modules.
Definition: Options.hh:95
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:139
virtual bool open_mesh(const char *_filename, OpenMesh::IO::Options _opt)
open mesh
VectorT< float, 3 > Vec3f
Definition: Vector11T.hh:769
void update_face_normals()
Update normal vectors for all faces.
Definition: PolyMeshT.cc:259
Has (r) / store (w) face colors.
Definition: Options.hh:114
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:115
std::string as_string(Format format=Automatic)
void update_vertex_normals()
Update normal vectors for all vertices.
Definition: PolyMeshT.cc:448
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition: Vector11T.hh:534
Has (r) / store (w) vertex colors.
Definition: Options.hh:110
void stop(void)
Stop measurement.
virtual bool open_texture(const char *_filename)
load texture