updated Added correct managment between logical and device window coords for mouse input and trackball.

Now with qt5.2 retina display correctly works
This commit is contained in:
Paolo Cignoni cignoni 2013-12-16 11:35:30 +00:00
parent 21fcee2145
commit 63c5e4cc41
2 changed files with 210 additions and 197 deletions

View File

@ -21,52 +21,55 @@
* *
****************************************************************************/
#include <GL/glew.h>
#include <QtGui>
#include <QGLWidget>
#include <wrap/gl/pick.h>
//#include <GL/glew.h>
#include "edit_align.h"
#include <QtGui>
#include <QGLWidget>
#include "AlignPairWidget.h"
#include "AlignPairDialog.h"
#include <wrap/gl/pick.h>
#include <wrap/qt/trackball.h>
#include <wrap/gl/picking.h>
#include <wrap/gl/space.h>
#include <wrap/qt/gl_label.h>
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<AlignPairDialog *>(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<vcg::Point3f>(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<AlignPairDialog *>(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<vcg::Point3f>(pointToPick[0],pointToPick[1],pp))
{
std::vector<vcg::Point3f> &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.size();++i)
if(Distance(pp,curVec[i])<bestDist)
{
std::vector<vcg::Point3f> &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.size();++i)
if(Distance(pp,curVec[i])<bestDist)
{
bestDist = Distance(pp,curVec[i]);
bestInd=i;
}
hasToDelete=false;
if(bestInd>=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<vcg::Point3f> &pointVec, vcg::Color4b color)
void AlignPairWidget::drawPickedPoints(QPainter *qp, std::vector<vcg::Point3f> &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; i<pointVec.size();++i)
{
vcg::Point3f &pt =pointVec[i];
glPointSize(5.0); glColor(vcg::Color4b::Black);
glBegin(GL_POINTS);
glVertex(pt);
glEnd();
glPointSize(3.0); glColor(color);
glBegin(GL_POINTS);
glVertex(pt);
glEnd();
renderText( pt[0],pt[1],pt[2], QString("%1").arg(i) );
}
glPopAttrib();
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; i<pointVec.size();++i)
{
vcg::Point3f &pt =pointVec[i];
glPointSize(5.0); glColor(vcg::Color4b::Black);
glBegin(GL_POINTS);
glVertex(pt);
glEnd();
glPointSize(3.0); glColor(color);
glBegin(GL_POINTS);
glVertex(pt);
glEnd();
vcg::glLabel::render(qp,pt,QString("%1").arg(i));
// renderText( pt[0],pt[1],pt[2], QString("%1").arg(i) );
}
glPopAttrib();
}
void AlignPairWidget::keyReleaseEvent (QKeyEvent * e)
{
e->ignore ();
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<AlignPairDialog *>(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 ();
}

View File

@ -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::Point3f> &, 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::Point3f> &, 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<vcg::Point3f> freePickedPointVec;
std::vector<vcg::Point3f> 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<vcg::Point3f> freePickedPointVec;
std::vector<vcg::Point3f> 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