#include "myglwidget.h" #include #include extern MyTetraMesh *tm; extern TetraStats Stats; bool MyGLWidget::ShowTextSimplex() { return (_ShowBar & SIMPLEX); } bool MyGLWidget::ShowTextPhysics() { return (_ShowBar & PHYSICS); } bool MyGLWidget::ShowTextQuality() { return (_ShowBar & QUALITY); } MyGLWidget::MyGLWidget( QWidget * parent, const char * name, const QGLWidget * shareWidget, WFlags f ): QGLWidget(parent, name) { Track.Reset(); Track.radius= 1; WT=0; modality=3; mouse_modality=MMTrackball; _ShowBar=SIMPLEX; } void MyGLWidget::DrawTextInfo() { glPushAttrib(0xffffffff); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); glEnable(GL_COLOR_MATERIAL); glDisable(GL_CLIP_PLANE0); glColor4d(0.7,0,0.7,0.6); glDepthRange(0.0,0.1); glBegin(GL_QUADS); glVertex3d(-0.5,-0.5,0); glVertex3d(-0.5,-0.3,0); glVertex3d(0.5,-0.3,0); glVertex3d(0.5,-0.5,0); glEnd(); if (Stats.TCurrent()!=0) { glBegin(GL_QUADS); glVertex3d(0.25,0.5,0); glVertex3d(0.5,0.5,0); glVertex3d(0.5,0.2,0); glVertex3d(0.25,0.2,0); glEnd(); } renderText( (width() - 10) / 2, 15, "a" ); QFont f( "arial", 8 ); QFontMetrics fmc( f ); glColor3d(1,1,1); QString str=""; int level=0; glDisable( GL_LIGHTING ); glDisable( GL_TEXTURE_2D ); if (ShowTextSimplex()) { level++; str.sprintf( "Tetrahedrons : %i Vertex: %i ",tm->tn,tm->vn); renderText( 20, height() - level*20, str, f ); } if (ShowTextPhysics()) { level++; str.sprintf( "Volume : %03f ",Stats.volume); renderText( 20, height() - level*20, str, f ); } if (ShowTextQuality()) { level++; str.sprintf( "Aspect Ratio : %03f ",Stats.ratio); renderText( 20, height() - level*20, str, f ); } //at the end i draw the window for informations about a tretrahedron if (Stats.TCurrent()!=0) { str=""; str.sprintf( "Volume : %03f ",Stats.TCurrent()->ComputeVolume()); renderText( width()-150, 30, str, f ); str.sprintf( "Aspect Ratio : %03f ",Stats.TCurrent()->AspectRatio()); renderText( width()-150, 50, str, f ); LoadMatrix(); glColor3d(1,0,0); glDisable(GL_BLEND); //write values of the tetrahedron glLineWidth(0.5); glColor3d(1,0,0); for (int i=0;i<4;i++) { double x=Stats.TCurrent()->V(i)->P().V(0);//x value of vertex double y=Stats.TCurrent()->V(i)->P().V(1);//y value of vertex double z=Stats.TCurrent()->V(i)->P().V(2);//z value of vertex str.sprintf("%i",i); renderText(x,y,z,str,f); } //show the tetrahedron glBegin(GL_LINE_LOOP); for (int i=0;i<4;i++) { glVertex(Stats.TCurrent()->V(i)->P()); } glEnd(); glBegin(GL_LINE_LOOP); glVertex(Stats.TCurrent()->V(0)->P()); glVertex(Stats.TCurrent()->V(2)->P()); glEnd(); glBegin(GL_LINE_LOOP); glVertex(Stats.TCurrent()->V(1)->P()); glVertex(Stats.TCurrent()->V(3)->P()); glEnd(); //end drawing } glPopAttrib(); } void MyGLWidget::DrawBox() { glPushAttrib(0xffffffff); glDisable(GL_COLOR_MATERIAL); glDisable(GL_LIGHT0); glDisable(GL_LIGHTING); glDisable(GL_NORMALIZE); glColor3d(1,1,1); glBegin(GL_LINE_LOOP); glVertex(tm->bbox.P(0)); glVertex(tm->bbox.P(1)); glVertex(tm->bbox.P(3)); glVertex(tm->bbox.P(2)); glEnd(); glBegin(GL_LINE_LOOP); glVertex(tm->bbox.P(4)); glVertex(tm->bbox.P(5)); glVertex(tm->bbox.P(7)); glVertex(tm->bbox.P(6)); glEnd(); glBegin(GL_LINE_LOOP); glVertex(tm->bbox.P(0)); glVertex(tm->bbox.P(1)); glVertex(tm->bbox.P(5)); glVertex(tm->bbox.P(4)); glEnd(); glBegin(GL_LINE_LOOP); glVertex(tm->bbox.P(3)); glVertex(tm->bbox.P(2)); glVertex(tm->bbox.P(6)); glVertex(tm->bbox.P(7)); glEnd(); glPopAttrib(); } void MyGLWidget::DrawTetraMesh() { switch (modality) { case 0:DrawBox();break; case 1:WT->Draw();break; case 2:WT->Draw();break; case 3:WT->Draw();break; case 4:WT->Draw();break; case 5:WT->Draw();break; case 6:WT->Draw();break; } } void MyGLWidget::SaveMatrix() { glGetDoublev(GL_PROJECTION_MATRIX ,projection); glGetDoublev(GL_MODELVIEW_MATRIX ,modelMatrix); } void MyGLWidget::LoadMatrix() { glMatrixMode(GL_PROJECTION); glLoadMatrixd(projection); glMatrixMode(GL_MODELVIEW); glLoadMatrixd(modelMatrix); } void MyGLWidget::glDraw(){ glClearColor(0.2,0.2,0.2,1); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45,1,0.01,20); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(0,0,1,0,0,0,0,10,0); if (tm!=0){ glPushMatrix(); glScalef(1/tm->bbox.Diag(),1/tm->bbox.Diag(),1/tm->bbox.Diag()); Track.GetView(); Track.Apply(); Track.Draw(); vcg::Point3d p=tm->bbox.Center(); glTranslate(-p); //if not exist crete an instance of wrapper if (WT==0) { WT= new vcg::GLWrapTetra >(tm->tetra); WT->SetHint(vcg::GLW::HShrinkFactor, 0.8); } /*glGetDoublev(GL_PROJECTION_MATRIX,proj); glGetDoublev(GL_mode_MATRIX,mod); glGetDoublev(GL_PROJECTION_MATRIX,);*/ SaveMatrix(); DrawTetraMesh(); glPopMatrix(); DrawTextInfo(); } QGLWidget::glDraw(); } void MyGLWidget::resizeGL( int w, int h ) { // setup viewport, projection etc.: glMatrixMode (GL_PROJECTION); glLoadIdentity (); float ratio=(float)w/(float)h; gluPerspective(45,ratio,1,20); _W=w; _H=h; glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_MODELVIEW); repaint(); } void MyGLWidget::mousePressEvent ( QMouseEvent * e ) { if (e->button()==Qt::LeftButton) { if (mouse_modality==MMTrackball) { Track.MouseDown(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT); repaint(); } else if (mouse_modality==MMSection) { LoadMatrix(); MyTetraMesh::TetraIterator ti; vcg::GLPickTetra::PickNearestTetra(e->x(),_H-e->y(),*tm,ti); if (ti!=0) { ///find exterbnal face int face=0; while (!ti->IsBorderF(face)) face++; vcg::Point3d p0=ti->V(vcg::Tetra::VofF(face,0))->P(); vcg::Point3d p1=ti->V(vcg::Tetra::VofF(face,1))->P(); vcg::Point3d p2=ti->V(vcg::Tetra::VofF(face,2))->P(); MyTetraMesh::VertexType::CoordType b=(p0+p1+p2)/3.f; WT->AddClipSection(p0,p1,p2); TrackClip.Reset(); TrackClip.radius=1; TrackClip.center.V(0)=(float)b.V(0); TrackClip.center.V(1)=(float)b.V(1); TrackClip.center.V(2)=(float)b.V(2); mouse_modality=MMNavigateSection; TrackClip.MouseDown(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT); } } } else if (e->button()==Qt::RightButton) { MyTetraMesh::TetraIterator ti; LoadMatrix(); //WT->section.GlClip(); vcg::GLPickTetra::PickNearestTetra(e->x(),_H-e->y(),*tm,ti); if (ti!=0) { Stats.TetraInfo(&*ti); } } } void MyGLWidget::mouseReleaseEvent(QMouseEvent * e ) { Track.MouseUp(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT); repaint(); } void MyGLWidget::mouseMoveEvent ( QMouseEvent * e ) { if (mouse_modality==MMTrackball) { Track.MouseMove(e->x(),_H-e->y()); repaint(); } else if (mouse_modality==MMNavigateSection) { LoadMatrix(); TrackClip.MouseMove(e->x(),_H-e->y()); TrackClip.GetView(); TrackClip.Apply(); WT->section.Transform(TrackClip.track.Matrix()); repaint(); } } void MyGLWidget::wheelEvent ( QWheelEvent * e ){ /* if (mouse_modality==MMTrackball) { const int WHEEL_DELTA =120; Track.MouseWheel( e->delta()/ float(WHEEL_DELTA) ); repaint(); }else*/ if (mouse_modality==MMNavigateSection) { const int WHEEL_DELTA =120; float delta= e->delta()/ float(WHEEL_DELTA); WT->section.Translate(delta/10); ///for casting from double to float TrackClip.center.V(0)=(float)WT->section.P.V(0); TrackClip.center.V(1)=(float)WT->section.P.V(1); TrackClip.center.V(2)=(float)WT->section.P.V(2); repaint(); } } void MyGLWidget::keyPressEvent(QKeyEvent *k) { mouse_modality=MMTrackball; if ((k->key()==Qt::Key_Escape)&&((mouse_modality==MMNavigateSection)||(mouse_modality==MMSection))) mouse_modality=MMTrackball; } void MyGLWidget::initializeGL(){ GLfloat f[4]={0.2,0.2,0.2,1.f}; GLfloat p[4]={3,3,5,0}; glLightfv(GL_LIGHT0, GL_AMBIENT,f); glLightfv(GL_LIGHT1, GL_POSITION,p); glLightfv(GL_LIGHT1, GL_DIFFUSE,f); glLightfv(GL_LIGHT1, GL_SPECULAR,f); glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); glPolygonMode(GL_FRONT,GL_FILL); glEnable(GL_BACK); glCullFace(GL_BACK); }