00001 #include "myglwidget.h"
00002 #include <vcg\space\tetra3.h>
00003 #include <vcg\space\point3.h>
00004 #include "mainframe.h"
00005
00006 extern MyTetraMesh *tm;
00007 extern TetraStats<MyTetraMesh> Stats;
00008
00009
00010 bool MyGLWidget::ShowTextSimplex()
00011 {
00012 return (_ShowBar & SIMPLEX);
00013 }
00014
00015 bool MyGLWidget::ShowTextPhysics()
00016 {
00017 return (_ShowBar & PHYSICS);
00018 }
00019
00020 bool MyGLWidget::ShowTextQuality()
00021 {
00022 return (_ShowBar & QUALITY);
00023 }
00024
00025
00026 MyGLWidget::MyGLWidget( QWidget * parent, const char * name, const QGLWidget * shareWidget, WFlags f ):
00027 QGLWidget(parent, name)
00028 {
00029 Track.Reset();
00030 Track.radius= 1;
00031 WT=0;
00032 modality=3;
00033 mouse_modality=MMTrackball;
00034 _ShowBar=SIMPLEX;
00035 grabKeyboard();
00036 }
00037
00038
00039 void MyGLWidget::DrawTextInfo()
00040 {
00041 glPushAttrib(0xffffffff);
00042
00043 glEnable(GL_BLEND);
00044 glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA);
00045 glEnable(GL_LIGHTING);
00046 glEnable(GL_NORMALIZE);
00047 glEnable(GL_COLOR_MATERIAL);
00048 glDisable(GL_CLIP_PLANE0);
00049 glColor4d(0.7,0,0.7,0.6);
00050
00051 glDepthRange(0.0,0.1);
00052
00053 glBegin(GL_QUADS);
00054 glVertex3d(-0.5,-0.5,0);
00055 glVertex3d(-0.5,-0.3,0);
00056 glVertex3d(0.5,-0.3,0);
00057 glVertex3d(0.5,-0.5,0);
00058 glEnd();
00059
00060 if (Stats.TCurrent()!=0)
00061 {
00062 glBegin(GL_QUADS);
00063 glVertex3d(0.25,0.5,0);
00064 glVertex3d(0.5,0.5,0);
00065 glVertex3d(0.5,0.2,0);
00066 glVertex3d(0.25,0.2,0);
00067 glEnd();
00068 }
00069
00070
00071 renderText( (width() - 10) / 2, 15, "a" );
00072
00073 QFont f( "arial", 12 );
00074 QFontMetrics fmc( f );
00075 glColor3d(1,1,1);
00076
00077 QString str="";
00078 int level=0;
00079
00080 glDisable( GL_LIGHTING );
00081 glDisable( GL_TEXTURE_2D );
00082
00083 if (ShowTextSimplex())
00084 {
00085 level++;
00086 str.sprintf( "Tetrahedrons : %i Vertex: %i ",tm->tn,tm->vn);
00087 renderText( 20, height() - level*20, str, f );
00088 }
00089 if (ShowTextPhysics())
00090 {
00091 level++;
00092 str.sprintf( "Volume : %03f ",Stats.volume);
00093 renderText( 20, height() - level*20, str, f );
00094 }
00095 if (ShowTextQuality())
00096 {
00097 level++;
00098 str.sprintf( "Aspect Ratio : %03f ",Stats.ratio);
00099 renderText( 20, height() - level*20, str, f );
00100 }
00101
00102
00103 if (Stats.TCurrent()!=0)
00104 {
00105 str="";
00106 str.sprintf( "Volume : %03f ",Stats.TCurrent()->ComputeVolume());
00107 renderText( width()-150, 30, str, f );
00108 str.sprintf( "Aspect Ratio : %03f ",Stats.TCurrent()->AspectRatio());
00109 renderText( width()-150, 50, str, f );
00110
00111 LoadMatrix();
00112 glColor3d(1,0,0);
00113
00114 glDisable(GL_BLEND);
00115
00116 for (int i=0;i<4;i++)
00117 {
00118 double x=Stats.TCurrent()->V(i)->P().V(0);
00119 double y=Stats.TCurrent()->V(i)->P().V(1);
00120 double z=Stats.TCurrent()->V(i)->P().V(2);
00121 str.sprintf("%i",i);
00122 renderText(x,y,z,str,f);
00123 }
00124 Stats.TCurrent()->SetS();
00125 }
00126 glPopAttrib();
00127 }
00128
00129
00130 void MyGLWidget::DrawBox()
00131 {
00132 glPushAttrib(0xffffffff);
00133 glDisable(GL_COLOR_MATERIAL);
00134 glDisable(GL_LIGHT0);
00135 glDisable(GL_LIGHTING);
00136 glDisable(GL_NORMALIZE);
00137 glColor3d(1,1,1);
00138
00139 glBegin(GL_LINE_LOOP);
00140 glVertex(tm->bbox.P(0));
00141 glVertex(tm->bbox.P(1));
00142 glVertex(tm->bbox.P(3));
00143 glVertex(tm->bbox.P(2));
00144 glEnd();
00145
00146 glBegin(GL_LINE_LOOP);
00147 glVertex(tm->bbox.P(4));
00148 glVertex(tm->bbox.P(5));
00149 glVertex(tm->bbox.P(7));
00150 glVertex(tm->bbox.P(6));
00151 glEnd();
00152
00153 glBegin(GL_LINE_LOOP);
00154 glVertex(tm->bbox.P(0));
00155 glVertex(tm->bbox.P(1));
00156 glVertex(tm->bbox.P(5));
00157 glVertex(tm->bbox.P(4));
00158 glEnd();
00159
00160 glBegin(GL_LINE_LOOP);
00161 glVertex(tm->bbox.P(3));
00162 glVertex(tm->bbox.P(2));
00163 glVertex(tm->bbox.P(6));
00164 glVertex(tm->bbox.P(7));
00165 glEnd();
00166
00167 glPopAttrib();
00168 }
00169
00170 void MyGLWidget::DrawTetraMesh()
00171 {
00172
00173 switch (modality)
00174 {
00175 case 0:DrawBox();break;
00176 case 1:WT->Draw<vcg::GLW::DMWire,vcg::GLW::NMFlat,vcg::GLW::CMNone>();break;
00177 case 2:WT->Draw<vcg::GLW::DMHidden,vcg::GLW::NMFlat,vcg::GLW::CMNone>();break;
00178 case 3:WT->Draw<vcg::GLW::DMFlat,vcg::GLW::NMFlat,vcg::GLW::CMNone>();break;
00179 case 4:WT->Draw<vcg::GLW::DMFlatWire,vcg::GLW::NMFlat,vcg::GLW::CMNone>();break;
00180 case 5:WT->Draw<vcg::GLW::DMFlat,vcg::GLW::NMSmooth,vcg::GLW::CMNone>();break;
00181 case 6:WT->Draw<vcg::GLW::DMSmallTetra,vcg::GLW::NMFlat,vcg::GLW::CMNone>();break;
00182 }
00183 }
00184
00185 void MyGLWidget::SaveMatrix()
00186 {
00187 glGetDoublev(GL_PROJECTION_MATRIX ,projection);
00188 glGetDoublev(GL_MODELVIEW_MATRIX ,modelMatrix);
00189 }
00190
00191 void MyGLWidget::LoadMatrix()
00192 {
00193 glMatrixMode(GL_PROJECTION);
00194 glLoadMatrixd(projection);
00195 glMatrixMode(GL_MODELVIEW);
00196 glLoadMatrixd(modelMatrix);
00197 }
00198
00199 void MyGLWidget::glDraw(){
00200
00201 glClearColor(0.2,0.2,0.2,1);
00202 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00203 glMatrixMode(GL_PROJECTION);
00204 glLoadIdentity();
00205 gluPerspective(45,1,0.01,20);
00206 glMatrixMode(GL_MODELVIEW);
00207 glLoadIdentity();
00208 gluLookAt(0,0,1,0,0,0,0,10,0);
00209
00210 if (tm!=0){
00211 glPushMatrix();
00212
00213 glScalef(1/tm->bbox.Diag(),1/tm->bbox.Diag(),1/tm->bbox.Diag());
00214
00215 Track.GetView();
00216 Track.Apply();
00217 Track.Draw();
00218
00219 vcg::Point3d p=tm->bbox.Center();
00220 glTranslate(-p);
00221
00222
00223
00224 if (WT==0)
00225 {
00226 WT= new vcg::GLWrapTetra<std::vector<MyTetrahedron> >(tm->tetra);
00227 WT->SetHint(vcg::GLW::HShrinkFactor, 0.8);
00228 }
00229
00230
00231
00232
00233 SaveMatrix();
00234 DrawTetraMesh();
00235 glPopMatrix();
00236 DrawTextInfo();
00237 }
00238 QGLWidget::glDraw();
00239 }
00240
00241 void MyGLWidget::resizeGL( int w, int h )
00242 {
00243
00244 glMatrixMode (GL_PROJECTION);
00245 glLoadIdentity ();
00246 float ratio=(float)w/(float)h;
00247 gluPerspective(45,ratio,1,20);
00248 _W=w;
00249 _H=h;
00250 glViewport (0, 0, (GLsizei) w, (GLsizei) h);
00251 glMatrixMode (GL_MODELVIEW);
00252 repaint();
00253
00254 }
00255
00256 void MyGLWidget::mousePressEvent ( QMouseEvent * e )
00257 {
00258 if (e->button()==Qt::LeftButton)
00259 {
00260 MyTetraMesh::TetraIterator ti;
00261 int face;
00262 switch(mouse_modality)
00263 {
00264 case MMTrackball:
00265 Track.MouseDown(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT);
00266 break;
00267
00268 case MMSection:
00269 LoadMatrix();
00270 vcg::GLPickTetra<MyTetraMesh>::PickNearestTetraFace(e->x(),_H-e->y(),*tm,ti,face);
00271 if (ti!=0)
00272 {
00274
00275
00276
00277
00278 vcg::Point3d p0=ti->V(vcg::Tetra::VofF(face,0))->P();
00279 vcg::Point3d p1=ti->V(vcg::Tetra::VofF(face,1))->P();
00280 vcg::Point3d p2=ti->V(vcg::Tetra::VofF(face,2))->P();
00281
00282
00283 MyTetraMesh::VertexType::CoordType b=(p0+p1+p2)/3.f;
00284
00285 WT->AddClipSection(p0,p1,p2);
00286 TrackClip.Reset();
00287 TrackClip.radius=1;
00288 TrackClip.center.V(0)=(float)b.V(0);
00289 TrackClip.center.V(1)=(float)b.V(1);
00290 TrackClip.center.V(2)=(float)b.V(2);
00291 mouse_modality=MMNavigateSection;
00292 TrackClip.MouseDown(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT);
00293 }
00294 break;
00295
00296 case MMNavigateSection:
00297 TrackClip.MouseDown(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT);
00298 break;
00299
00300 }
00301 }
00302
00303 else if (e->button()==Qt::RightButton)
00304 {
00305 MyTetraMesh::TetraIterator ti;
00306 LoadMatrix();
00307 WT->section.GlClip();
00308 vcg::GLPickTetra<MyTetraMesh>::PickNearestTetra(e->x(),_H-e->y(),*tm,ti);
00309 if (ti!=0)
00310 {
00311 Stats.SetTetraInfo(&*ti);
00312 }
00313 }
00314
00315 repaint();
00316 }
00317
00318 void MyGLWidget::mouseReleaseEvent(QMouseEvent * e )
00319 {
00320 Track.MouseUp(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT);
00321 repaint();
00322 }
00323
00324 void MyGLWidget::mouseMoveEvent ( QMouseEvent * e )
00325 {
00326 if (mouse_modality==MMTrackball)
00327 {
00328 Track.MouseMove(e->x(),_H-e->y());
00329 repaint();
00330 }
00331 else
00332 if ((mouse_modality==MMNavigateSection)&&(e->state() & Qt::LeftButton))
00333 {
00334 LoadMatrix();
00335 TrackClip.MouseMove(e->x(),_H-e->y());
00336 TrackClip.GetView();
00337 TrackClip.Apply();
00338 WT->section.Transform(TrackClip.track.Matrix());
00339 repaint();
00340 }
00341 }
00342
00343 void MyGLWidget::wheelEvent ( QWheelEvent * e ){
00344
00345
00346
00347
00348
00349
00350
00351 if (mouse_modality==MMNavigateSection)
00352 {
00353 const int WHEEL_DELTA =120;
00354 float delta= e->delta()/ float(WHEEL_DELTA);
00355 WT->section.Translate(delta/10);
00356
00358 TrackClip.center.V(0)=(float)WT->section.P.V(0);
00359 TrackClip.center.V(1)=(float)WT->section.P.V(1);
00360 TrackClip.center.V(2)=(float)WT->section.P.V(2);
00361
00362 repaint();
00363 }
00364 }
00365
00366
00367 void MyGLWidget::keyPressEvent(QKeyEvent *k)
00368 {
00369 if (k->key()==Qt::Key_Escape)
00370 {
00371 mouse_modality=MMTrackball;
00372 WT->ClearClipSection();
00373 }
00374 }
00375
00376 void MyGLWidget::initializeGL(){
00377
00378 GLfloat f[4]={0.2,0.2,0.2,1.f};
00379 GLfloat p[4]={3,3,5,0};
00380 glLightfv(GL_LIGHT0, GL_AMBIENT,f);
00381 glLightfv(GL_LIGHT1, GL_POSITION,p);
00382 glLightfv(GL_LIGHT1, GL_DIFFUSE,f);
00383 glLightfv(GL_LIGHT1, GL_SPECULAR,f);
00384
00385 glEnable(GL_LIGHT0);
00386 glEnable(GL_LIGHT1);
00387 glEnable(GL_LIGHTING);
00388 glEnable(GL_DEPTH_TEST);
00389 glDepthFunc(GL_LESS);
00390 glPolygonMode(GL_FRONT,GL_FILL);
00391 glEnable(GL_BACK);
00392 glCullFace(GL_BACK);
00393
00394 }