OpenMesh
MeshViewerWidgetT_impl.hh
1/* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2023, 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
62using namespace OpenMesh;
63using namespace Qt;
64
65#if defined(_MSC_VER)
66# undef min
67# undef max
68#endif
69
70//== IMPLEMENTATION ==========================================================
71
72
73template <typename M>
74bool
75MeshViewerWidgetT<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
105 // check for possible color information
106 if ( opt_.check( IO::Options::VertexColor ) )
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";
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 if ( this->parentWidget() != nullptr )
192 this->parentWidget()->setWindowTitle(QFileInfo(_filename).fileName());
193 else
194 setWindowTitle(QFileInfo(_filename).fileName());
195
196 // loading done
197 return true;
198 }
199 return false;
200}
201
202
203//-----------------------------------------------------------------------------
204
205template <typename M>
206bool 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
221template <typename M>
222bool 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 = _texsrc.convertToFormat(QImage::Format_ARGB32).rgbSwapped();
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
282template <typename M>
283void
284MeshViewerWidgetT<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
570template <typename M>
571void
572MeshViewerWidgetT<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
694template <typename M>
695void
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
708template <typename M>
709void
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
726template <typename M>
727void
728MeshViewerWidgetT<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
A timer class.
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:59
Definition: MeshViewerWidgetT.hh:71
virtual bool open_texture(const char *_filename)
load texture
Definition: MeshViewerWidgetT_impl.hh:206
virtual bool open_mesh(const char *_filename, OpenMesh::IO::Options _opt)
open mesh
Definition: MeshViewerWidgetT_impl.hh:75
virtual void draw_scene(const std::string &_draw_mode) override
inherited drawing method
Definition: MeshViewerWidgetT_impl.hh:572
virtual void draw_openmesh(const std::string &_drawmode)
draw the mesh
Definition: MeshViewerWidgetT_impl.hh:284
VectorT< Scalar, DIM > min(const VectorT< Scalar, DIM > &_v1, const VectorT< Scalar, DIM > &_v2)
non-member min
Definition: Vector11T.hh:797
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
Definition: Vector11T.hh:588
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
Definition: Vector11T.hh:560
Scalar norm(const VectorT< Scalar, DIM > &_v)
non-member norm
Definition: Vector11T.hh:749
Set options for reader/writer modules.
Definition: Options.hh:92
Kernel::ConstFaceIter ConstFaceIter
Scalar type.
Definition: PolyMeshT.hh:151
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Definition: PolyMeshT.hh:136
Kernel::ConstFaceVertexIter ConstFaceVertexIter
Circulator.
Definition: PolyMeshT.hh:177
Kernel::FaceIter FaceIter
Scalar type.
Definition: PolyMeshT.hh:146
void update_face_normals()
Update normal vectors for all faces.
Definition: PolyMeshT_impl.hh:335
Kernel::ConstVertexIter ConstVertexIter
Scalar type.
Definition: PolyMeshT.hh:148
void update_vertex_normals()
Update normal vectors for all vertices.
Definition: PolyMeshT_impl.hh:572
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
Kernel::VertexIter VertexIter
Scalar type.
Definition: PolyMeshT.hh:143
Timer class.
Definition: Timer.hh:83
void stop(void)
Stop measurement.
std::string as_string(Format format=Automatic)
Returns the measured time as a string.
void start(void)
Start measurement.

Project OpenMesh, ©  Visual Computing Institute, RWTH Aachen. Documentation generated using doxygen .