00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
00049 xRot = INIT_X;
00050 yRot = INIT_Y;
00051 zRot = INIT_Z;
00052 drawAble = false;
00053 mousePoint = -1;
00054 depth = -1.0f;
00055
00056
00057 avgX = 0.0f;
00058 avgY = 0.0f;
00059 avgZ = 0.0f;
00060
00061
00062 bColor = QColor(BR*255, BG*255, BB*255);
00063 pointColor = QColor(0, 0, 255);
00064 initColor = true;
00065
00066
00067 movingMouse = false;
00068 bounding = true;
00069 cameraEnable = true;
00070 movingClear = false;
00071 pointDrawn = true;
00072 cubeDrawn = false;
00073 cubeWidth = 3;
00074
00075
00076 mainWindow = qobject_cast<QMainWindow *>(parentWidget());
00077
00078
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;
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
00227 glTranslated(0.0, 0.0, depth);
00228
00229
00230
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
00244 glColor3f(0.0f,0.0f,1.0f);
00245
00246
00247 if( drawAble ){
00248
00249
00250 if(bounding){
00251
00252 glBegin(GL_LINES);
00253 glVertex3f( maxX, maxY, minZ);
00254 glVertex3f( minX, maxY, minZ);
00255
00256 glVertex3f( minX, maxY, maxZ);
00257 glVertex3f( maxX, maxY, maxZ);
00258
00259 glVertex3f( maxX, minY, maxZ);
00260 glVertex3f( minX, minY, maxZ);
00261
00262 glVertex3f( minX, minY, minZ);
00263 glVertex3f( maxX, minY, minZ);
00264
00265 glVertex3f( maxX, maxY, maxZ);
00266 glVertex3f( maxX, minY, maxZ);
00267
00268 glVertex3f( minX, minY, maxZ);
00269 glVertex3f( minX, maxY, maxZ);
00270
00271 glVertex3f( maxX, minY, minZ);
00272 glVertex3f( maxX, minY, maxZ);
00273
00274 glVertex3f( minX, maxY, minZ);
00275 glVertex3f( minX, maxY, maxZ);
00276
00277 glVertex3f( minX, minY, minZ);
00278 glVertex3f( minX, maxY, minZ);
00279
00280 glVertex3f( minX, minY, minZ);
00281 glVertex3f( minX, minY, maxZ);
00282
00283 glVertex3f( maxX, maxY, minZ);
00284 glVertex3f( maxX, maxY, maxZ);
00285
00286 glVertex3f( maxX, maxY, minZ);
00287 glVertex3f( maxX, minY, minZ);
00288
00289 glEnd();
00290
00291 }
00292
00293
00294 if( ! ( movingClear && movingMouse ) ){
00295
00296 if( pointDrawn )
00297 glPointSize( POINT_SIZE );
00298 else if( cubeDrawn )
00299 glPointSize( float( cubeWidth ));
00300
00301
00302 glBegin(GL_POINTS);
00303 if( fileReader->getEncoding() == 0 ){
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{
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
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
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
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
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
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
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
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
00402
00403
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
00473 int deltaMoved = we->delta();
00474 if( deltaMoved < 0 )
00475 depth -= 0.2f;
00476 else
00477 depth += 0.2f;
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 }