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