point3dwidget.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Author:  Jaime Valls Miro <jaime.vallsmiro@eng.uts.edu.au>
00004 **          Hue Tuan Thi <huetuan.thi@uts.edu.au>, (C) 2006
00005 **
00006 ** This file is part of the S3D Viewer Project
00007 **
00008 ** This file may be used under the terms of the GNU General Public
00009 ** License version 2.0 as published by the Free Software Foundation
00010 ** and appearing in the file LICENSE.GPL included in the packaging of
00011 ** this file.  Please review the following information to ensure GNU
00012 ** General Public Licensing requirements will be met:
00013 ** http://www.trolltech.com/products/qt/opensource.html
00014 **
00015 ** If you are unsure which license is appropriate for your use, please
00016 ** review the following information:
00017 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00018 ** sales department at sales@trolltech.com.
00019 **
00020 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00021 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00022 **
00023 ****************************************************************************/
00024 
00032 #include <QtGui>
00033 #include <QtOpenGL>
00034 #include <math.h>
00035 
00036 #include "point3dwidget.h"
00037 
00045 Point3dWidget::Point3dWidget(QWidget *parent)
00046     : QGLWidget(parent)
00047 {
00048     // initiate flags and vars
00049     xRot = INIT_X;
00050     yRot = INIT_Y;
00051     zRot = INIT_Z;
00052     drawAble = false;
00053     mousePoint = -1;
00054     depth = -1.0f;
00055 
00056     // initiate average values
00057     avgX = 0.0f;
00058     avgY = 0.0f;
00059     avgZ = 0.0f;
00060 
00061     // initiate colors
00062     bColor = QColor(BR*255, BG*255, BB*255);
00063     pointColor = QColor(0, 0, 255);
00064     initColor = true;
00065 
00066     // initiate flags
00067     movingMouse = false;
00068     bounding = true;
00069     cameraEnable = true;
00070     movingClear = false;
00071     pointDrawn = true;
00072     cubeDrawn = false;
00073     cubeWidth = 3;
00074 
00075     // set main window parent
00076     mainWindow = qobject_cast<QMainWindow *>(parentWidget());
00077 
00078     // set strong focus for mouse and keyboard
00079     setFocusPolicy(Qt::StrongFocus);
00080 }
00081 
00085 Point3dWidget::~Point3dWidget()
00086 {
00087     makeCurrent();
00088 }
00089 
00095 void Point3dWidget::setXRotation(int angle)
00096 {
00097     normalizeAngle(&angle);
00098     if (angle != xRot) {
00099         xRot = angle;
00100         emit xRotationChanged(angle);
00101         updateGL();
00102     }
00103 }
00104 
00110 void Point3dWidget::setYRotation(int angle)
00111 {
00112     normalizeAngle(&angle);
00113     if (angle != yRot) {
00114         yRot = angle;
00115         emit yRotationChanged(angle);
00116         updateGL();
00117     }
00118 }
00119 
00125 void Point3dWidget::setZRotation(int angle)
00126 {
00127     normalizeAngle(&angle);
00128     if (angle != zRot) {
00129         zRot = angle;
00130         emit zRotationChanged(angle);
00131         updateGL();
00132     }
00133 }
00134 
00140 void Point3dWidget::updateFile( FileReader *fd){
00141     fileReader = fd;
00142     setDrawAble(true);
00143     minX = findMin(0);
00144     maxX = findMax(0);
00145     minY = -findMin(1);
00146     maxY = -findMax(1);
00147     minZ = -findMin(2);
00148     maxZ = -findMax(2);
00149 
00150     avgX = (minX + maxX)/2;
00151     avgY = (minY + maxY)/2;
00152     avgZ = (minZ + maxZ)/2;
00153 
00154     updateGL();
00155 }
00156 
00162 float Point3dWidget::findMin(int k){
00163     float min = 999.0f;
00164 
00165     for( int i = 0; i < fileReader->getNp(); i ++){
00166         if( fileReader->pointArray[i][k] < min )
00167             min = fileReader->pointArray[i][k];
00168     }
00169 
00170     return min;
00171 }
00172 
00178 float Point3dWidget::findMax(int k){
00179     float max = -999.0f; // large enough value
00180 
00181     for( int i = 0; i < fileReader->getNp(); i ++){
00182         if( fileReader->pointArray[i][k] > max )
00183             max = fileReader->pointArray[i][k];
00184     }
00185 
00186     return max;
00187 }
00188 
00195 void Point3dWidget::setDrawAble(bool status){
00196     drawAble = status;
00197 }
00198 
00204 void Point3dWidget::initializeGL()
00205 {
00206     glEnable(GL_DEPTH_TEST);
00207     glEnable(GL_NORMALIZE);
00208     glEnable(GL_BLEND);
00209     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00210     glClearColor(bColor.red()/255, bColor.green()/255, bColor.blue()/255, 0.0);
00211 }
00212 
00218 void Point3dWidget::paintGL()
00219 {
00220     makeCurrent();
00221     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00222     glClearColor((float)bColor.red()/255, (float)bColor.green()/255, (float)bColor.blue()/255, 0.0);
00223     glLoadIdentity();
00224     glPushMatrix();
00225 
00226     // move to init depth position
00227     glTranslated(0.0, 0.0, depth);
00228 
00229     // rotate model at specified factor
00230     // and around the model centre (by translate to avg points)
00231     glTranslated(0.0, avgY, avgZ);
00232     glRotated(xRot / 16.0, 1.0, 0.0, 0.0);
00233     glTranslated(0.0, -avgY, -avgZ);
00234 
00235     glTranslated(avgX, 0.0, avgZ);
00236     glRotated(yRot / 16.0, 0.0, 1.0, 0.0);
00237     glTranslated(-avgX, 0.0, -avgZ);
00238 
00239     glTranslated(avgX, avgY, 0.0);
00240     glRotated(zRot / 16.0, 0.0, 0.0, 1.0);
00241     glTranslated(-avgX, -avgY, 0.0);
00242 
00243     // drawing color
00244     glColor3f(0.0f,0.0f,1.0f);  // Color Blue
00245 
00246     // draw points after file is read
00247     if( drawAble ){
00248 
00249         // draw bounds first
00250         if(bounding){
00251 
00252             glBegin(GL_LINES);                    // Draw The Cube Using quads
00253                 glVertex3f( maxX, maxY, minZ);    // Top Right Of The Quad (Top)
00254                 glVertex3f( minX, maxY, minZ);    // Top Left Of The Quad (Top)
00255 
00256                 glVertex3f( minX, maxY, maxZ);    // Bottom Left Of The Quad (Top)
00257                 glVertex3f( maxX, maxY, maxZ);    // Bottom Right Of The Quad (Top)
00258 
00259                 glVertex3f( maxX, minY, maxZ);    // Top Right Of The Quad (Bottom)
00260                 glVertex3f( minX, minY, maxZ);    // Top Left Of The Quad (Bottom)
00261 
00262                 glVertex3f( minX, minY, minZ);    // Bottom Left Of The Quad (Bottom)
00263                 glVertex3f( maxX, minY, minZ);    // Bottom Right Of The Quad (Bottom)
00264 
00265                 glVertex3f( maxX, maxY, maxZ);    // Top Right Of The Quad (Front)
00266                 glVertex3f( maxX, minY, maxZ);    // Top Left Of The Quad (Front)
00267 
00268                 glVertex3f( minX, minY, maxZ);    // Bottom Left Of The Quad (Front)
00269                 glVertex3f( minX, maxY, maxZ);    // Bottom Right Of The Quad (Front)
00270 
00271                 glVertex3f( maxX, minY, minZ);    // Top Right Of The Quad (Back)
00272                 glVertex3f( maxX, minY, maxZ);    // Top Left Of The Quad (Back)
00273 
00274                 glVertex3f( minX, maxY, minZ);    // Bottom Left Of The Quad (Back)
00275                 glVertex3f( minX, maxY, maxZ);    // Bottom Right Of The Quad (Back)
00276 
00277                 glVertex3f( minX, minY, minZ);    // Top Right Of The Quad (Left)
00278                 glVertex3f( minX, maxY, minZ);    // Top Left Of The Quad (Left)
00279 
00280                 glVertex3f( minX, minY, minZ);    // Bottom Left Of The Quad (Left)
00281                 glVertex3f( minX, minY, maxZ);    // Bottom Right Of The Quad (Left)
00282 
00283                 glVertex3f( maxX, maxY, minZ);    // Top Right Of The Quad (Right)
00284                 glVertex3f( maxX, maxY, maxZ);    // Top Left Of The Quad (Right)
00285 
00286                 glVertex3f( maxX, maxY, minZ);    // Bottom Left Of The Quad (Right)
00287                 glVertex3f( maxX, minY, minZ);    // Bottom Right Of The Quad (Right)
00288 
00289             glEnd();                              // End Drawing The Cube
00290 
00291         }
00292 
00293         // if moving flag is not on when object is being moved
00294         if( ! ( movingClear && movingMouse ) ){
00295             // check whether point or cube is required for drawing
00296             if( pointDrawn )
00297                 glPointSize( POINT_SIZE );
00298             else if( cubeDrawn )
00299                 glPointSize( float( cubeWidth ));
00300 
00301             // now draw all points
00302             glBegin(GL_POINTS);
00303             if( fileReader->getEncoding() == 0 ){ // 3d points with associated image coordination
00304                 for( int i = 0; i < fileReader->getNp(); i ++){
00305                     double r = getColor( (int)fileReader->pointArray[i][3], (int)fileReader->pointArray[i][4], 0);
00306                     double g = getColor( (int)fileReader->pointArray[i][3], (int)fileReader->pointArray[i][4], 1);
00307                     double b = getColor( (int)fileReader->pointArray[i][3], (int)fileReader->pointArray[i][4], 2);
00308 
00309                     if( initColor )
00310                         glColor3d(r, g, b);
00311                     else
00312                         glColor3d(((float)pointColor.red()/255), ((float)pointColor.green()/255), ((float)pointColor.blue()/255));
00313 
00314                     glVertex3f(fileReader->pointArray[i][0], -fileReader->pointArray[i][1], -fileReader->pointArray[i][2]);
00315                 }
00316             }else{ // 3d points with their own color
00317                 for( int i = 0; i < fileReader->getNp(); i ++){
00318 
00319                     if( initColor )
00320                         glColor3f(fileReader->pointArray[i][3], fileReader->pointArray[i][4], fileReader->pointArray[i][5]);
00321                     else
00322                         glColor3d(((float)pointColor.red()/255), ((float)pointColor.green()/255), ((float)pointColor.blue()/255));
00323 
00324                     glVertex3f(fileReader->pointArray[i][0], -fileReader->pointArray[i][1], -fileReader->pointArray[i][2]);
00325                 }
00326             }
00327             glEnd();
00328         }
00329 
00330         glPointSize( POINT_SIZE );
00331 
00332         // draw Camera
00333         if( cameraEnable ){
00334             float TW = -0.2f;
00335             float UNC = -0.005f;
00336             glColor4f(1.0, 0.0, 0.0, 0.4);
00337             glBegin(GL_TRIANGLES);
00338               // top triangle
00339               glVertex3f( TW-UNC, TW+UNC, TW*3+UNC);
00340               glVertex3f( -TW+UNC, TW+UNC, TW*3+UNC);
00341               glVertex3f( 0.0, 0.0+UNC, 0.0-UNC);
00342 
00343               // right triangle
00344               glVertex3f( TW+UNC, TW-UNC, TW*3+UNC);
00345               glVertex3f( TW+UNC, -TW+UNC, TW*3+UNC);
00346               glVertex3f( 0.0+UNC, 0.0, 0.0+UNC);
00347 
00348               // bottom triangle
00349               glVertex3f( -TW-UNC, -TW-UNC, TW*3+UNC);
00350               glVertex3f( TW-UNC, -TW-UNC, TW*3+UNC);
00351               glVertex3f( 0.0, 0.0-UNC, 0.0+UNC);
00352 
00353               // left triangle
00354               glVertex3f( -TW-UNC, TW-UNC, TW*3+UNC);
00355               glVertex3f( -TW-UNC, -TW+UNC, TW*3+UNC);
00356               glVertex3f( 0.0-UNC, 0.0, 0.0+UNC);
00357             glEnd();
00358 
00359             // a line from camera center to the back of the object
00360             glColor3f(1.0,0.0,0.0);
00361             glBegin(GL_LINES);
00362                 glVertex3f(0.0, 0.0, 0.0);
00363                 glVertex3f(0.0, 0.0, maxZ);
00364             glEnd();
00365         }
00366 
00367         // mouse Point associated with reference pixel being pointed
00368         if( mousePoint >= 0 )
00369         {
00370             int i = mousePoint;
00371             float rw = 0.02;
00372             glColor3f(0.0, 1.0, 0.0);
00373             glBegin(GL_POLYGON);
00374                 glVertex3f(( fileReader->pointArray[i][0] + rw), -( fileReader->pointArray[i][1] + rw), -fileReader->pointArray[i][2]);
00375                 glVertex3f(( fileReader->pointArray[i][0] - rw), -( fileReader->pointArray[i][1] + rw), -fileReader->pointArray[i][2]);
00376                 glVertex3f(( fileReader->pointArray[i][0] - rw), -( fileReader->pointArray[i][1] - rw), -fileReader->pointArray[i][2]);
00377                 glVertex3f(( fileReader->pointArray[i][0] + rw), -( fileReader->pointArray[i][1] - rw), -fileReader->pointArray[i][2]);
00378             glEnd();
00379         }
00380     }
00381 
00382     glPopMatrix();
00383 
00384 }
00385 
00391 void Point3dWidget::setMousePoint(int mp){
00392     mousePoint = mp;
00393 }
00394 
00400 double Point3dWidget::getColor(int col, int row, int i){
00401     // x and y are in 0->255 format
00402     // obtained from reference image
00403     // to be converted to 0.0->1.0 format
00404     return (double) ( (fileReader->imagePixels[col][row][i] ) / 255.0000 );
00405 }
00406 
00412 void Point3dWidget::resizeGL(int width, int height)
00413 {
00414     int side = qMin(width, height);
00415     glViewport((width - side) / 2, (height - side) / 2, side, side);
00416     glMatrixMode(GL_PROJECTION);
00417     glLoadIdentity();
00418     glFrustum(-SIZE, +SIZE, -SIZE, SIZE, 1.0, 80.0);
00419     glMatrixMode(GL_MODELVIEW);
00420     glLoadIdentity();
00421     glTranslated(0.0, 0.0, depth);
00422 }
00423 
00429 void Point3dWidget::mousePressEvent(QMouseEvent *event)
00430 {
00431     movingMouse = true;
00432     lastPos = event->pos();
00433     updateGL();
00434 }
00435 
00441 void Point3dWidget::mouseReleaseEvent(QMouseEvent *event){
00442     movingMouse = false;
00443     updateGL();
00444 }
00445 
00451 void Point3dWidget::mouseDoubleClickEvent(QMouseEvent *event){
00452     initCamera();
00453 }
00454 
00460 void Point3dWidget::initCamera(){
00461     setXRotation(INIT_X);
00462     setYRotation(INIT_Y);
00463     setZRotation(INIT_Z);
00464 }
00465 
00471 void Point3dWidget::wheelEvent( QWheelEvent *we){
00472     // check for mouse move direction
00473     int deltaMoved = we->delta();
00474     if( deltaMoved < 0 )
00475         depth -= 0.2f; // decrease depth
00476     else
00477         depth += 0.2f; // increase depth
00478 
00479     mainWindow->statusBar()->showMessage(QString("Z coordinate %1").arg(depth));
00480 
00481     updateGL();
00482 }
00483 
00489 void Point3dWidget::mouseMoveEvent(QMouseEvent *event)
00490 {
00491     int dx = event->x() - lastPos.x();
00492     int dy = event->y() - lastPos.y();
00493 
00494     if (event->buttons() & Qt::LeftButton) {
00495         setXRotation((int) (xRot + 2.0 * dy));
00496         setYRotation((int) (yRot + 2.0 * dx));
00497     } else if (event->buttons() & Qt::RightButton) {
00498         setXRotation((int) (xRot + 2.0 * dy));
00499         setZRotation((int) (zRot + 2.0 * dx));
00500     }
00501     lastPos = event->pos();
00502 }
00503 
00509 void Point3dWidget::normalizeAngle(int *angle)
00510 {
00511     while (*angle < 0)
00512         *angle += 360 * 16;
00513     while (*angle > 360 * 16)
00514         *angle -= 360 * 16;
00515 }
00516 
00522 void Point3dWidget::keyPressEvent(QKeyEvent *e){
00523     switch( e->key() ){
00524         case Qt::Key_Right:
00525             cubeWidth ++;
00526             emit cubeWidthChanged(cubeWidth);
00527             break;
00528         case Qt::Key_Left:
00529             cubeWidth --;
00530             emit cubeWidthChanged(cubeWidth);
00531             break;
00532         case Qt::Key_Up:
00533             depth += 0.2f;
00534             mainWindow->statusBar()->showMessage(QString("Z coordinate %1").arg(depth));
00535             updateGL();
00536             break;
00537         case Qt::Key_Down:
00538             depth -= 0.2f;
00539             mainWindow->statusBar()->showMessage(QString("Z coordinate %1").arg(depth));
00540             updateGL();
00541             break;
00542         default:
00543             break;
00544     }
00545 }
00546 
00547 void Point3dWidget::dragEnterEvent(QDragEnterEvent *event)
00548 {
00549   if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
00550     if (event->source() == this) {
00551       event->setDropAction(Qt::MoveAction);
00552       event->accept();
00553     } else {
00554       event->acceptProposedAction();
00555     }
00556   } else {
00557     event->ignore();
00558   }
00559 }
00560 
00561 void Point3dWidget::dropEvent(QDropEvent *event)
00562 {
00563   if (event->mimeData()->hasFormat("application/x-dnditemdata")) {
00564     QByteArray itemData = event->mimeData()->data("application/x-dnditemdata");
00565     QDataStream dataStream(&itemData, QIODevice::ReadOnly);
00566 
00567     QPixmap pixmap;
00568     QPoint offset;
00569     dataStream >> pixmap >> offset;
00570 
00571     QLabel *newIcon = new QLabel(this);
00572     newIcon->setPixmap(pixmap);
00573     newIcon->move(event->pos() - offset);
00574     newIcon->show();
00575     newIcon->setAttribute(Qt::WA_DeleteOnClose);
00576 
00577     if (event->source() == this) {
00578       event->setDropAction(Qt::MoveAction);
00579       event->accept();
00580     } else {
00581       event->acceptProposedAction();
00582     }
00583   } else {
00584     event->ignore();
00585   }
00586 }

Generated on Mon Aug 14 10:44:20 2006 for S3DViewer by  doxygen 1.4.4