📄 qglviewerwidget.cc
字号:
//=============================================================================// // OpenMesh // Copyright (C) 2001-2005 by Computer Graphics Group, RWTH Aachen // www.openmesh.org // //-----------------------------------------------------------------------------// // License // // This library is free software; you can redistribute it and/or modify it // under the terms of the GNU Library General Public License as published // by the Free Software Foundation, version 2. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // //-----------------------------------------------------------------------------// // $Revision: 1.2.2.1 $// $Date: 2007-02-26 17:02:29 $// //=============================================================================//== INCLUDES =================================================================#ifdef _MSC_VER# pragma warning(disable: 4267 4311 4305)#endif#include <iomanip>#include <sstream>#include <algorithm>// --------------------#ifndef WIN32#ifdef ARCH_DARWIN# include <glut.h>#else# include <GL/glut.h>#endif#endif// --------------------#include <qnamespace.h>#include <qapplication.h>#include <qpopupmenu.h>#include <qcursor.h>#include <qimage.h>#include <qdatetime.h>// --------------------#include <OpenMesh/Apps/QtViewer/QGLViewerWidget.hh>#include <OpenMesh/Tools/Utils/Timer.hh>#if !defined(M_PI)# define M_PI 3.1415926535897931#endifusing namespace OpenMesh;//== IMPLEMENTATION ========================================================== std::string QGLViewerWidget::nomode_ = "";//----------------------------------------------------------------------------QGLViewerWidget::QGLViewerWidget( QWidget* _parent, const char* _name ) : QGLWidget( _parent, _name ){ init();}//----------------------------------------------------------------------------QGLViewerWidget::QGLViewerWidget( QGLFormat& _fmt, QWidget* _parent, const char* _name ) : QGLWidget( _fmt, _parent, _name ){ init();}//----------------------------------------------------------------------------void QGLViewerWidget::init(void){ // qt stuff setBackgroundMode( NoBackground ); setFocusPolicy(QWidget::StrongFocus); setAcceptDrops( true ); setCursor(pointingHandCursor); // popup menu popup_menu_ = new QPopupMenu(this, "Draw Mode Menu"); popup_menu_->setCheckable(true); connect( popup_menu_, SIGNAL(activated(int)), this, SLOT(slotPopupMenu(int))); // init draw modes n_draw_modes_ = 0; add_draw_mode("Wireframe"); add_draw_mode("Solid Flat"); add_draw_mode("Solid Smooth"); slotPopupMenu(2);}//----------------------------------------------------------------------------QGLViewerWidget::~QGLViewerWidget(){}//----------------------------------------------------------------------------void QGLViewerWidget::setDefaultMaterial(void){ GLfloat mat_a[] = {0.1, 0.1, 0.1, 1.0}; GLfloat mat_d[] = {0.7, 0.7, 0.5, 1.0}; GLfloat mat_s[] = {1.0, 1.0, 1.0, 1.0}; GLfloat shine[] = {120.0}; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat_a); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_d); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat_s); glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shine);}//----------------------------------------------------------------------------voidQGLViewerWidget::setDefaultLight(void){ GLfloat pos1[] = { 0.1, 0.1, -0.02, 0.0}; GLfloat pos2[] = {-0.1, 0.1, -0.02, 0.0}; GLfloat pos3[] = { 0.0, 0.0, 0.1, 0.0}; GLfloat col1[] = { 0.7, 0.7, 0.8, 1.0}; GLfloat col2[] = { 0.8, 0.7, 0.7, 1.0}; GLfloat col3[] = { 1.0, 1.0, 1.0, 1.0}; glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0,GL_POSITION, pos1); glLightfv(GL_LIGHT0,GL_DIFFUSE, col1); glLightfv(GL_LIGHT0,GL_SPECULAR, col1); glEnable(GL_LIGHT1); glLightfv(GL_LIGHT1,GL_POSITION, pos2); glLightfv(GL_LIGHT1,GL_DIFFUSE, col2); glLightfv(GL_LIGHT1,GL_SPECULAR, col2); glEnable(GL_LIGHT2); glLightfv(GL_LIGHT2,GL_POSITION, pos3); glLightfv(GL_LIGHT2,GL_DIFFUSE, col3); glLightfv(GL_LIGHT2,GL_SPECULAR, col3);}//----------------------------------------------------------------------------voidQGLViewerWidget::initializeGL(){ // OpenGL state glClearColor(0.0, 0.0, 0.0, 0.0); glDisable( GL_DITHER ); glEnable( GL_DEPTH_TEST ); // Material setDefaultMaterial(); // Lighting glLoadIdentity(); setDefaultLight(); // Fog GLfloat fogColor[4] = { 0.3, 0.3, 0.4, 1.0 }; glFogi(GL_FOG_MODE, GL_LINEAR); glFogfv(GL_FOG_COLOR, fogColor); glFogf(GL_FOG_DENSITY, 0.35); glHint(GL_FOG_HINT, GL_DONT_CARE); glFogf(GL_FOG_START, 5.0f); glFogf(GL_FOG_END, 25.0f); // scene pos and size glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix_); set_scene_pos(Vec3f(0.0, 0.0, 0.0), 1.0);}//----------------------------------------------------------------------------voidQGLViewerWidget::resizeGL( int _w, int _h ){ update_projection_matrix(); glViewport(0, 0, _w, _h); updateGL();}//----------------------------------------------------------------------------voidQGLViewerWidget::paintGL(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode( GL_PROJECTION ); glLoadMatrixd( projection_matrix_ ); glMatrixMode( GL_MODELVIEW ); glLoadMatrixd( modelview_matrix_ ); if (draw_mode_) { assert(draw_mode_ <= n_draw_modes_); draw_scene(draw_mode_names_[draw_mode_-1]); }}//----------------------------------------------------------------------------voidQGLViewerWidget::draw_scene(const std::string& _draw_mode){ if (_draw_mode == "Wireframe") { glDisable(GL_LIGHTING);#ifndef WIN32 glutWireTeapot(0.5);#endif } else if (_draw_mode == "Solid Flat") { glEnable(GL_LIGHTING); glShadeModel(GL_FLAT);#ifndef WIN32 glutSolidTeapot(0.5);#endif } else if (_draw_mode == "Solid Smooth") { glEnable(GL_LIGHTING); glShadeModel(GL_SMOOTH);#ifndef WIN32 glutSolidTeapot(0.5);#endif }}//----------------------------------------------------------------------------voidQGLViewerWidget::mousePressEvent( QMouseEvent* _event ){ // popup menu if (_event->button() == RightButton) { popup_menu_->exec(QCursor::pos()); } else { last_point_ok_ = map_to_sphere( last_point_2D_=_event->pos(), last_point_3D_ ); }}//----------------------------------------------------------------------------voidQGLViewerWidget::mouseMoveEvent( QMouseEvent* _event ){ QPoint newPoint2D = _event->pos(); if ( (newPoint2D.x()<0) || (newPoint2D.x()>width()) || (newPoint2D.y()<0) || (newPoint2D.y()>height()) ) return; // Left button: rotate around center_ // Middle button: translate object // Left & middle button: zoom in/out float value_y; Vec3f newPoint3D; bool newPoint_hitSphere = map_to_sphere( newPoint2D, newPoint3D ); float dx = newPoint2D.x() - last_point_2D_.x(); float dy = newPoint2D.y() - last_point_2D_.y(); float w = width(); float h = height(); // enable GL context makeCurrent(); // move in z direction if ( (_event->state() & LeftButton) && (_event->state() & MidButton)) { value_y = radius_ * dy * 3.0 / h; translate(Vec3f(0.0, 0.0, value_y)); } // move in x,y direction else if (_event->state() & MidButton) { float z = - (modelview_matrix_[ 2]*center_[0] + modelview_matrix_[ 6]*center_[1] + modelview_matrix_[10]*center_[2] + modelview_matrix_[14]) / (modelview_matrix_[ 3]*center_[0] + modelview_matrix_[ 7]*center_[1] + modelview_matrix_[11]*center_[2] + modelview_matrix_[15]); float aspect = w / h; float near_plane = 0.01 * radius_; float top = tan(fovy()/2.0f*M_PI/180.0f) * near_plane; float right = aspect*top; translate(Vec3f( 2.0*dx/w*right/near_plane*z, -2.0*dy/h*top/near_plane*z, 0.0f)); } // rotate else if (_event->state() & LeftButton) { if (last_point_ok_) { if (newPoint_hitSphere = map_to_sphere(newPoint2D, newPoint3D)) { Vec3f axis = last_point_3D_ % newPoint3D; float cos_angle = (last_point_3D_ | newPoint3D); if ( fabs(cos_angle) < 1.0 ) { float angle = 2.0 * acos( cos_angle ) * 180.0 / M_PI; rotate( axis, angle ); } } } } // remember this point last_point_2D_ = newPoint2D; last_point_3D_ = newPoint3D; last_point_ok_ = newPoint_hitSphere; // trigger redraw updateGL();}//----------------------------------------------------------------------------voidQGLViewerWidget::mouseReleaseEvent( QMouseEvent* _event ){ last_point_ok_ = false;}//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -