OpenMesh: OpenMesh/Apps/QtViewer/MeshViewerWidgetT_impl.hh Source File

| OpenMesh

MeshViewerWidgetT_impl.hh
1 /* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2022, 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>
59 #include <OpenMesh/Tools/Utils/Timer.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 {
157 OpenMesh::Utils::Timer t;
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;
178 OpenMesh::Utils::Timer t;
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 = _texsrc.convertToFormat(QImage::Format_ARGB32).rgbSwapped();
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
693 MeshViewerWidgetT<M>::enable_strips()
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
707 MeshViewerWidgetT<M>::disable_strips()
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
Timer.hh
A timer class.
OpenMesh
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:59
OpenMesh::Vec3f
VectorT< float, 3 > Vec3f
3-float vector
Definition: Vector11T.hh:850
OpenMesh::IO::read_mesh
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:95
MeshViewerWidgetT
Definition: MeshViewerWidgetT.hh:71
MeshViewerWidgetT::open_texture
virtual bool open_texture(const char *_filename)
load texture
Definition: MeshViewerWidgetT_impl.hh:203
MeshViewerWidgetT::open_mesh
virtual bool open_mesh(const char *_filename, OpenMesh::IO::Options _opt)
open mesh
Definition: MeshViewerWidgetT_impl.hh:75
MeshViewerWidgetT::draw_scene
virtual void draw_scene(const std::string &_draw_mode) override
inherited drawing method
Definition: MeshViewerWidgetT_impl.hh:569
MeshViewerWidgetT::draw_openmesh
virtual void draw_openmesh(const std::string &_drawmode)
draw the mesh
Definition: MeshViewerWidgetT_impl.hh:281
OpenMesh::VectorT< float, 3 >
OpenMesh::VectorT::minimize
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition: Vector11T.hh:559
OpenMesh::VectorT::maximize
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition: Vector11T.hh:587
OpenMesh::IO::Options
Set options for reader/writer modules.
Definition: Options.hh:91
OpenMesh::IO::Options::FaceNormal
@ FaceNormal
Has (r) / store (w) face normals.
Definition: Options.hh:108
OpenMesh::IO::Options::FaceColor
@ FaceColor
Has (r) / store (w) face colors.
Definition: Options.hh:109
OpenMesh::IO::Options::VertexNormal
@ VertexNormal
Has (r) / store (w) vertex normals.
Definition: Options.hh:104
OpenMesh::IO::Options::VertexTexCoord
@ VertexTexCoord
Has (r) / store (w) texture coordinates.
Definition: Options.hh:106
OpenMesh::IO::Options::VertexColor
@ VertexColor
Has (r) / store (w) vertex colors.
Definition: Options.hh:105
OpenMesh::PolyMeshT::ConstFaceIter
Kernel::ConstFaceIter ConstFaceIter
Scalar type.
Definition: PolyMeshT.hh:151
OpenMesh::PolyMeshT::VertexHandle
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136
OpenMesh::PolyMeshT::ConstFaceVertexIter
Kernel::ConstFaceVertexIter ConstFaceVertexIter
Circulator.
Definition: PolyMeshT.hh:177
OpenMesh::PolyMeshT::FaceIter
Kernel::FaceIter FaceIter
Scalar type.
Definition: PolyMeshT.hh:146
OpenMesh::PolyMeshT::update_face_normals
void update_face_normals()
Update normal vectors for all faces.
Definition: PolyMeshT_impl.hh:335
OpenMesh::PolyMeshT::ConstVertexIter
Kernel::ConstVertexIter ConstVertexIter
Scalar type.
Definition: PolyMeshT.hh:148
OpenMesh::PolyMeshT::update_vertex_normals
void update_vertex_normals()
Update normal vectors for all vertices.
Definition: PolyMeshT_impl.hh:550
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
OpenMesh::PolyMeshT::VertexIter
Kernel::VertexIter VertexIter
Scalar type.
Definition: PolyMeshT.hh:143
OpenMesh::Utils::Timer
Timer class.
Definition: Timer.hh:83
OpenMesh::Utils::Timer::stop
void stop(void)
Stop measurement.
OpenMesh::Utils::Timer::as_string
std::string as_string(Format format=Automatic)
Returns the measured time as a string.
OpenMesh::Utils::Timer::start
void start(void)
Start measurement.