vcglib/apps/pivoting/glarea.cpp

410 lines
10 KiB
C++

#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/trimesh/update/normal.h>
#include <vcg/complex/trimesh/update/topology.h>
#include <vcg/complex/trimesh/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);
}