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