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