vcglib/apps/tetraviewer/myglwidget.cpp

395 lines
8.6 KiB
C++

#include "myglwidget.h"
#include <vcg\space\tetra3.h>
#include <vcg\space\point3.h>
#include "mainframe.h"
extern MyTetraMesh *tm;
extern TetraStats<MyTetraMesh> Stats;
//extern MainFrame *wp;
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;
grabKeyboard();
}
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", 12 );
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
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);
}
Stats.TCurrent()->SetS();
}
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<vcg::GLW::DMWire,vcg::GLW::NMFlat,vcg::GLW::CMNone>();break;
case 2:WT->Draw<vcg::GLW::DMHidden,vcg::GLW::NMFlat,vcg::GLW::CMNone>();break;
case 3:WT->Draw<vcg::GLW::DMFlat,vcg::GLW::NMFlat,vcg::GLW::CMNone>();break;
case 4:WT->Draw<vcg::GLW::DMFlatWire,vcg::GLW::NMFlat,vcg::GLW::CMNone>();break;
case 5:WT->Draw<vcg::GLW::DMFlat,vcg::GLW::NMSmooth,vcg::GLW::CMNone>();break;
case 6:WT->Draw<vcg::GLW::DMSmallTetra,vcg::GLW::NMFlat,vcg::GLW::CMNone>();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<std::vector<MyTetrahedron> >(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)
{
MyTetraMesh::TetraIterator ti;
int face;
switch(mouse_modality)
{
case MMTrackball:
Track.MouseDown(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT);
break;
case MMSection:
LoadMatrix();
vcg::GLPickTetra<MyTetraMesh>::PickNearestTetraFace(e->x(),_H-e->y(),*tm,ti,face);
if (ti!=0)
{
///find external face
/*while (!ti->IsBorderF(face))
face++;*/
/*ti->SetS();*/
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();
//put the trackball on the barycenter of the face
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);
}
break;
case MMNavigateSection:
TrackClip.MouseDown(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT);
break;
}
}
else if (e->button()==Qt::RightButton)
{
MyTetraMesh::TetraIterator ti;
LoadMatrix();
WT->section.GlClip();
vcg::GLPickTetra<MyTetraMesh>::PickNearestTetra(e->x(),_H-e->y(),*tm,ti);
if (ti!=0)
{
Stats.SetTetraInfo(&*ti);
}
}
repaint();
}
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)&&(e->state() & Qt::LeftButton))
{
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)
{
if (k->key()==Qt::Key_Escape)//&&((mouse_modality==MMNavigateSection)||(mouse_modality==MMSection)))
{
mouse_modality=MMTrackball;
WT->ClearClipSection();
}
}
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);
}