From 63c5e4cc41c2977010a88f1aa44746a6efaebc38 Mon Sep 17 00:00:00 2001 From: Paolo Cignoni cignoni Date: Mon, 16 Dec 2013 11:35:30 +0000 Subject: [PATCH] updated Added correct managment between logical and device window coords for mouse input and trackball. Now with qt5.2 retina display correctly works --- .../edit_align/AlignPairWidget.cpp | 324 +++++++++--------- .../edit_align/AlignPairWidget.h | 83 ++--- 2 files changed, 210 insertions(+), 197 deletions(-) diff --git a/src/meshlabplugins/edit_align/AlignPairWidget.cpp b/src/meshlabplugins/edit_align/AlignPairWidget.cpp index 21d624cbc..d1453af5c 100644 --- a/src/meshlabplugins/edit_align/AlignPairWidget.cpp +++ b/src/meshlabplugins/edit_align/AlignPairWidget.cpp @@ -21,52 +21,55 @@ * * ****************************************************************************/ -#include -#include -#include -#include +//#include #include "edit_align.h" +#include +#include #include "AlignPairWidget.h" #include "AlignPairDialog.h" +#include #include #include #include +#include AlignPairWidget::AlignPairWidget (QWidget * parent) :QGLWidget (parent) { currentTrack=0; - freeMesh=0; - gluedTree=0; - tt[0]=&trackLeft; - tt[1]=&trackRight; + freeMesh=0; + gluedTree=0; + tt[0]=&trackLeft; + tt[1]=&trackRight; isUsingVertexColor = false; usePointRendering = false; - freePickedPointVec.clear(); - gluedPickedPointVec.clear(); + freePickedPointVec.clear(); + gluedPickedPointVec.clear(); - hasToPick=false; + hasToPick=false; hasToDelete=false; - pointToPick=vcg::Point2i(-1,-1); + pointToPick=vcg::Point2i(-1,-1); + setAutoFillBackground(false); + } void AlignPairWidget::initMesh(MeshNode *_freeMesh, MeshTree *_gluedTree) { - freeMesh=_freeMesh; - gluedTree=_gluedTree; - assert(freeMesh->glued==false); - assert(gluedTree->gluedNum()>0); - updateGL(); + freeMesh=_freeMesh; + gluedTree=_gluedTree; + assert(freeMesh->glued==false); + assert(gluedTree->gluedNum()>0); + update(); } void AlignPairWidget::initializeGL () { glewInit(); //needed to init extensions, used by the aligner GL window while rendering - glClearColor(0, 0, 0, 0); + glClearColor(0, 0, 0, 0); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_NORMALIZE); @@ -75,203 +78,212 @@ void AlignPairWidget::initializeGL () glEnable(GL_DEPTH_TEST); } -void AlignPairWidget::paintGL () +void AlignPairWidget::paintEvent(QPaintEvent *) { - //MeshModel * mm[2]={meshLeft,meshRight}; - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - if(freeMesh==0 || gluedTree==0) return; - - for(int i=0;i<2;++i) - { - if(i==0) - glViewport (0, 0, (GLsizei) width()/2, (GLsizei) height()); - else - glViewport (width()/2, 0, (GLsizei) width()/2, (GLsizei) height()); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(30, (AlignPairWidget::width()/2)/(float)AlignPairWidget::height(), 0.1, 100); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - gluLookAt(0,0,6, 0,0,0, 0,1,0); - tt[i]->center=vcg::Point3f(0, 0, 0); - tt[i]->radius= 1; - tt[i]->GetView(); - tt[i]->Apply(); - vcg::Box3f bb; - if(i==0) bb=freeMesh->bbox(); - else bb=gluedTree->gluedBBox(); - vcg::GLW::DrawMode localDM=vcg::GLW::DMFlat; - vcg::GLW::ColorMode localCM = vcg::GLW::CMPerMesh; - if((freeMesh->m->hasDataMask(MeshModel::MM_VERTCOLOR))&&(isUsingVertexColor)) localCM = vcg::GLW::CMPerVert; - if((freeMesh->m->cm.fn==0)||(usePointRendering)) localDM=vcg::GLW::DMPoints; - glPushMatrix(); - bool allowScaling = qobject_cast(parent())->allowScalingCB->isChecked(); - if(allowScaling) vcg::glScale(3.0f/bb.Diag()); - else vcg::glScale(3.0f/gluedTree->gluedBBox().Diag()); - vcg::glTranslate(-bb.Center()); - if(i==0) - { - freeMesh->m->render(localDM,localCM,vcg::GLW::TMNone); - drawPickedPoints(freePickedPointVec,vcg::Color4b(vcg::Color4b::Red)); - } else { - foreach(MeshNode *mn, gluedTree->nodeList) - if(mn->glued && mn != freeMesh && mn->m->visible) mn->m->render(localDM,localCM,vcg::GLW::TMNone); - drawPickedPoints(gluedPickedPointVec,vcg::Color4b(vcg::Color4b::Blue)); - } - - int pickSide= ( pointToPick[0] < (width()/2) )? 0 : 1; - if(hasToPick && pickSide==i) - { - vcg::Point3f pp; - hasToPick=false; - if(vcg::Pick(pointToPick[0],pointToPick[1],pp)) + QPainter painter(this); + painter.beginNativePainting(); + makeCurrent(); + if(!isValid() )return; + + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if(freeMesh==0 || gluedTree==0) return; + + for(int i=0;i<2;++i) + { + if(i==0) + glViewport (0, 0, (GLsizei) QTLogicalToDevice(this,width()/2), (GLsizei) QTLogicalToDevice(this,height())); + else + glViewport (QTLogicalToDevice(this,width()/2), 0, (GLsizei) QTLogicalToDevice(this,width()/2), (GLsizei) QTLogicalToDevice(this,height())); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(30, (AlignPairWidget::width()/2)/(float)AlignPairWidget::height(), 0.1, 100); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0,0,6, 0,0,0, 0,1,0); + tt[i]->center=vcg::Point3f(0, 0, 0); + tt[i]->radius= 1; + tt[i]->GetView(); + tt[i]->Apply(); + vcg::Box3f bb; + if(i==0) bb=freeMesh->bbox(); + else bb=gluedTree->gluedBBox(); + vcg::GLW::DrawMode localDM=vcg::GLW::DMFlat; + vcg::GLW::ColorMode localCM = vcg::GLW::CMPerMesh; + if((freeMesh->m->hasDataMask(MeshModel::MM_VERTCOLOR))&&(isUsingVertexColor)) localCM = vcg::GLW::CMPerVert; + if((freeMesh->m->cm.fn==0)||(usePointRendering)) localDM=vcg::GLW::DMPoints; + glPushMatrix(); + bool allowScaling = qobject_cast(parent())->allowScalingCB->isChecked(); + if(allowScaling) vcg::glScale(3.0f/bb.Diag()); + else vcg::glScale(3.0f/gluedTree->gluedBBox().Diag()); + vcg::glTranslate(-bb.Center()); + if(i==0) + { + freeMesh->m->render(localDM,localCM,vcg::GLW::TMNone); + drawPickedPoints(&painter, freePickedPointVec,vcg::Color4b(vcg::Color4b::Red)); + } else { + foreach(MeshNode *mn, gluedTree->nodeList) + if(mn->glued && mn != freeMesh && mn->m->visible) mn->m->render(localDM,localCM,vcg::GLW::TMNone); + drawPickedPoints(&painter, gluedPickedPointVec,vcg::Color4b(vcg::Color4b::Blue)); + } + + int pickSide= ( pointToPick[0] < QTLogicalToDevice(this,(width()/2)) )? 0 : 1; + if(hasToPick && pickSide==i) + { + vcg::Point3f pp; + hasToPick=false; + if(vcg::Pick(pointToPick[0],pointToPick[1],pp)) + { + std::vector &curVec = pickSide?gluedPickedPointVec:freePickedPointVec; + + qDebug("Picked point %i %i -> %f %f %f",pointToPick[0],pointToPick[1],pp[0],pp[1],pp[2]); + + if(hasToDelete) + { + int bestInd = -1; + double bestDist =10e100; + for(int i=0;i &curVec = pickSide?gluedPickedPointVec:freePickedPointVec; - - qDebug("Picked point %i %i -> %f %f %f",pointToPick[0],pointToPick[1],pp[0],pp[1],pp[2]); - - if(hasToDelete) - { - int bestInd = -1; - double bestDist =10e100; - for(int i=0;i=0) - curVec.erase(curVec.begin()+bestInd); - } - else curVec.push_back(pp); - hasToPick=false; - update(); + bestDist = Distance(pp,curVec[i]); + bestInd=i; } - } - glPopMatrix(); - tt[i]->DrawPostApply(); - } + hasToDelete=false; + if(bestInd>=0) + curVec.erase(curVec.begin()+bestInd); + } + else curVec.push_back(pp); + hasToPick=false; + update(); + } + } + glPopMatrix(); + tt[i]->DrawPostApply(); + } + doneCurrent(); + painter.endNativePainting(); } -void AlignPairWidget::drawPickedPoints(std::vector &pointVec, vcg::Color4b color) +void AlignPairWidget::drawPickedPoints(QPainter *qp, std::vector &pointVec, vcg::Color4b color) { - glPushAttrib(GL_ENABLE_BIT | GL_POINT_BIT | GL_CURRENT_BIT | GL_DEPTH_BUFFER_BIT); - glDisable(GL_LIGHTING); - glDisable(GL_TEXTURE); - glDepthFunc(GL_ALWAYS); - //glDisable(GL_DEPTH_TEST); - for(uint i=0; iignore (); - + for(int i=0;i<2;++i) - { - if (e->key () == Qt::Key_Control) tt[i]->ButtonUp (QT2VCG (Qt::NoButton, Qt::ControlModifier)); - if (e->key () == Qt::Key_Shift) tt[i]->ButtonUp (QT2VCG (Qt::NoButton, Qt::ShiftModifier)); - if (e->key () == Qt::Key_Alt) tt[i]->ButtonUp (QT2VCG (Qt::NoButton, Qt::AltModifier)); - } - updateGL (); + { + if (e->key () == Qt::Key_Control) tt[i]->ButtonUp (QT2VCG (Qt::NoButton, Qt::ControlModifier)); + if (e->key () == Qt::Key_Shift) tt[i]->ButtonUp (QT2VCG (Qt::NoButton, Qt::ShiftModifier)); + if (e->key () == Qt::Key_Alt) tt[i]->ButtonUp (QT2VCG (Qt::NoButton, Qt::AltModifier)); + } + update (); } void AlignPairWidget::keyPressEvent (QKeyEvent * e) { e->ignore (); for(int i=0;i<2;++i) - { + { if (e->key () == Qt::Key_Control) tt[i]->ButtonDown (QT2VCG (Qt::NoButton, Qt::ControlModifier)); - if (e->key () == Qt::Key_Shift) tt[i]->ButtonDown (QT2VCG (Qt::NoButton, Qt::ShiftModifier)); - if (e->key () == Qt::Key_Alt) tt[i]->ButtonDown (QT2VCG (Qt::NoButton, Qt::AltModifier)); - } - updateGL (); + if (e->key () == Qt::Key_Shift) tt[i]->ButtonDown (QT2VCG (Qt::NoButton, Qt::ShiftModifier)); + if (e->key () == Qt::Key_Alt) tt[i]->ButtonDown (QT2VCG (Qt::NoButton, Qt::AltModifier)); + } + update(); } void AlignPairWidget::mouseDoubleClickEvent(QMouseEvent * e) { - hasToPick=true; - pointToPick=vcg::Point2i(e->x(), height() -e->y()); + hasToPick=true; + pointToPick=vcg::Point2i(QT2VCG_X(this,e), QT2VCG_Y(this,e)); if(e->modifiers()&Qt::ControlModifier) hasToDelete=true; - updateGL (); + update(); } void AlignPairWidget::mousePressEvent (QMouseEvent * e) { e->accept (); setFocus (); - int index = e->x () < ( width() /2) ? 0 : 1 ; - currentTrack = tt[index]; - currentTrack->MouseDown (e->x (), height () - e->y (), QT2VCG (e->button (), e->modifiers ())); + int index = e->x () < ( width() /2) ? 0 : 1 ; + currentTrack = tt[index]; + currentTrack->MouseDown (QT2VCG_X(this,e), QT2VCG_Y(this,e), QT2VCG (e->button (), e->modifiers ())); } void AlignPairWidget::mouseMoveEvent (QMouseEvent * e) { - if(!currentTrack) + if(!currentTrack) { qDebug("Warning useless mousemove"); return; - } + } if(e->buttons()&Qt::RightButton) { float lx,ly; lx = (e->x() / (float(width())/2.0f)) - 1.0; ly = ((height()-e->y()) / (float(height())/2.0f)) - 1.0; - float lightPosF[]={lx,ly,1.0,0.0}; + float lightPosF[]={lx,ly,1.0,0.0}; glPushMatrix(); glLoadIdentity(); - glLightfv(GL_LIGHT0,GL_POSITION,lightPosF); + glLightfv(GL_LIGHT0,GL_POSITION,lightPosF); glPopMatrix(); - updateGL (); + update(); } if (e->buttons()&Qt::LeftButton) { - currentTrack->MouseMove (e->x (), height () - e->y ()); - updateGL (); + currentTrack->MouseMove (QT2VCG_X(this,e), QT2VCG_Y(this,e)); + update(); } } void AlignPairWidget::mouseReleaseEvent (QMouseEvent * e) { - if(!currentTrack) { - qDebug("Warning useless mouse release"); - return; - } - currentTrack->MouseUp (e->x (), height () - e->y (), QT2VCG (e->button (), e->modifiers ())); - currentTrack=0; + if(!currentTrack) { + qDebug("Warning useless mouse release"); + return; + } + currentTrack->MouseUp (QT2VCG_X(this,e), QT2VCG_Y(this,e), QT2VCG (e->button (), e->modifiers ())); + currentTrack=0; } void AlignPairWidget::wheelEvent (QWheelEvent * e) { const int WHEEL_STEP = 120; AlignPairDialog * dd= qobject_cast(parent()); - if(dd->allowScalingCB->isChecked()) - { - int index = e->x () < ( width() /2) ? 0 : 1 ; - tt[index]->MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ())); - } - else - { - tt[0]->MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ())); - tt[1]->MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ())); - } - updateGL (); + if(dd->allowScalingCB->isChecked()) + { + int index = e->x () < ( width() /2) ? 0 : 1 ; + tt[index]->MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ())); + } + else + { + tt[0]->MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ())); + tt[1]->MouseWheel (e->delta () / float (WHEEL_STEP), QTWheel2VCG (e->modifiers ())); + } + update (); } diff --git a/src/meshlabplugins/edit_align/AlignPairWidget.h b/src/meshlabplugins/edit_align/AlignPairWidget.h index 9cba1f3bc..98329b286 100644 --- a/src/meshlabplugins/edit_align/AlignPairWidget.h +++ b/src/meshlabplugins/edit_align/AlignPairWidget.h @@ -8,7 +8,7 @@ * \ * * All rights reserved. * * * -* This program is free software; you can redistribute it and/or modify * +* This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * @@ -35,53 +35,54 @@ class MeshNode; class AlignPairWidget: public QGLWidget { - Q_OBJECT + Q_OBJECT public: - AlignPairWidget (QWidget * parent = 0); - public slots: - /// widget-based user interaction slots + AlignPairWidget (QWidget * parent = 0); + public slots: + /// widget-based user interaction slots signals: - /// signal for setting the statusbar message - void setStatusBar(QString message); + /// signal for setting the statusbar message + void setStatusBar(QString message); protected: - /// opengl initialization and drawing calls - void initializeGL (); - void paintGL (); - /// keyboard and mouse event callbacks - void keyReleaseEvent(QKeyEvent * e); - void keyPressEvent(QKeyEvent * e); - void mousePressEvent(QMouseEvent*e); - void mouseMoveEvent(QMouseEvent*e); - void mouseReleaseEvent(QMouseEvent*e); - void wheelEvent(QWheelEvent*e); - void mouseDoubleClickEvent(QMouseEvent * e); - void drawPickedPoints(std::vector &, vcg::Color4b color); + /// opengl initialization and drawing calls + void initializeGL (); + void paintEvent(QPaintEvent *); +// void paintGL (); + /// keyboard and mouse event callbacks + void keyReleaseEvent(QKeyEvent * e); + void keyPressEvent(QKeyEvent * e); + void mousePressEvent(QMouseEvent*e); + void mouseMoveEvent(QMouseEvent*e); + void mouseReleaseEvent(QMouseEvent*e); + void wheelEvent(QWheelEvent*e); + void mouseDoubleClickEvent(QMouseEvent * e); + void drawPickedPoints(QPainter *qp, std::vector &, vcg::Color4b color); private: - /// the active mesh instance - MeshNode* freeMesh; - MeshTree* gluedTree; + /// the active mesh instance + MeshNode* freeMesh; + MeshTree* gluedTree; - /// the active manipulator - vcg::Trackball trackLeft,trackRight; - vcg::Trackball* tt[2]; - vcg::Trackball* currentTrack; -public: - std::vector freePickedPointVec; - std::vector gluedPickedPointVec; - - /// mesh data structure initializer - bool hasToPick; - bool hasToDelete; - vcg::Point2i pointToPick; - - // use mesh vertex colors - bool isUsingVertexColor; - - // force point rendering - bool usePointRendering; + /// the active manipulator + vcg::Trackball trackLeft,trackRight; + vcg::Trackball* tt[2]; + vcg::Trackball* currentTrack; public: - void initMesh(MeshNode *left, MeshTree *right); + std::vector freePickedPointVec; + std::vector gluedPickedPointVec; + + /// mesh data structure initializer + bool hasToPick; + bool hasToDelete; + vcg::Point2i pointToPick; + + // use mesh vertex colors + bool isUsingVertexColor; + + // force point rendering + bool usePointRendering; +public: + void initMesh(MeshNode *left, MeshTree *right); }; #endif