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 "qv3dcanvas.h"
00032 #include <QTimer>
00033 #define GL_VIEW_ASPECT 1.333
00034
00035 #ifndef DOXYGEN_IGNORE_THIS
00036 QV3DCanvas::QV3DCanvas( const QString &title, const double zoom, bool dr_center, const QColor &backgroundColor, QWidget* parent): QGLWidget(parent),
00037 trackballQuat(QVQuaternion::trackball(0.0, 0.0, 0.0, 0.0)),
00038 cx(0), cy(0), cz(0), ambientLightR(1.0), ambientLightG(1.0), ambientLightB(1.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
00102 glMatrixMode(GL_PROJECTION);
00103 glLoadIdentity();
00104
00105
00106 gluPerspective(fov, (float)size().width()/(float)size().height(), 0.25, 100*zoom);
00107
00108
00109 glMatrixMode(GL_MODELVIEW);
00110 glLoadIdentity();
00111
00112
00113 qglClearColor(backgroundColor);
00114
00115
00116 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00117
00118
00119 glEnable(GL_LIGHTING);
00120
00121
00122 const GLfloat ambientLight[4] = {ambientLightR, ambientLightG, ambientLightB, 1.0 };
00123 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
00124
00125 glTranslatef(0,0,-8*zoom);
00126 glMultMatrixd(QVMatrix(trackballQuat).getReadData());
00127 glTranslatef(cx,cy,cz);
00128
00129 display();
00130
00131 viewer();
00132
00133 if(dr_center)
00134 draw_center_of_rotation();
00135
00136 glFlush();
00137 }
00138
00139 void QV3DCanvas::resizeGL( int w, int h )
00140 {
00141 glViewport(0,0,w,h);
00142 reshape(w,h);
00143
00144 glScaled((GLdouble)0.5,(GLdouble)0.5,(GLdouble)0.5);
00145
00146 viewer();
00147
00148 glFlush();
00149 }
00150
00154
00155 void QV3DCanvas::mousePressEvent(QMouseEvent *event)
00156 {
00157 beginx = event->x();
00158 beginy = event->y();
00159 if(event->button() == Qt::LeftButton) {
00160 pressedleft = TRUE;
00161 } else if(event->button() == Qt::RightButton) {
00162 pressedright = TRUE;
00163 }
00164 }
00165
00166 void QV3DCanvas::mouseReleaseEvent(QMouseEvent *event)
00167 {
00168 if(event->button() == Qt::LeftButton) {
00169 pressedleft = FALSE;
00170 } else if(event->button() == Qt::RightButton) {
00171 pressedright = FALSE;
00172 }
00173 }
00174
00175 void QV3DCanvas::mouseMoveEvent(QMouseEvent *event)
00176 {
00177 int x,y;
00178
00179 x = (int) event->x();
00180 y = (int) event->y();
00181
00182 if (pressedleft) {
00183 QVQuaternion spinQuat = QVQuaternion::trackball(
00184 (2.0*beginx - size().width()) / size().width(),
00185 (size().height() - 2.0*beginy) / size().height(),
00186 (2.0*x - size().width()) / size().width(),
00187 (size().height() - 2.0*y) / size().height());
00188
00189 trackballQuat = spinQuat * trackballQuat;
00190 updateGL();
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 beginx = x;
00202 beginy = y;
00203 }
00204
00205 void QV3DCanvas::wheelEvent(QWheelEvent *event)
00206 {
00207 zoom *= pow(0.9995,event->delta());
00208 updateGL();
00209 }
00210
00211 void QV3DCanvas::keyPressEvent(QKeyEvent *event)
00212 {
00213
00214 switch(event->key()) {
00215 case Qt::Key_Left:
00216 cx -= 0.1;
00217 break;
00218 case Qt::Key_Right:
00219 cx += 0.1;
00220 break;
00221 case Qt::Key_Up:
00222 cy += 0.1;
00223 break;
00224 case Qt::Key_Down:
00225 cy -= 0.1;
00226 break;
00227 case Qt::Key_PageUp:
00228 cz += 0.1;
00229 break;
00230 case Qt::Key_PageDown:
00231 cz -= 0.1;
00232 break;
00233 case 'C':
00234 dr_center = not dr_center;
00235 break;
00236
00237
00238
00239 }
00240
00241 updateGL();
00242 }
00243
00244 void QV3DCanvas::closeEvent(QCloseEvent * event)
00245 {
00246 Q_UNUSED(event);
00247 emit closed();
00248 }
00249
00251 #include <iostream>
00252 void QV3DCanvas::viewer()
00253 {
00254 qDebug() << "QVImageCanvas::viewer()";
00255 readInputProperties();
00256
00257
00258 foreach(QString name, getPropertyList())
00259 if (getPropertyFlags(name) & inputFlag)
00260 {
00261
00262 if (isType< QV3DPolylineF >(name))
00263 draw( getPropertyValue< QV3DPolylineF >(name),
00264 getPropertyValue<QColor>("Color for " + name),
00265 getPropertyValue<double>("Size for " + name));
00266
00267 else if (isType< QList<QV3DPointF> >(name))
00268 draw( getPropertyValue< QList<QV3DPointF> >(name),
00269 getPropertyValue<QColor>("Color for " + name),
00270 getPropertyValue<double>("Size for " + name));
00271
00272 else if (isType< QList<QV3DPolylineF> >(name))
00273 foreach(QV3DPolylineF polyline, getPropertyValue< QList<QV3DPolylineF> >(name))
00274 draw( polyline,
00275 getPropertyValue<QColor>("Color for " + name));
00276 }
00277
00278 foreach(QV3DModel *model, models)
00279 model->updatePaint(*this);
00280
00281 qDebug() << "QVImageCanvas::viewer() -> return";
00282 }
00283
00284 void QV3DCanvas::draw(const QV3DPolylineF &qv3DPolyline, const QColor color, const double size)
00285 {
00286 glPointSize(size);
00287 glBegin(GL_LINES);
00288 qglColor(color);
00289 for (int i = 1; i < qv3DPolyline.size(); i++)
00290 {
00291 glVertex3f(qv3DPolyline[i].x(), qv3DPolyline[i].y(), qv3DPolyline[i].z());
00292 glVertex3f(qv3DPolyline[i-1].x(), qv3DPolyline[i-1].y(), qv3DPolyline[i-1].z());
00293 }
00294 glEnd();
00295 }
00296
00297 #include <GL/glu.h>
00298 void QV3DCanvas::draw(const QList<QV3DPointF> &qv3DPointList, const QColor color, const double size)
00299 {
00300 foreach(QV3DPointF point, qv3DPointList)
00301 QV3DEllipsoid(color, size, size, size, point.x(), point.y(), point.z(), 10, 10).updatePaint(*this);
00302 }
00303
00304 bool QV3DCanvas::linkUnspecifiedInputProperty(QVPropertyContainer *sourceContainer, QString sourcePropName, LinkType linkType)
00305 {
00306 if (linkType == SynchronousLink)
00307 {
00308 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedInputProperty():"
00309 << " the linkType must be AsynchronousLink, the link will not be done"
00310 << std::endl;
00311 return false;
00312 }
00313
00314 QVProcessingBlock* block;
00315 if((block = dynamic_cast<QVProcessingBlock*>(sourceContainer)) != NULL)
00316 {
00317 if ( block->isType< QV3DPolylineF >(sourcePropName) ||
00318 block->isType< QList<QV3DPointF> >(sourcePropName) ||
00319 block->isType< QList<QV3DPolylineF> >(sourcePropName) )
00320 {
00321 addPropertyFromQVariant(sourcePropName, inputFlag, block->getPropertyQVariantValue(sourcePropName), block->getPropertyInfo(sourcePropName));
00322 addProperty<QColor>("Color for " + sourcePropName, inputFlag, getNextColor(), QString("Color for object ") + sourcePropName);
00323 addProperty<double>("Size for " + sourcePropName, inputFlag, 1, QString("Size for object ") + sourcePropName);
00324 std::cout << "QV3DCanvas: Added property 'Color for " << qPrintable(sourcePropName) << "'" << std::endl;
00325 std::cout << "QV3DCanvas: Added property 'Size for " << qPrintable(sourcePropName) << "'" << std::endl;
00326 }
00327 bool result = block->linkProperty(sourcePropName, this, sourcePropName ,QVProcessingBlock::AsynchronousLink);
00328
00329 return result;
00330 }
00331 else
00332 {
00333 std::cerr << "ERROR: QVImageCanvas::linkUnspecifiedInputProperty(): the sourceContainer container must be a QVProcessingBlock, the link will not be done" << std::endl;
00334 return false;
00335 }
00336
00337 }
00338
00339 void QV3DEllipsoid::paint(QV3DCanvas &glWidget)
00340 {
00341 glWidget.qglColor(color);
00342
00343 for(int i = 0; i <= lats; i++)
00344 {
00345 double lat0 = M_PI * (-0.5 + (double) (i - 1) / lats);
00346 double z0 = sin(lat0);
00347 double zr0 = cos(lat0);
00348
00349 double lat1 = M_PI * (-0.5 + (double) i / lats);
00350 double z1 = sin(lat1);
00351 double zr1 = cos(lat1);
00352
00353 glBegin(GL_QUAD_STRIP);
00354 for(int j = 0; j <= longs; j++)
00355 {
00356 double lng = 2 * M_PI * (double) (j - 1) / longs;
00357 double x = cos(lng);
00358 double y = sin(lng);
00359
00360 glNormal3f(rx * x * zr0 + cx, ry * y * zr0 + cy, rz * z0 + cz);
00361 glVertex3f(rx * x * zr0 + cx, ry * y * zr0 + cy, rz * z0 + cz);
00362 glNormal3f(rx * x * zr1 + cx, ry * y * zr1 + cy, rz * z1 + cz);
00363 glVertex3f(rx * x * zr1 + cx, ry * y * zr1 + cy, rz * z1 + cz);
00364 }
00365 glEnd();
00366 }
00367 };
00368
00369
00370 #endif
00371