You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
409 lines
10 KiB
409 lines
10 KiB
|
|
#include <math.h> |
|
#include <iostream> |
|
|
|
#include <QtCore/QFile> |
|
#include <QtGui/QMouseEvent> |
|
#include <QtGui/QMessageBox> |
|
#include <QtGui/QImage> |
|
#include <QtGui/QFileDialog> |
|
|
|
#include "glarea.h" |
|
#include "cmesh.h" |
|
#include <wrap/io_trimesh/import.h> |
|
#include <wrap/io_trimesh/export.h> |
|
#include <vcg/complex/algorithms/update/normal.h> |
|
#include <vcg/complex/algorithms/update/topology.h> |
|
#include <vcg/complex/algorithms/update/flag.h> |
|
|
|
#include <vcg/space/normal_extrapolation.h> |
|
//#include "curvature.h" |
|
|
|
|
|
|
|
|
|
|
|
using namespace std; |
|
using namespace vcg; |
|
|
|
GLArea::GLArea(QWidget *parent): QGLWidget(parent), pivot(NULL), smooth(false), radius(1.2) { |
|
|
|
tot = 1; |
|
|
|
setMouseTracking(true); |
|
// init("uccello.ply", radius); |
|
} |
|
|
|
bool GLArea::loadModel(const QString &file) { |
|
|
|
updateGL(); |
|
return true; |
|
} |
|
void GLArea::open() { |
|
QString file = QFileDialog::getOpenFileName(this, "Select a ply file", "", "*.ply"); |
|
if(!file.size()) return; |
|
init(file, radius); |
|
} |
|
|
|
void GLArea::init(QString file, float ballsize = 1.2) { |
|
|
|
int err = tri::io::Importer<CMesh>::Open(mesh, file.toAscii().data()); |
|
if(err) return; |
|
mesh.face.clear(); |
|
mesh.fn = 0; |
|
|
|
// UpdateTopology<CMesh>::VertexFace(mesh); |
|
// UpdateTopology<CMesh>::FaceFace(mesh); |
|
// tri::UpdateFlags<CMesh>::FaceBorderFromFF(mesh); |
|
// tri::UpdateFlags<CMesh>::VertexBorderFromFace(mesh); |
|
|
|
//compute box; |
|
box = Box3f(); |
|
for(int i = 0; i < mesh.vert.size(); i++) |
|
box.Add(mesh.vert[i].P()); |
|
|
|
|
|
float r = sqrt((box.Diag()*box.Diag())/mesh.vn); |
|
|
|
// mesh.face.clear(); |
|
// mesh.fn = 0; |
|
if(pivot) delete pivot; |
|
cout << "creating pibot\n"; |
|
|
|
NormalExtrapolation<vector<CVertex> >::ExtrapolateNormals(mesh.vert.begin(), mesh.vert.end(), 10); |
|
// pivot = new Pivot<CMesh>(mesh, r*ballsize, 0.1, 0); |
|
pivot = new Pivot<CMesh>(mesh, 0, 0.1, 0); |
|
// pivot.build(); |
|
// pivot->buildMesh(); |
|
|
|
} |
|
|
|
void GLArea::save() { |
|
|
|
mesh.vn = mesh.vert.size(); |
|
mesh.fn = mesh.face.size(); |
|
tri::io::ExporterPLY<CMesh>::Save(mesh, "prova.ply"); |
|
|
|
} |
|
|
|
void GLArea::addFace() { |
|
pivot->addFace(); |
|
updateGL(); |
|
/* std::list<Hinge>::iterator li; |
|
for(li=pivot->front.begin();li!=pivot->front.end();++li) |
|
printf("(%d-%d-%d)",(*li).v0,(*li).v1,(*li).v2); |
|
printf("\n");*/ |
|
|
|
} |
|
|
|
void GLArea::add10Faces() { |
|
for(int i =0; i < 10; i++) |
|
if(-1 == pivot->addFace()) return; |
|
|
|
updateGL(); |
|
} |
|
|
|
|
|
void GLArea::add100Faces() { |
|
for(int i =0; i < 100; i++) |
|
if(-1 == pivot->addFace()) return; |
|
updateGL(); |
|
} |
|
|
|
void GLArea::add1000Faces() { |
|
for(int i =0; i < 1000; i++) |
|
if(-1 == pivot->addFace()) return; |
|
updateGL(); |
|
} |
|
|
|
void GLArea::addAll() { |
|
while(1) { |
|
for(int i = 0; i < 1000; i++) |
|
if(0 > pivot->addFace()) return; |
|
updateGL(); |
|
} |
|
} |
|
|
|
void GLArea::addTot() { |
|
for(int i = 0; i < tot; i++) |
|
if(0 > pivot->addFace()) return; |
|
updateGL(); |
|
} |
|
|
|
|
|
|
|
void GLArea::viewSmooth(bool on) { |
|
smooth = on; |
|
updateGL(); |
|
} |
|
void GLArea::initializeGL() { |
|
glClearColor(1, 1, 1, 1); |
|
glEnable(GL_DEPTH_TEST); |
|
glEnable(GL_LIGHTING); |
|
glEnable(GL_LIGHT0); |
|
glEnable(GL_COLOR_MATERIAL); |
|
|
|
glDisable(GL_BLEND); |
|
glEnable(GL_NORMALIZE); |
|
glDisable(GL_CULL_FACE); |
|
glCullFace(GL_BACK); |
|
glColor4f(1, 1, 1, 1); |
|
|
|
glEnable(GL_LIGHTING); |
|
double st = 4; //1/sqrt(3); |
|
float lpos[4]; |
|
lpos[0] = lpos[1] = lpos[2] = st; |
|
lpos[3] = 1; |
|
glLightfv(GL_LIGHT0, GL_POSITION, lpos); |
|
|
|
float v[4] = {0.8, 0.8, 0.8, 0.0}; |
|
glLightfv(GL_LIGHT0, GL_DIFFUSE, v); |
|
|
|
trackball.center=Point3f(0, 0, 0); |
|
trackball.radius= 1; |
|
|
|
glLoadIdentity(); |
|
} |
|
|
|
|
|
void GLArea::resizeGL(int w, int h) { |
|
glViewport(0, 0, (GLint)w, (GLint)h); |
|
glMatrixMode(GL_PROJECTION); |
|
glLoadIdentity(); |
|
|
|
|
|
float r = w/(float)h; |
|
gluPerspective(60, r, 1, 4); |
|
|
|
glMatrixMode(GL_MODELVIEW); |
|
|
|
} |
|
|
|
|
|
void GLArea::paintGL() { |
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); |
|
|
|
glLoadIdentity(); |
|
gluLookAt(0, 0, 3, 0, 0, 0, 0, 1, 0); |
|
|
|
//Drawing the scene |
|
glPushMatrix(); |
|
trackball.GetView(); |
|
trackball.Apply(true); |
|
|
|
Point3f c = -box.Center(); |
|
float radius = 2.0f/box.Diag(); |
|
|
|
if(mesh.face.size()>0) { |
|
CFace &face = mesh.face[0]; |
|
CVertex *v[3]; |
|
v[0] = face.V(0); |
|
c=-v[0]->P(); |
|
radius=radius*5; |
|
} |
|
|
|
if(!pivot) return; |
|
|
|
glPushMatrix(); |
|
glScalef(radius, radius, radius); |
|
glTranslatef(c[0], c[1], c[2]); |
|
|
|
if(pivot->front.size()>2) |
|
{ |
|
glEnable(GL_LINE_SMOOTH); |
|
glColor4f(1, 0, 1, 0.1); |
|
glLineWidth(5); |
|
Pivot<CMesh>::Edgex &ee=pivot->front.front(); |
|
int v0=ee.v0; |
|
int v1=ee.v1; |
|
glBegin(GL_LINES); |
|
glVertex3fv(mesh.vert[v0].P().V()); |
|
glVertex3fv(mesh.vert[v1].P().V()); |
|
glEnd(); |
|
glLineWidth(1); |
|
} |
|
glEnable(GL_LIGHTING); |
|
glColor3f(0, 1, 0); |
|
|
|
|
|
|
|
|
|
|
|
glBegin(GL_TRIANGLES); |
|
for(int i = 0; i < mesh.face.size(); i++) { |
|
CFace &face = mesh.face[i]; |
|
CVertex *v[3]; |
|
v[0] = face.V(0); |
|
v[1] = face.V(1); |
|
v[2] = face.V(2); |
|
|
|
Point3f n = (v[1]->P()- v[0]->P()) ^ (v[2]->P() - v[0]->P()); |
|
//Point3f &n = face.N(); |
|
glNormal3fv(&(n[0])); |
|
|
|
for(int k = 0; k < 3; k++) { |
|
glVertex3fv((float *)&(v[k]->P())); |
|
} |
|
} |
|
glEnd(); |
|
|
|
glEnable(GL_POLYGON_OFFSET_LINE); |
|
glPolygonOffset(-3, -3); |
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); |
|
glDisable(GL_LIGHTING); |
|
glColor3f(0, 0.5, 0); |
|
|
|
glPolygonOffset(-1, -1); |
|
glBegin(GL_TRIANGLES); |
|
for(int i = 0; i < mesh.face.size(); i++) { |
|
CFace &face = mesh.face[i]; |
|
CVertex *v[3]; |
|
v[0] = face.V(0); |
|
v[1] = face.V(1); |
|
v[2] = face.V(2); |
|
for(int k = 0; k < 3; k++) { |
|
glVertex3fv((float *)&(v[k]->P())); |
|
} |
|
} |
|
glEnd(); |
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); |
|
|
|
glDisable(GL_DEPTH_TEST); |
|
glLineWidth(3.0f); |
|
glBegin(GL_LINES); |
|
for(list<Pivot<CMesh>::Edgex>::iterator k = pivot->front.begin(); k != pivot->front.end(); k++) { |
|
glColor3f(1, 0, 0); |
|
Point3f &p0 = mesh.vert[(*k).v0].P(); |
|
glVertex3fv(&(p0[0])); |
|
glColor3f(0, 0, 1); |
|
Point3f &p1 = mesh.vert[(*k).v1].P(); |
|
glVertex3fv(&(p1[0])); |
|
|
|
/* glColor3f(1, 1, 0); |
|
Point3f middle = (mesh.vert[(*k).v0].P() + mesh.vert[(*k).v1].P())/2; |
|
glVertex3fv(&(middle[0])); |
|
glVertex3fv(&((*k).center[0]));*/ |
|
} |
|
for(list<Pivot<CMesh>::Edgex>::iterator k = pivot->deads.begin(); k != pivot->deads.end(); k++) { |
|
glColor3f(0, 0, 0); |
|
Point3f &p0 = mesh.vert[(*k).v0].P(); |
|
glVertex3fv(&(p0[0])); |
|
Point3f &p1 = mesh.vert[(*k).v1].P(); |
|
glVertex3fv(&(p1[0])); |
|
} |
|
glEnd(); |
|
glEnable(GL_DEPTH_TEST); |
|
|
|
glPointSize(4.0f); |
|
glBegin(GL_POINTS); |
|
for(int i = 0; i < mesh.vert.size(); i++) { |
|
CVertex &v = mesh.vert[i]; |
|
Point3f &p = v.P(); |
|
if(v.IsD()) continue; |
|
if(v.IsV()) glColor3f(1, 0, 0); |
|
else if(v.IsB()) glColor3f(1, 1, 0); |
|
else continue; |
|
glVertex3f(p[0], p[1], p[2]); |
|
} |
|
glEnd(); |
|
glColor3f(0, 0, 0); |
|
glPointSize(1.0f); |
|
|
|
glLineWidth(1.0f); |
|
glEnable(GL_LIGHTING); |
|
|
|
|
|
glBegin(GL_LINES); |
|
for(int i = 0; i < mesh.vert.size(); i++) { |
|
CVertex &v = mesh.vert[i]; |
|
Point3f &p = v.P(); |
|
if(v.IsD()) continue; |
|
glVertex3f(p[0], p[1], p[2]); |
|
Point3f q = p + v.N(); |
|
glVertex3f(q[0], q[1], q[2]); |
|
} |
|
glEnd(); |
|
|
|
|
|
|
|
|
|
|
|
glDisable(GL_POLYGON_OFFSET_LINE); |
|
|
|
|
|
|
|
|
|
|
|
glDisable(GL_LIGHTING); |
|
glPopMatrix(); |
|
|
|
glScalef(radius, radius, radius); |
|
glTranslatef(c[0], c[1], c[2]); |
|
glEnable(GL_BLEND); |
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
|
// cloud.draw(); |
|
glColor3f(0.5, 0.5, 0.5); |
|
glPointSize(2); |
|
glBegin(GL_POINTS); |
|
for(int i = 0; i < mesh.vert.size(); i++) { |
|
CVertex &vert = mesh.vert[i]; |
|
Point3f n = vert.N(); |
|
Point3f p = vert.P(); |
|
glNormal3f(n[0], n[1], n[2]); |
|
glVertex3f(p[0], p[1], p[2]); |
|
} |
|
glEnd(); |
|
|
|
glDisable(GL_BLEND); |
|
glPopMatrix(); |
|
} |
|
|
|
void GLArea::wheelEvent(QWheelEvent *e) { |
|
if(e->delta() > 0) |
|
trackball.MouseWheel(1); |
|
else |
|
trackball.MouseWheel(-1); |
|
updateGL(); |
|
} |
|
|
|
void GLArea::mouseMoveEvent(QMouseEvent *e) { |
|
trackball.MouseMove(e->x(), height() - e->y()); |
|
updateGL(); |
|
} |
|
Trackball::Button QT2VCG(Qt::MouseButton qtbt, Qt::KeyboardModifiers modifiers) |
|
{ |
|
int vcgbt=Trackball::BUTTON_NONE; |
|
if(qtbt & Qt::LeftButton ) vcgbt |= Trackball::BUTTON_LEFT; |
|
if(qtbt & Qt::RightButton ) vcgbt |= Trackball::BUTTON_RIGHT; |
|
if(qtbt & Qt::MidButton ) vcgbt |= Trackball::BUTTON_MIDDLE; |
|
if(modifiers & Qt::ShiftModifier ) vcgbt |= Trackball::KEY_SHIFT; |
|
if(modifiers & Qt::ControlModifier ) vcgbt |= Trackball::KEY_CTRL; |
|
if(modifiers & Qt::AltModifier ) vcgbt |= Trackball::KEY_ALT; |
|
return Trackball::Button(vcgbt); |
|
} |
|
|
|
void GLArea::keyReleaseEvent ( QKeyEvent * e ) |
|
{ |
|
if(e->key()==Qt::Key_Control) trackball.MouseUp(0,0, QT2VCG(Qt::NoButton, Qt::ControlModifier ) ); |
|
if(e->key()==Qt::Key_Shift) trackball.MouseUp(0,0, QT2VCG(Qt::NoButton, Qt::ShiftModifier ) ); |
|
if(e->key()==Qt::Key_Alt) trackball.MouseUp(0,0, QT2VCG(Qt::NoButton, Qt::AltModifier ) ); |
|
} |
|
|
|
void GLArea::mousePressEvent(QMouseEvent *e) { |
|
trackball.MouseDown(e->x(),height()-e->y(), QT2VCG(e->button(), e->modifiers() ) ); |
|
// if(e->button() == Qt::LeftButton) |
|
//trackball.MouseDown(e->x(), width() - e->y(), Trackball::BUTTON_LEFT); |
|
// if(e->button() == Qt::RightButton) |
|
// trackball.MouseDown(e->x(), width() - e->y(), Trackball::BUTTON_LEFT | Trackball::KEY_CTRL); |
|
updateGL(); |
|
} |
|
|
|
void GLArea::mouseReleaseEvent(QMouseEvent *e) { |
|
trackball.MouseUp(e->x(),height()-e->y(), QT2VCG(e->button(), e->modifiers() ) ); |
|
// if(e->button() == Qt::LeftButton) |
|
//trackball.MouseUp(e->x(), width() - e->y(), Trackball::BUTTON_LEFT); |
|
//if(e->button() == Qt::RightButton) |
|
// trackball.MouseUp(e->x(), width() - e->y(), Trackball::BUTTON_LEFT | Trackball::KEY_CTRL); |
|
}
|
|
|