00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025 #include <QMouseEvent>
00026
00027 #include <qvipp.h>
00028 #include <qvdefines.h>
00029 #include <qvmatrixalgebra.h>
00030
00031 #include <qvgui/qv3dcanvas.h>
00032 #include <QTimer>
00033 #define GL_VIEW_ASPECT 1.333
00034
00035
00036 QV3DCanvas::QV3DCanvas( const QString &title, const double zoom,
00037 bool dr_center, const QColor &backgroundColor, QWidget* parent): QGLWidget(parent),
00038 trackballQuat(QVQuaternion::trackball(0.0, 0.0, 0.0, 0.0)), cx(0), cy(0), cz(0),
00039 dr_center(dr_center), zoom(zoom), fov(45), pressedleft(FALSE), pressedright(FALSE), colorCursor(0), backgroundColor(backgroundColor)
00040 {
00041 setName(title);
00042
00043 resize(400,(int)(400/GL_VIEW_ASPECT));
00044 setWindowTitle(title);
00045
00046 QTimer *timer = new QTimer(this);
00047 connect(timer, SIGNAL(timeout()), this, SLOT(updateGL()));
00048 timer->start(1000/24);
00049
00050 show();
00051 }
00052
00053 QV3DCanvas::~QV3DCanvas ()
00054 {
00055
00056 }
00057
00058 void QV3DCanvas::initializeGL()
00059 {
00060 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00061
00062 glDisable(GL_CULL_FACE);
00063 glEnable(GL_DEPTH_TEST);
00064
00065 glEnable(GL_DITHER);
00066 glShadeModel(GL_SMOOTH);
00067 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
00068 glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
00069
00070 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00071 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00072 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
00073
00074 glEnable(GL_DEPTH_TEST);
00075 glEnable(GL_CULL_FACE);
00076 glEnable(GL_TEXTURE_2D);
00077
00078 init();
00079 }
00080
00081 void QV3DCanvas::draw_center_of_rotation()
00082 {
00083
00084 glBegin(GL_LINES);
00085 glColor3ub(255,255,0);
00086
00087 glVertex3f(cx - 0.1,cy,cz);
00088 glVertex3f(cx + 0.1,cy,cz);
00089
00090 glVertex3f(cx,cy- 0.1,cz);
00091 glVertex3f(cx,cy+ 0.1,cz);
00092
00093 glVertex3f(cx,cy,cz- 0.1);
00094 glVertex3f(cx,cy,cz+ 0.1);
00095 glEnd();
00096 }
00097
00098 #define S 15
00099 void QV3DCanvas::paintGL()
00100 {
00101 glMatrixMode(GL_PROJECTION);
00102
00103 glLoadIdentity();
00104 gluPerspective(fov,(float)size().width()/(float)size().height(),1,100*zoom);
00105 glMatrixMode(GL_MODELVIEW);
00106
00107 qglClearColor(backgroundColor);
00108 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00109
00110 glLoadIdentity();
00111
00112 glTranslatef(0,0,-4*zoom);
00113 glScaled((GLdouble)0.5/zoom,(GLdouble)0.5/zoom,(GLdouble)0.5/zoom);
00114
00115 QVMatrix M(trackballQuat);
00116 GLfloat m[4][4];
00117
00118 for (int i=0; i <4; i++)
00119 for (int j=0; j <4; j++)
00120 m[i][j] = M(i,j);
00121
00122 glMultMatrixf(&m[0][0]);
00123
00124 glRotatef(270,1,0,0);
00125
00126 glTranslatef(-cx,-cy,-cz);
00127
00128 if(dr_center)
00129 draw_center_of_rotation();
00130
00131 glScaled((GLdouble)0.5,(GLdouble)0.5,(GLdouble)0.5);
00132
00133 viewer();
00134
00135 display();
00136 }
00137
00138 void QV3DCanvas::resizeGL( int w, int h )
00139 {
00140 glViewport(0,0,w,h);
00141 reshape(w,h);
00142
00143 glScaled((GLdouble)0.5,(GLdouble)0.5,(GLdouble)0.5);
00144
00145 viewer();
00146 }
00147
00151
00152 void QV3DCanvas::mousePressEvent(QMouseEvent *event)
00153 {
00154 beginx = event->x();
00155 beginy = event->y();
00156 if(event->button() == Qt::LeftButton) {
00157 pressedleft = TRUE;
00158 } else if(event->button() == Qt::RightButton) {
00159 pressedright = TRUE;
00160 }
00161 }
00162
00163 void QV3DCanvas::mouseReleaseEvent(QMouseEvent *event)
00164 {
00165 if(event->button() == Qt::LeftButton) {
00166 pressedleft = FALSE;
00167 } else if(event->button() == Qt::RightButton) {
00168 pressedright = FALSE;
00169 }
00170 }
00171
00172 void QV3DCanvas::mouseMoveEvent(QMouseEvent *event)
00173 {
00174 int x,y;
00175
00176 x = (int) event->x();
00177 y = (int) event->y();
00178
00179 if (pressedleft) {
00180 QVQuaternion spinQuat = QVQuaternion::trackball(
00181 (2.0*beginx - size().width()) / size().width(),
00182 (size().height() - 2.0*beginy) / size().height(),
00183 (2.0*x - size().width()) / size().width(),
00184 (size().height() - 2.0*y) / size().height());
00185
00186 trackballQuat = spinQuat * trackballQuat;
00187 updateGL();
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 beginx = x;
00199 beginy = y;
00200 }
00201
00202 void QV3DCanvas::wheelEvent(QWheelEvent *event)
00203 {
00204 zoom *= pow(0.9995,event->delta());
00205 updateGL();
00206 }
00207
00208 void QV3DCanvas::keyPressEvent(QKeyEvent *event)
00209 {
00210
00211 switch(event->key()) {
00212 case Qt::Key_Left:
00213 cx -= 0.1;
00214 break;
00215 case Qt::Key_Right:
00216 cx += 0.1;
00217 break;
00218 case Qt::Key_Up:
00219 cy += 0.1;
00220 break;
00221 case Qt::Key_Down:
00222 cy -= 0.1;
00223 break;
00224 case Qt::Key_PageUp:
00225 cz += 0.1;
00226 break;
00227 case Qt::Key_PageDown:
00228 cz -= 0.1;
00229 break;
00230 case 'C':
00231 dr_center = not dr_center;
00232 break;
00233
00234
00235
00236 }
00237
00238 updateGL();
00239 }
00240
00241 void QV3DCanvas::closeEvent(QCloseEvent * event)
00242 {
00243 Q_UNUSED(event);
00244 emit closed();
00245 }
00246
00248 #include <iostream>
00249 void QV3DCanvas::viewer()
00250 {
00251 qDebug() << "QVImageCanvas::viewer()";
00252 readInputProperties();
00253
00254
00255 foreach(QString name, getPropertyList())
00256 if (getPropertyFlags(name) & inputFlag)
00257 {
00258
00259 if (isType< QV3DPolylineF >(name))
00260 draw( getPropertyValue< QV3DPolylineF >(name),
00261 getPropertyValue<QColor>("Color for " + name),
00262 getPropertyValue<double>("Size for " + name));
00263
00264 else if (isType< QList<QV3DPointF> >(name))
00265 draw( getPropertyValue< QList<QV3DPointF> >(name),
00266 getPropertyValue<QColor>("Color for " + name),
00267 getPropertyValue<double>("Size for " + name));
00268
00269 else if (isType< QList<QV3DPolylineF> >(name))
00270 foreach(QV3DPolylineF polyline, getPropertyValue< QList<QV3DPolylineF> >(name))
00271 draw( polyline,
00272 getPropertyValue<QColor>("Color for " + name));
00273 }
00274
00275 foreach(QV3DModel *model, models)
00276 model->updatePaint(*this);
00277
00278 glFlush();
00279 qDebug() << "QVImageCanvas::viewer() -> return";
00280 }
00281
00282 void QV3DCanvas::draw(const QV3DPolylineF &qv3DPolyline, const QColor color, const double size)
00283 {
00284 glPointSize(size);
00285 glBegin(GL_LINES);
00286 qglColor(color);
00287 for (int i = 1; i < qv3DPolyline.size(); i++)
00288 {
00289 glVertex3f(qv3DPolyline[i].x(), qv3DPolyline[i].y(), qv3DPolyline[i].z());
00290 glVertex3f(qv3DPolyline[i-1].x(), qv3DPolyline[i-1].y(), qv3DPolyline[i-1].z());
00291 }
00292 glEnd();
00293 }
00294
00295 #include <GL/glu.h>
00296 void QV3DCanvas::draw(const QList<QV3DPointF> &qv3DPointList, const QColor color, const double size)
00297 {
00298 glPointSize(size);
00299 glEnable(GL_POINT_SMOOTH);
00300 glBegin( GL_POINTS );
00301 qglColor(color);
00302 foreach(QV3DPointF point, qv3DPointList)
00303 glVertex3f(point.x(), point.y(), point.z());
00304 glEnd();
00305
00306 glBegin(GL_LINES);
00307 glColor3ub(color.red()/2, color.green()/2, color.blue()/2);
00308 foreach(QV3DPointF point, qv3DPointList)
00309 {
00310 glVertex3f(point.x(), point.y(), point.z());
00311 glVertex3f(point.x(), point.y(), 0);
00312 }
00313 glEnd();
00314
00315 }
00316
00317 bool QV3DCanvas::linkUnspecifiedInputProperty(QVPropertyContainer *sourceContainer, QString sourcePropName, LinkType linkType)
00318 {
00319 if (linkType == SynchronousLink)
00320 {
00321 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedInputProperty():"
00322 << " the linkType must be AsynchronousLink, the link will not be done"
00323 << std::endl;
00324 return false;
00325 }
00326
00327 QVWorker* worker;
00328 if((worker = dynamic_cast<QVWorker*>(sourceContainer)) != NULL)
00329 {
00330 if ( worker->isType< QV3DPolylineF >(sourcePropName) ||
00331 worker->isType< QList<QV3DPointF> >(sourcePropName) ||
00332 worker->isType< QList<QV3DPolylineF> >(sourcePropName) )
00333 {
00334 addPropertyFromQVariant(sourcePropName, inputFlag, worker->getPropertyQVariantValue(sourcePropName), worker->getPropertyInfo(sourcePropName));
00335 addProperty<QColor>("Color for " + sourcePropName, inputFlag, getNextColor(), QString("Color for object ") + sourcePropName);
00336 addProperty<double>("Size for " + sourcePropName, inputFlag, 1, QString("Size for object ") + sourcePropName);
00337 }
00338 bool result = worker->linkProperty(sourcePropName, this, sourcePropName ,QVWorker::AsynchronousLink);
00339
00340 return result;
00341 }
00342 else
00343 {
00344 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedInputProperty(): the sourceContainer container must be a QVWorker, the link will not be done" << std::endl;
00345 return false;
00346 }
00347
00348 }