570 lines
12 KiB
C++
570 lines
12 KiB
C++
#include <SimpleGLWidget.h>
|
|
#include <qlineedit.h>
|
|
#include <qfiledialog.h>
|
|
#include <qimage.h>
|
|
#include <qdir.h>
|
|
#include <qmessagebox.h>
|
|
#include <qslider.h>
|
|
|
|
extern Segmentator *s;
|
|
|
|
SimpleGLWidget::SimpleGLWidget( QWidget * parent, const char * name, const QGLWidget * shareWidget, WFlags f ):
|
|
QGLWidget(parent, name)
|
|
{
|
|
|
|
///grabKeyboard();
|
|
_showslides=false;
|
|
blocked=false;
|
|
wire=true;
|
|
extForces=false;
|
|
intForces=false;
|
|
resultForces=false;
|
|
continue_int=false;
|
|
_numslide=0;
|
|
|
|
TrackM.center=Point3f(0,0,0);
|
|
TrackM.Reset();
|
|
TrackM.radius= 100.f;
|
|
|
|
TrackS.center=Point3f(0,0,0);
|
|
TrackS.Reset();
|
|
TrackS.radius= 100.f;
|
|
|
|
zoom=1;
|
|
path="";
|
|
/*s=new Segmentator();*/
|
|
//timer = new QTimer(this );
|
|
//QTimer::connect( timer, SIGNAL(timeout()), this, SLOT(Update()) );
|
|
// timer->start(0); // 2 seconds single-shot timer
|
|
|
|
}
|
|
|
|
void SimpleGLWidget::SaveMatrix()
|
|
{
|
|
glGetDoublev(GL_PROJECTION_MATRIX ,projection);
|
|
glGetDoublev(GL_MODELVIEW_MATRIX ,modelMatrix);
|
|
glGetIntegerv(GL_VIEWPORT,viewport);
|
|
}
|
|
|
|
void SimpleGLWidget::LoadMatrix()
|
|
{
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadMatrixd(projection);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadMatrixd(modelMatrix);
|
|
}
|
|
|
|
//load as texture the i jpg of the directory
|
|
void SimpleGLWidget::LoadTexture(QString p,int level)
|
|
{
|
|
QImage qI=QImage();
|
|
QDir Qd=QDir(p);
|
|
QString qformat;
|
|
QString Path=QString(p);
|
|
Qd.setNameFilter("*.jpg");
|
|
|
|
Qd.setSorting(QDir::Name);
|
|
QString PathFile=Path;
|
|
PathFile.append(Qd[level]);
|
|
|
|
qI.load(PathFile,qformat);
|
|
QImage tx = QGLWidget::convertToGLFormat (qI);
|
|
|
|
|
|
glGenTextures(1, &texName);
|
|
glBindTexture(GL_TEXTURE_2D, texName);
|
|
glTexImage2D( GL_TEXTURE_2D, 0, 3, tx.width(), tx.height(), 0,GL_RGBA, GL_UNSIGNED_BYTE, tx.bits() );
|
|
glEnable(GL_TEXTURE_2D);
|
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
|
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
|
|
|
|
}
|
|
|
|
void SimpleGLWidget::drawSlide()
|
|
{
|
|
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
glPolygonMode(GL_FRONT,GL_FILL);
|
|
glMatrixMode (GL_TEXTURE);
|
|
glLoadIdentity();
|
|
glEnable(GL_TEXTURE_2D);
|
|
glEnable(GL_NORMALIZE);
|
|
glEnable(GL_LIGHTING);
|
|
glEnable(GL_LIGHT0);
|
|
glEnable(GL_COLOR_MATERIAL);
|
|
|
|
float dx=s->BBox().DimX();
|
|
float dy=s->BBox().DimY();
|
|
|
|
//to change take scale from segmentator.. better!
|
|
float n=atof(w->S_dist->text());
|
|
float level=((float)_numslide)*n;
|
|
|
|
Point3f p0=s->BBox().min;
|
|
p0+=Point3f(0.f,0.f,level);
|
|
|
|
Point3f p1=p0+Point3f(dx,0.f,0.f);
|
|
Point3f p2=p0+Point3f(dx,dy,0.f);
|
|
Point3f p3=p0+Point3f(0.f,dy,0.f);
|
|
|
|
glColor3d(1,1,1);
|
|
|
|
///texture
|
|
//_numslide
|
|
glBegin(GL_QUADS);
|
|
glNormal(Point3d(0,0,1));
|
|
glTexCoord(Point3f(0,1,0));
|
|
glVertex(p0);
|
|
glTexCoord(Point3f(1,1,0));
|
|
glVertex(p1);
|
|
glTexCoord(Point3f(1,0,0));
|
|
glVertex(p2);
|
|
glTexCoord(Point3f(0,0,0));
|
|
glVertex(p3);
|
|
glEnd();
|
|
glPopAttrib();
|
|
|
|
//glBegin(GL_QUADS);
|
|
//for (int x=0;x<((s->V.dimX())-1);x++)
|
|
// for (int y=0;y<((s->V.dimY())-1);y++)
|
|
// {
|
|
// glNormal(Point3d(0,0,1));
|
|
// Point3<int> p0=Point3<int>(x,y,_numslide);
|
|
// double color=((double)s->V.getAt(p0))/256.f;
|
|
// glColor3d(color,color,color);
|
|
// glVertex(p0);
|
|
//
|
|
// Point3<int> p1=Point3<int>(x+1,y,_numslide);
|
|
// color=((double)s->V.getAt(p1))/256.f;
|
|
// glColor3d(color,color,color);
|
|
// glVertex(p1);
|
|
//
|
|
// Point3<int> p2=Point3<int>(x+1,y+1,_numslide);
|
|
// color=((double)s->V.getAt(p2))/256.f;
|
|
// glColor3d(color,color,color);
|
|
// glVertex(p2);
|
|
//
|
|
// Point3<int> p3=Point3<int>(x,y+1,_numslide);
|
|
// color=((double)s->V.getAt(p3))/256.f;
|
|
// glColor3d(color,color,color);
|
|
// glVertex(p3);
|
|
// }
|
|
//glEnd();
|
|
}
|
|
|
|
void drawForces(Segmentator::Part_VertexContainer *pv,int typeForce)
|
|
{
|
|
Segmentator::Part_VertexContainer::iterator vi;
|
|
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
glLineWidth(0.3f);
|
|
glDisable(GL_NORMALIZE);
|
|
glDisable(GL_LIGHTING);
|
|
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
|
|
|
if (typeForce==0)
|
|
glColor3d(1,0,0);
|
|
else
|
|
if (typeForce==1)
|
|
glColor3d(0,0,1);
|
|
else
|
|
if (typeForce==2)
|
|
glColor3d(0,1,0);
|
|
|
|
for (vi=pv->begin();vi<pv->end();++vi)
|
|
{
|
|
glBegin(GL_LINE_LOOP);
|
|
vcg::glVertex((*vi).P());
|
|
if (typeForce==0)
|
|
vcg::glVertex((*vi).P()+((*vi).IntForce()*4.f));
|
|
else
|
|
if (typeForce==1)
|
|
vcg::glVertex((*vi).P()+((*vi).ExtForce()*4.f));
|
|
else
|
|
if (typeForce==2)
|
|
vcg::glVertex((*vi).P()+(((*vi).ExtForce()+(*vi).IntForce())*4.f));
|
|
glEnd();
|
|
}
|
|
glPopAttrib();
|
|
}
|
|
|
|
void SimpleGLWidget::Save()
|
|
{
|
|
QString filename = QFileDialog::getSaveFileName("prova.ply",
|
|
"Ply files (*.ply)",
|
|
this,
|
|
"save file dialog",
|
|
"Choose a filename to save under" );
|
|
if (filename!=NULL)
|
|
{
|
|
const char *path_save=filename.ascii();
|
|
vcg::tri::io::ExporterPLY<Segmentator::MyTriMesh>::Save((*s->m),path_save);
|
|
}
|
|
|
|
}
|
|
|
|
bool TimeSelfIntersection()
|
|
{
|
|
static clock_t time=0;
|
|
clock_t elapsedsecs=abs(time-clock());
|
|
if (elapsedsecs>500)
|
|
{
|
|
time=clock();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//void SimpleGLWidget::WriteInfo()
|
|
//{
|
|
//
|
|
// if (s!=0)
|
|
// {
|
|
//
|
|
// 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();
|
|
//
|
|
// 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 );
|
|
//
|
|
// level++;
|
|
// str.sprintf( "Triangles : %i Vertex: %i ",s->m.fn,s->m.vn);
|
|
// renderText( 20, height() - level*20, str, f );
|
|
// }
|
|
//}
|
|
|
|
void SimpleGLWidget::SmoothMesh()
|
|
{
|
|
s->Smooth();
|
|
}
|
|
|
|
void SimpleGLWidget::glDraw(){
|
|
glClearColor(0.2f,0.2f,0.2f,1.f);
|
|
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 (s!=0){
|
|
|
|
glPushMatrix();
|
|
if (_showslides)
|
|
{
|
|
vcg::Point3f p=Point3f((float)s->BBox().Center().V(0),(float)s->BBox().Center().V(1),(float)s->BBox().Center().V(2));
|
|
TrackS.radius=s->BBox().Diag();
|
|
TrackS.GetView();
|
|
TrackS.Apply();
|
|
TrackS.Draw();
|
|
glScalef(1.f/s->BBox().Diag(),1.f/s->BBox().Diag(),1.f/s->BBox().Diag());
|
|
//glScalef(GLfloat(zoom),GLfloat(zoom),GLfloat(zoom));
|
|
glTranslate(-p);
|
|
//save transformation matrixes
|
|
SaveMatrix();
|
|
}
|
|
else
|
|
{
|
|
if (s->m!=NULL)
|
|
{
|
|
//vcg::tri::UpdateBounding<Segmentator::MyTriMesh>::Box(*(s->m));
|
|
vcg::Point3f p=s->m->bbox.Center();
|
|
TrackM.GetView();
|
|
TrackM.Apply();
|
|
TrackM.Draw();
|
|
glScalef(1.f/s->m->bbox.Diag(),1.f/s->m->bbox.Diag(),1.f/s->m->bbox.Diag());
|
|
glTranslate(-p);
|
|
//glScalef(1.f/s->m->bbox.Diag(),1.f/s->m->bbox.Diag(),1.f/s->m->bbox.Diag());
|
|
}
|
|
}
|
|
|
|
glEnable(GL_NORMALIZE);
|
|
glEnable(GL_LIGHTING);
|
|
glEnable(GL_LIGHT0);
|
|
glEnable(GL_COLOR_MATERIAL);
|
|
if (_showslides)
|
|
drawSlide();
|
|
|
|
if (intForces)
|
|
drawForces(&s->P_Vertex,0);
|
|
if (extForces)
|
|
drawForces(&s->P_Vertex,1);
|
|
if (resultForces)
|
|
drawForces(&s->P_Vertex,2);
|
|
|
|
//draw faces
|
|
glEnable(GL_NORMALIZE);
|
|
glEnable(GL_LIGHTING);
|
|
glEnable(GL_LIGHT0);
|
|
glEnable(GL_COLOR_MATERIAL);
|
|
glDisable(GL_TEXTURE_2D);
|
|
|
|
Segmentator::MyTriMesh::FaceIterator fi;
|
|
|
|
|
|
if (wire)
|
|
{
|
|
glDisable(GL_NORMALIZE);
|
|
glDisable(GL_LIGHTING);
|
|
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
|
|
}
|
|
else
|
|
glPolygonMode(GL_FRONT,GL_FILL);
|
|
|
|
if (s->m!=NULL)
|
|
{
|
|
glBegin(GL_TRIANGLES);
|
|
for (fi=s->m->face.begin();fi<s->m->face.end();fi++)
|
|
{
|
|
if(!(*fi).IsD())
|
|
{
|
|
glColor3d(0.4,0.8,0.8);
|
|
if (fi->intersected)
|
|
glColor3d(1.f,0,0);
|
|
|
|
if (((blocked)&&(!fi->IsBlocked()))||(!blocked))
|
|
{
|
|
if (!wire)
|
|
{
|
|
vcg::glNormal(fi->V(0)->N());
|
|
vcg::glVertex(fi->V(0)->P());
|
|
vcg::glNormal(fi->V(1)->N());
|
|
vcg::glVertex(fi->V(1)->P());
|
|
vcg::glNormal(fi->V(2)->N());
|
|
vcg::glVertex(fi->V(2)->P());
|
|
}
|
|
else
|
|
{
|
|
vcg::glVertex(fi->V(0)->P());
|
|
vcg::glVertex(fi->V(1)->P());
|
|
vcg::glVertex(fi->V(2)->P());
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
glEnd();
|
|
glPopMatrix();
|
|
//WriteInfo();
|
|
|
|
}
|
|
QGLWidget::glDraw();
|
|
}
|
|
|
|
///open the directiry and initialize dataset
|
|
void SimpleGLWidget::OpenDirectory()
|
|
{
|
|
QString filename = QFileDialog::getExistingDirectory(
|
|
".",
|
|
this,
|
|
"open file dialog"
|
|
"Choose a Directory" );
|
|
if (filename!=NULL)
|
|
{
|
|
filename+="/";
|
|
path=filename;
|
|
const char *pa=filename.ascii();
|
|
char *p=(char*)pa;
|
|
s->LoadFromDir(p,"prova.txt");
|
|
LoadTexture(p,0);
|
|
_showslides=true;
|
|
w->SlidesButton->setOn(true);
|
|
repaint();
|
|
}
|
|
}
|
|
|
|
void SimpleGLWidget::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 SimpleGLWidget::ClearMesh()
|
|
{
|
|
s->m->Clear();
|
|
repaint();
|
|
}
|
|
|
|
void SimpleGLWidget::UpdateBBMesh()
|
|
{
|
|
vcg::tri::UpdateBounding<Segmentator::MyTriMesh>::Box(*(s->m));
|
|
}
|
|
|
|
void SimpleGLWidget::mousePressEvent ( QMouseEvent * e )
|
|
{
|
|
if (e->button()==Qt::LeftButton )
|
|
{
|
|
|
|
if ((!_showslides)&&(s->m!=NULL))
|
|
{
|
|
/*vcg::tri::UpdateBounding<Segmentator::MyTriMesh>::Box(*(s->m));
|
|
TrackM.radius=s->m->bbox.Diag();
|
|
TrackM.center=s->m->bbox.Center();
|
|
*/
|
|
UpdateBBMesh();
|
|
TrackM.MouseDown(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT);
|
|
}
|
|
else if (_showslides)
|
|
TrackS.MouseDown(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT);
|
|
}
|
|
else
|
|
//test mass spring model
|
|
if ((e->button()==Qt::RightButton)&&(_showslides))
|
|
{
|
|
float winz;
|
|
double x;
|
|
double y;
|
|
double z;
|
|
//LoadMatrix();
|
|
glReadPixels(e->x(),_H-e->y(),1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&winz);
|
|
gluUnProject(e->x(),_H-e->y(),winz,modelMatrix,projection,viewport,&x,&y,&z);
|
|
|
|
SetExtractionParameters();
|
|
s->InitSegmentation(Point3f(x,y,z));
|
|
w->slider1->setValue(s->gray_init);
|
|
|
|
UpdateBBMesh();
|
|
//vcg::tri::UpdateBounding<Segmentator::MyTriMesh>::Box(*(s->m));
|
|
repaint();
|
|
}
|
|
//vcg::tri::UpdateBounding<Segmentator::MyTriMesh>::Box(s->m);
|
|
}
|
|
|
|
void SimpleGLWidget::setColor()
|
|
{
|
|
s->gray_init=w->slider1->value();
|
|
}
|
|
|
|
void SimpleGLWidget::wheelEvent(QWheelEvent *e)
|
|
{
|
|
if (!_showslides)
|
|
{
|
|
/* zoom+=e->delta()/120.f;
|
|
repaint();*/
|
|
TrackM.MouseWheel(e->delta()/120.f);
|
|
repaint();
|
|
}
|
|
else
|
|
{
|
|
int oldnum=_numslide;
|
|
_numslide+=e->delta()/120.f;
|
|
if ((_numslide<0)||(_numslide>=s->V.dimZ()))
|
|
_numslide=oldnum;
|
|
if (s!=0)
|
|
{
|
|
LoadTexture(path,_numslide);
|
|
}
|
|
}
|
|
|
|
repaint();
|
|
}
|
|
|
|
void SimpleGLWidget::mouseReleaseEvent(QMouseEvent * e )
|
|
{
|
|
if (!_showslides)
|
|
TrackM.MouseUp(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT);
|
|
else
|
|
TrackS.MouseUp(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT);
|
|
|
|
repaint();
|
|
}
|
|
|
|
void SimpleGLWidget::Step()
|
|
{
|
|
if ((s!=0)&&(continue_int))
|
|
{
|
|
s->AutoStep();
|
|
repaint();
|
|
}
|
|
}
|
|
|
|
void SimpleGLWidget::MarchingCube()
|
|
{
|
|
if (s->m->fn>0)
|
|
s->Resample();
|
|
|
|
//vcg::tri::io::ExporterPLY<Segmentator::MyTriMesh>::Save((*s->new_m),"d:/march.ply");
|
|
//vcg::tri::io::ExporterPLY<Segmentator::MyTriMesh>::Save((*s->m),"d:/march.ply");
|
|
}
|
|
|
|
void SimpleGLWidget::SetExtractionParameters()
|
|
{
|
|
float mass=atof(w->M_particles->text());
|
|
float k_elanst=atof(w->K_elanst->text());
|
|
float dihedral=atof(w->D_angle->text());
|
|
float timestep=atof(w->T_step->text());
|
|
float edge=atof(w->E_size->text());
|
|
float tolerance=atof(w->Tolerance->text());
|
|
float dinstance=atof(w->S_dist->text());
|
|
//int color =atoi(w->Color->text());
|
|
///to modify
|
|
|
|
s->SetSegmentParameters(tolerance,mass,k_elanst,dihedral,timestep,edge,Point3f(1.f,1.f,dinstance));
|
|
}
|
|
|
|
void SimpleGLWidget::mouseMoveEvent ( QMouseEvent * e )
|
|
{
|
|
if (_showslides)
|
|
TrackS.MouseMove(e->x(),_H-e->y());
|
|
else
|
|
TrackM.MouseMove(e->x(),_H-e->y());
|
|
|
|
repaint();
|
|
}
|
|
|
|
|
|
void SimpleGLWidget::initializeGL(){
|
|
|
|
GLfloat f[4]={0.2f,0.2f,0.2f,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);
|
|
|
|
}
|