00001
00002 #include <math.h>
00003 #include <iostream>
00004
00005 #include <QtCore/QFile>
00006 #include <QtGui/QMouseEvent>
00007 #include <QtGui/QMessageBox>
00008 #include <QtGui/QImage>
00009 #include <QtGui/QFileDialog>
00010
00011 #include "glarea.h"
00012 #include "cmesh.h"
00013 #include <wrap/io_trimesh/import.h>
00014 #include <wrap/io_trimesh/export.h>
00015 #include <vcg/complex/trimesh/update/normal.h>
00016 #include <vcg/complex/trimesh/update/topology.h>
00017 #include <vcg/complex/trimesh/update/flag.h>
00018
00019 #include <vcg/space/normal_extrapolation.h>
00020
00021
00022
00023
00024
00025
00026 using namespace std;
00027 using namespace vcg;
00028
00029 GLArea::GLArea(QWidget *parent): QGLWidget(parent), pivot(NULL), smooth(false), radius(1.2) {
00030
00031 tot = 1;
00032
00033 setMouseTracking(true);
00034
00035 }
00036
00037 bool GLArea::loadModel(const QString &file) {
00038
00039 updateGL();
00040 return true;
00041 }
00042 void GLArea::open() {
00043 QString file = QFileDialog::getOpenFileName(this, "Select a ply file", "", "*.ply");
00044 if(!file.size()) return;
00045 init(file, radius);
00046 }
00047
00048 void GLArea::init(QString file, float ballsize = 1.2) {
00049
00050 int err = tri::io::Importer<CMesh>::Open(mesh, file.toAscii().data());
00051 if(err) return;
00052 mesh.face.clear();
00053 mesh.fn = 0;
00054
00055
00056
00057
00058
00059
00060
00061 box = Box3f();
00062 for(int i = 0; i < mesh.vert.size(); i++)
00063 box.Add(mesh.vert[i].P());
00064
00065
00066 float r = sqrt((box.Diag()*box.Diag())/mesh.vn);
00067
00068
00069
00070 if(pivot) delete pivot;
00071 cout << "creating pibot\n";
00072
00073 NormalExtrapolation<vector<CVertex> >::ExtrapolateNormals(mesh.vert.begin(), mesh.vert.end(), 10);
00074
00075 pivot = new Pivot<CMesh>(mesh, 0, 0.1, 0);
00076
00077
00078
00079 }
00080
00081 void GLArea::save() {
00082
00083 mesh.vn = mesh.vert.size();
00084 mesh.fn = mesh.face.size();
00085 tri::io::ExporterPLY<CMesh>::Save(mesh, "prova.ply");
00086
00087 }
00088
00089 void GLArea::addFace() {
00090 pivot->addFace();
00091 updateGL();
00092
00093
00094
00095
00096
00097 }
00098
00099 void GLArea::add10Faces() {
00100 for(int i =0; i < 10; i++)
00101 if(-1 == pivot->addFace()) return;
00102
00103 updateGL();
00104 }
00105
00106
00107 void GLArea::add100Faces() {
00108 for(int i =0; i < 100; i++)
00109 if(-1 == pivot->addFace()) return;
00110 updateGL();
00111 }
00112
00113 void GLArea::add1000Faces() {
00114 for(int i =0; i < 1000; i++)
00115 if(-1 == pivot->addFace()) return;
00116 updateGL();
00117 }
00118
00119 void GLArea::addAll() {
00120 while(1) {
00121 for(int i = 0; i < 1000; i++)
00122 if(0 > pivot->addFace()) return;
00123 updateGL();
00124 }
00125 }
00126
00127 void GLArea::addTot() {
00128 for(int i = 0; i < tot; i++)
00129 if(0 > pivot->addFace()) return;
00130 updateGL();
00131 }
00132
00133
00134
00135 void GLArea::viewSmooth(bool on) {
00136 smooth = on;
00137 updateGL();
00138 }
00139 void GLArea::initializeGL() {
00140 glClearColor(1, 1, 1, 1);
00141 glEnable(GL_DEPTH_TEST);
00142 glEnable(GL_LIGHTING);
00143 glEnable(GL_LIGHT0);
00144 glEnable(GL_COLOR_MATERIAL);
00145
00146 glDisable(GL_BLEND);
00147 glEnable(GL_NORMALIZE);
00148 glDisable(GL_CULL_FACE);
00149 glCullFace(GL_BACK);
00150 glColor4f(1, 1, 1, 1);
00151
00152 glEnable(GL_LIGHTING);
00153 double st = 4;
00154 float lpos[4];
00155 lpos[0] = lpos[1] = lpos[2] = st;
00156 lpos[3] = 1;
00157 glLightfv(GL_LIGHT0, GL_POSITION, lpos);
00158
00159 float v[4] = {0.8, 0.8, 0.8, 0.0};
00160 glLightfv(GL_LIGHT0, GL_DIFFUSE, v);
00161
00162 trackball.center=Point3f(0, 0, 0);
00163 trackball.radius= 1;
00164
00165 glLoadIdentity();
00166 }
00167
00168
00169 void GLArea::resizeGL(int w, int h) {
00170 glViewport(0, 0, (GLint)w, (GLint)h);
00171 glMatrixMode(GL_PROJECTION);
00172 glLoadIdentity();
00173
00174
00175 float r = w/(float)h;
00176 gluPerspective(60, r, 1, 4);
00177
00178 glMatrixMode(GL_MODELVIEW);
00179
00180 }
00181
00182
00183 void GLArea::paintGL() {
00184
00185 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
00186
00187 glLoadIdentity();
00188 gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0);
00189
00190
00191 glPushMatrix();
00192 trackball.GetView();
00193 trackball.Apply(true);
00194
00195 Point3f c = -box.Center();
00196 float radius = 2.0f/box.Diag();
00197
00198 if(mesh.face.size()>0) {
00199 CFace &face = mesh.face[0];
00200 CVertex *v[3];
00201 v[0] = face.V(0);
00202 c=-v[0]->P();
00203 radius=radius*5;
00204 }
00205
00206 if(!pivot) return;
00207
00208 glPushMatrix();
00209 glScalef(radius, radius, radius);
00210 glTranslatef(c[0], c[1], c[2]);
00211
00212 if(pivot->front.size()>2)
00213 {
00214 glEnable(GL_LINE_SMOOTH);
00215 glColor4f(1, 0, 1, 0.1);
00216 glLineWidth(5);
00217 Pivot<CMesh>::Edgex &ee=pivot->front.front();
00218 int v0=ee.v0;
00219 int v1=ee.v1;
00220 glBegin(GL_LINES);
00221 glVertex3fv(mesh.vert[v0].P().V());
00222 glVertex3fv(mesh.vert[v1].P().V());
00223 glEnd();
00224 glLineWidth(1);
00225 }
00226 glEnable(GL_LIGHTING);
00227 glColor3f(0, 1, 0);
00228
00229
00230
00231
00232
00233 glBegin(GL_TRIANGLES);
00234 for(int i = 0; i < mesh.face.size(); i++) {
00235 CFace &face = mesh.face[i];
00236 CVertex *v[3];
00237 v[0] = face.V(0);
00238 v[1] = face.V(1);
00239 v[2] = face.V(2);
00240
00241 Point3f n = (v[1]->P()- v[0]->P()) ^ (v[2]->P() - v[0]->P());
00242
00243 glNormal3fv(&(n[0]));
00244
00245 for(int k = 0; k < 3; k++) {
00246 glVertex3fv((float *)&(v[k]->P()));
00247 }
00248 }
00249 glEnd();
00250
00251 glEnable(GL_POLYGON_OFFSET_LINE);
00252 glPolygonOffset(-3, -3);
00253 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
00254 glDisable(GL_LIGHTING);
00255 glColor3f(0, 0.5, 0);
00256
00257 glPolygonOffset(-1, -1);
00258 glBegin(GL_TRIANGLES);
00259 for(int i = 0; i < mesh.face.size(); i++) {
00260 CFace &face = mesh.face[i];
00261 CVertex *v[3];
00262 v[0] = face.V(0);
00263 v[1] = face.V(1);
00264 v[2] = face.V(2);
00265 for(int k = 0; k < 3; k++) {
00266 glVertex3fv((float *)&(v[k]->P()));
00267 }
00268 }
00269 glEnd();
00270
00271 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
00272
00273 glDisable(GL_DEPTH_TEST);
00274 glLineWidth(3.0f);
00275 glBegin(GL_LINES);
00276 for(list<Pivot<CMesh>::Edgex>::iterator k = pivot->front.begin(); k != pivot->front.end(); k++) {
00277 glColor3f(1, 0, 0);
00278 Point3f &p0 = mesh.vert[(*k).v0].P();
00279 glVertex3fv(&(p0[0]));
00280 glColor3f(0, 0, 1);
00281 Point3f &p1 = mesh.vert[(*k).v1].P();
00282 glVertex3fv(&(p1[0]));
00283
00284
00285
00286
00287
00288 }
00289 for(list<Pivot<CMesh>::Edgex>::iterator k = pivot->deads.begin(); k != pivot->deads.end(); k++) {
00290 glColor3f(0, 0, 0);
00291 Point3f &p0 = mesh.vert[(*k).v0].P();
00292 glVertex3fv(&(p0[0]));
00293 Point3f &p1 = mesh.vert[(*k).v1].P();
00294 glVertex3fv(&(p1[0]));
00295 }
00296 glEnd();
00297 glEnable(GL_DEPTH_TEST);
00298
00299 glPointSize(4.0f);
00300 glBegin(GL_POINTS);
00301 for(int i = 0; i < mesh.vert.size(); i++) {
00302 CVertex &v = mesh.vert[i];
00303 Point3f &p = v.P();
00304 if(v.IsD()) continue;
00305 if(v.IsV()) glColor3f(1, 0, 0);
00306 else if(v.IsB()) glColor3f(1, 1, 0);
00307 else continue;
00308 glVertex3f(p[0], p[1], p[2]);
00309 }
00310 glEnd();
00311 glColor3f(0, 0, 0);
00312 glPointSize(1.0f);
00313
00314 glLineWidth(1.0f);
00315 glEnable(GL_LIGHTING);
00316
00317
00318 glBegin(GL_LINES);
00319 for(int i = 0; i < mesh.vert.size(); i++) {
00320 CVertex &v = mesh.vert[i];
00321 Point3f &p = v.P();
00322 if(v.IsD()) continue;
00323 glVertex3f(p[0], p[1], p[2]);
00324 Point3f q = p + v.N();
00325 glVertex3f(q[0], q[1], q[2]);
00326 }
00327 glEnd();
00328
00329
00330
00331
00332
00333 glDisable(GL_POLYGON_OFFSET_LINE);
00334
00335
00336
00337
00338
00339 glDisable(GL_LIGHTING);
00340 glPopMatrix();
00341
00342 glScalef(radius, radius, radius);
00343 glTranslatef(c[0], c[1], c[2]);
00344 glEnable(GL_BLEND);
00345 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00346
00347 glColor3f(0.5, 0.5, 0.5);
00348 glPointSize(2);
00349 glBegin(GL_POINTS);
00350 for(int i = 0; i < mesh.vert.size(); i++) {
00351 CVertex &vert = mesh.vert[i];
00352 Point3f n = vert.N();
00353 Point3f p = vert.P();
00354 glNormal3f(n[0], n[1], n[2]);
00355 glVertex3f(p[0], p[1], p[2]);
00356 }
00357 glEnd();
00358
00359 glDisable(GL_BLEND);
00360 glPopMatrix();
00361 }
00362
00363 void GLArea::wheelEvent(QWheelEvent *e) {
00364 if(e->delta() > 0)
00365 trackball.MouseWheel(1);
00366 else
00367 trackball.MouseWheel(-1);
00368 updateGL();
00369 }
00370
00371 void GLArea::mouseMoveEvent(QMouseEvent *e) {
00372 trackball.MouseMove(e->x(), height() - e->y());
00373 updateGL();
00374 }
00375 Trackball::Button QT2VCG(Qt::MouseButton qtbt, Qt::KeyboardModifiers modifiers)
00376 {
00377 int vcgbt=Trackball::BUTTON_NONE;
00378 if(qtbt & Qt::LeftButton ) vcgbt |= Trackball::BUTTON_LEFT;
00379 if(qtbt & Qt::RightButton ) vcgbt |= Trackball::BUTTON_RIGHT;
00380 if(qtbt & Qt::MidButton ) vcgbt |= Trackball::BUTTON_MIDDLE;
00381 if(modifiers & Qt::ShiftModifier ) vcgbt |= Trackball::KEY_SHIFT;
00382 if(modifiers & Qt::ControlModifier ) vcgbt |= Trackball::KEY_CTRL;
00383 if(modifiers & Qt::AltModifier ) vcgbt |= Trackball::KEY_ALT;
00384 return Trackball::Button(vcgbt);
00385 }
00386
00387 void GLArea::keyReleaseEvent ( QKeyEvent * e )
00388 {
00389 if(e->key()==Qt::Key_Control) trackball.MouseUp(0,0, QT2VCG(Qt::NoButton, Qt::ControlModifier ) );
00390 if(e->key()==Qt::Key_Shift) trackball.MouseUp(0,0, QT2VCG(Qt::NoButton, Qt::ShiftModifier ) );
00391 if(e->key()==Qt::Key_Alt) trackball.MouseUp(0,0, QT2VCG(Qt::NoButton, Qt::AltModifier ) );
00392 }
00393
00394 void GLArea::mousePressEvent(QMouseEvent *e) {
00395 trackball.MouseDown(e->x(),height()-e->y(), QT2VCG(e->button(), e->modifiers() ) );
00396
00397
00398
00399
00400 updateGL();
00401 }
00402
00403 void GLArea::mouseReleaseEvent(QMouseEvent *e) {
00404 trackball.MouseUp(e->x(),height()-e->y(), QT2VCG(e->button(), e->modifiers() ) );
00405
00406
00407
00408
00409 }