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>
61 #include <OpenMesh/Tools/Utils/Timer.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 {
160 OpenMesh::Utils::Timer t;
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;
181 OpenMesh::Utils::Timer t;
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
696 MeshViewerWidgetT<M>::enable_strips()
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
710 MeshViewerWidgetT<M>::disable_strips()
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
OpenMesh::vector_cast
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
OpenMesh::PolyMeshT::ConstFaceVertexIter
Kernel::ConstFaceVertexIter ConstFaceVertexIter
Circulator.
Definition: PolyMeshT.hh:177
OpenMesh::IO::Options::VertexColor
Has (r) / store (w) vertex colors.
Definition: Options.hh:105
OpenMesh::IO::Options::FaceColor
Has (r) / store (w) face colors.
Definition: Options.hh:109
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
MeshViewerWidgetT::draw_scene
virtual void draw_scene(const std::string &_draw_mode) override
inherited drawing method
Definition: MeshViewerWidgetT_impl.hh:572
OpenMesh::Vec3f
VectorT< float, 3 > Vec3f
Definition: Vector11T.hh:831
OpenMesh::VectorT< float, 3 >
OpenMesh::Utils::Timer::as_string
std::string as_string(Format format=Automatic)
OpenMesh::VectorT::maximize
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition: Vector11T.hh:568
MeshViewerWidgetT::open_texture
virtual bool open_texture(const char *_filename)
load texture
Definition: MeshViewerWidgetT_impl.hh:206
MeshViewerWidgetT::open_mesh
virtual bool open_mesh(const char *_filename, OpenMesh::IO::Options _opt)
open mesh
Definition: MeshViewerWidgetT_impl.hh:78
OpenMesh::Utils::Timer::stop
void stop(void)
Stop measurement.
OpenMesh
Definition: MeshItems.hh:59
OpenMesh::IO::read_mesh
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:112
OpenMesh::VectorT::minimize
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition: Vector11T.hh:540
OpenMesh::PolyMeshT::update_vertex_normals
void update_vertex_normals()
Update normal vectors for all vertices.
Definition: PolyMeshT_impl.hh:550
Timer.hh
OpenMesh::IO::Options
Set options for reader/writer modules.
Definition: Options.hh:90
MeshViewerWidgetT::draw_openmesh
virtual void draw_openmesh(const std::string &_drawmode)
draw the mesh
Definition: MeshViewerWidgetT_impl.hh:284
OpenMesh::PolyMeshT::update_face_normals
void update_face_normals()
Update normal vectors for all faces.
Definition: PolyMeshT_impl.hh:335
Qt
MeshViewerWidgetT
Definition: MeshViewerWidgetT.hh:70
OpenMesh::IO::Options::VertexNormal
Has (r) / store (w) vertex normals.
Definition: Options.hh:104
OpenMesh::IO::Options::FaceNormal
Has (r) / store (w) face normals.
Definition: Options.hh:108
OpenMesh::Utils::Timer::start
void start(void)
Start measurement.
OpenMesh::Utils::Timer
Definition: Timer.hh:82
OpenMesh::IO::Options::VertexTexCoord
Has (r) / store (w) texture coordinates.
Definition: Options.hh:106
OpenMesh::PolyMeshT::VertexHandle
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136