https://github.com/NeuroanatomyAndConnectivity/vidview
Tip revision: a08f8878e4d91ae2d7a73ffc20168146eac1c29e authored by boettger on 04 March 2013, 18:09:51 UTC
ROI & connectivity drawing
ROI & connectivity drawing
Tip revision: a08f887
glwidget.cpp
#include <QtGui>
#include <QtOpenGL>
#include <QtDebug>
#include "glwidget.h"
#include <QMatrix4x4>
#include "afnisurface.h"
GLWidget::GLWidget(QWidget *parent, const QGLWidget * shareWidget, Qt::WindowFlags f)
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent, shareWidget, f)
{
data = NULL;
brainAlpha = 0.3;
stuffAlpha = 0.1;
screen = false;
//o = arg("orientation");
view = new GLfloat[16];
//background gray value
bg = 1;
process = new QProcess();
setFocusPolicy(Qt::StrongFocus);
qDebug("widget created");
}
void GLWidget::loadData(QString ssl, QString ssr, QString scons, QString overlayl, QString overlayr, float clipthr){
data = new Data(ssl, ssr, scons, overlayl, overlayr, clipthr);
QVector3D size(1,1,1);
size = data->max() - data->min();
qDebug() << "size: " << size.x() << size.y();
float largest = qMax(size.x(),size.y());
scale = (1/largest)*0.95;
qDebug() << "widget data loaded";
}
void GLWidget::setData(GLWidget* glw){
setData(glw->data);
}
void GLWidget::setData(Data* data){
this->data = data;
QVector3D size(1,1,1);
size = data->max() - data->min();
qDebug() << "size: " << size.x() << size.y();
float largest = qMax(size.x(),size.y());
scale = (1/largest)*0.95;
}
GLWidget::~GLWidget()
{
}
void GLWidget::initializeGL()
{
qDebug() << "initialize GL start";
GLfloat fSizes[2];
glGetFloatv(GL_POINT_SIZE_RANGE,fSizes);
GLfloat step;
glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);
qDebug() << "Pointsize range: " << fSizes[0] << fSizes[1];
qDebug() << "Pointsize granularity: " << step;
glEnable(GL_RESCALE_NORMAL);
//glEnable(GL_DEPTH_TEST);
glCullFace(GL_FRONT);
glDisable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
//glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
//glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_LIGHT0);
glEnable(GL_MULTISAMPLE);
glEnable(GL_LINE_SMOOTH);
static GLfloat global_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
static GLfloat specular[] = {0.5f, 0.5f, 0.5f , 1.0f};
glMateriali(GL_FRONT, GL_SHININESS, 1);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
static GLfloat lightPosition[4] = { 10000, 10000, 50000, 1.0 };
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
if (!screen) glGetFloatv(GL_MODELVIEW_MATRIX, view);
qDebug() << "initialize GL done";
}
void GLWidget::setView(){
glLoadIdentity();
glScaled(scale,scale,scale);
glMultMatrixf(view);
//This is only for initialization...
if (o=="i"){
glRotatef(180,0,1,0);
}
if (o=="a"){
glRotatef(90,0,1,0);
glRotatef(-90,1,0,0);
glRotatef(90,0,0,1);
}
if (o=="p"){
glRotatef(90,0,1,0);
glRotatef(-90,1,0,0);
glRotatef(-90,0,0,1);
}
if (o=="l"){
glRotatef(90,0,1,0);
glRotatef(-90,1,0,0);
}
if (o=="r"){
glRotatef(-90,0,1,0);
glRotatef(-90,1,0,0);
}
}
void GLWidget::paintGL()
{
qDebug() << "begin paintGL in GLWidget";
setView();
render(true);
}
void GLWidget::render(bool shift, bool allNodes){
glColorMask(1,1,1,1);
glClearColor(bg,bg,bg,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
data->paintGL(dp,shift,allNodes);
//TODO: This seems necessary to get keyboard events to this widget:
//if (!picking) setFocus();
QVector3D* s = data->selPos();
qDebug() << "selPos:" << s;
if (cursor&&(s!=NULL)){
double l = 10;
glBegin(GL_LINES);
glColor3f(1,0,0);
glVertex3f(s->x()+l,s->y(),s->z());
glVertex3f(s->x()-l,s->y(),s->z());
glColor3f(0,1,0);
glVertex3f(s->x(),s->y()+l,s->z());
glVertex3f(s->x(),s->y()-l,s->z());
glColor3f(0,0,1);
glVertex3f(s->x(),s->y(),s->z()+l);
glVertex3f(s->x(),s->y(),s->z()-l);
glEnd();
glDisable(GL_DEPTH_TEST);
glPointSize(5);
glColor3f(1,0,0);
glBegin(GL_POINTS);
glVertex3f(s->x(),s->y(),s->z());
glEnd();
}
}
void GLWidget::resizeGL(int width, int height)
{
qDebug() << "begin GL resize, width: " << width << " height: " << height;
glViewport(0, 0, width, height);
ar = (float)width/(float)height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (ar>1){
glOrtho(ar*-0.5, ar*+0.5, -0.5, +0.5, -1000, 1000);
} else {
glOrtho(-0.5, +0.5, -0.5/ar, +0.5/ar, -1000, 1000);
}
//glOrtho(-0.5,+0.5,-0.5,+0.5,-0.5,0.5);
glMatrixMode(GL_MODELVIEW);
}
void GLWidget::mousePressEvent(QMouseEvent *event)
{
lastPos = event->pos();
select(event);
//updateGL();
}
bool GLWidget::select(QMouseEvent *event){
if (event->modifiers() & Qt::ControlModifier){
qDebug() << "selecting...";
int viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
GLfloat z;
GLint x = event->x();
GLint y = viewport[3] - event->y();
glReadPixels(x, y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, (void*)&z);
//qDebug() << "glReadPixels x: " << x << " y: " << y << " z: " << z;
float xs = 2*x/(float)viewport[2]-1;
float ys = 2*y/(float)viewport[3]-1;
float zs = 2*z-1;
QVector3D sp(xs,ys,zs);
//qDebug() << sp;
QMatrix4x4 inv = modelMatrix()->inverted();
QMatrix4x4 inv2 = projectionMatrix()->inverted();
QVector3D repro = inv2.map(sp);
//qDebug() << sp;
world = inv.map(repro);
data->select(world, event->modifiers());
int s = data->selected->selectedIndex;
emit selected();
return true;
} else {
return false;
}
}
void GLWidget::mouseMoveEvent(QMouseEvent *event)
{
if (!select(event)){
glLoadIdentity();
int dx = event->x() - lastPos.x();
int dy = event->y() - lastPos.y();
if (event->buttons() & Qt::LeftButton) {
QMatrix4x4 mat(view[0],view[4],view[8],view[12],view[1],view[5],view[9],view[13],view[2],view[6],view[10],view[14],view[3],view[7],view[11],view[15]);
QVector3D orig(0, 0, 0);
QVector3D m = mat.map(orig);
glTranslatef(m.x(), m.y(), m.z());
glRotatef(qSqrt(dx*dx+dy*dy)/2.0, dy, dx, 0);
glTranslatef(-m.x(), -m.y(), -m.z());
} else if (event->buttons() & Qt::RightButton) {
glTranslatef(dx/(float)width()*ar/scale, -dy/(float)height()/scale, 0);
}
lastPos = event->pos();
glPushMatrix();
glMultMatrixf(view);
glGetFloatv(GL_MODELVIEW_MATRIX, view);
glPopMatrix();
}
updateGL();
}
void GLWidget::mouseReleaseEvent(QMouseEvent *event){
//TODO: sorting of all stuff in one sweep?
//surfr->sortTriangles();
//surfl->sortTriangles();
//cons->sortCons();
updateGL();
}
void GLWidget::wheelEvent (QWheelEvent *event)
{
int d = event->delta();
//qDebug() << "scale" << scale;
scale *= 1.0-d/1200.0;
updateGL();
}
void GLWidget::screenshot(QString name, double resolution){
screen = true;
//TODO: check: supp. does not work on windows / blocks on laptop / does not work non-interactively...
QPixmap map = this->renderPixmap(this->width()*resolution,this->height()*resolution,true);
map.save(name);
}
void GLWidget::keyPressEvent(QKeyEvent *event) {
qDebug() << "key:" << event->key();
if (event->key() == Qt::Key_C) {
if (bg == 1) {
bg = 0;
} else {
bg =1;
}
}
if (event->key() == Qt::Key_T) screenshot("test.png");
if (event->key() == Qt::Key_F) {
if (this->window()->isFullScreen()) {
this->window()->showNormal();
} else {
this->window()->showFullScreen();
}
}
if (event->key() == Qt::Key_I) {
glLoadIdentity();
glRotatef(180,0,1,0);
glGetFloatv(GL_MODELVIEW_MATRIX, view);
o = "";
}
if (event->key() == Qt::Key_A) {
glLoadIdentity();
glRotatef(90,0,1,0);
glRotatef(-90,1,0,0);
glRotatef(90,0,0,1);
glGetFloatv(GL_MODELVIEW_MATRIX, view);
o = "";
}
if (event->key() == Qt::Key_P) {
glLoadIdentity();
glRotatef(90,0,1,0);
glRotatef(-90,1,0,0);
glRotatef(-90,0,0,1);
glGetFloatv(GL_MODELVIEW_MATRIX, view);
o = "";
}
if (event->key() == Qt::Key_L) {
glLoadIdentity();
glRotatef(90,0,1,0);
glRotatef(-90,1,0,0);
glGetFloatv(GL_MODELVIEW_MATRIX, view);
o = "";
}
if (event->key() == Qt::Key_R) {
glLoadIdentity();
glRotatef(-90,0,1,0);
glRotatef(-90,1,0,0);
glGetFloatv(GL_MODELVIEW_MATRIX, view);
o = "";
}
if (event->key() == Qt::Key_S) {
glLoadIdentity();
glGetFloatv(GL_MODELVIEW_MATRIX, view);
o = "";
}
if (event->key() == Qt::Key_B){
if (data->surfset) {
qDebug() << "switching surface";
data->surfset->switchSurface();
}
if (data->surfsetr) {
qDebug() << "switching surface r";
data->surfsetr->switchSurface();
}
}
if (event->key() == Qt::Key_G){
if (data->surfset) {
data->surfset->clear_depth = !data->surfset->clear_depth;
}
}
emit dataChanged();
updateGL();
}
QMatrix4x4* GLWidget::modelMatrix(){
float mat[16];
glGetFloatv(GL_MODELVIEW_MATRIX, mat);
return new QMatrix4x4(mat[0],mat[4],mat[8],mat[12],mat[1],mat[5],mat[9],mat[13],mat[2],mat[6],mat[10],mat[14],mat[3],mat[7],mat[11],mat[15]);
}
QMatrix4x4* GLWidget::projectionMatrix(){
float mat[16];
for (int i = 0; i<16; i++){
//qDebug() << mat[i];
}
glGetFloatv(GL_PROJECTION_MATRIX, mat);
return new QMatrix4x4(mat[0],mat[4],mat[8],mat[12],mat[1],mat[5],mat[9],mat[13],mat[2],mat[6],mat[10],mat[14],mat[3],mat[7],mat[11],mat[15]);
}
void GLWidget::setDisplayParameters(DisplayParameters* dp){
this->dp = dp;
connect(dp,SIGNAL(changed()),this,SLOT(updateParameters()));
updateParameters();
}
void GLWidget::updateParameters(){
if (data->surfl) data->surfl->setAlpha(dp->left);
if (data->surfr) data->surfr->setAlpha(dp->right);
data->setGlyphAlpha(dp->glyphs);
qDebug() << "parameters: " << dp->left << dp->right << dp->glyphs;
QCheckBox* b = dp->findChild<QCheckBox*>("cursorBox");
cursor = b->isChecked();
b = dp->findChild<QCheckBox*>("leftBox_2");
data->lon = b->isChecked();
qDebug() << "lon: " << data->lon;
b = dp->findChild<QCheckBox*>("rightBox_2");
data->ron = b->isChecked();
qDebug() << "ron: " << data->ron;
b = dp->findChild<QCheckBox*>("connectivityBox");
data->connectivity = b->isChecked();
b = dp->findChild<QCheckBox*>("glyphVisibilityBox");
data->glyphsVisible = b->isChecked();
emit dataChanged();
updateGL();
}
void GLWidget::updateNode(int i){
QMutexLocker locker(&mutex);
qDebug() << "updateNode: " << i;
}
void GLWidget::saveView(QString filename){
QFile file(filename);
file.open(QIODevice::WriteOnly);
QTextStream out(&file);
for (int i = 0; i<16; i++){
out << view[i] << endl;
}
out << scale;
file.close();
}
void GLWidget::loadView(QString filename){
QFile file(filename);
file.open(QIODevice::ReadOnly);
QTextStream in(&file);
for (int i = 0; i<16; i++){
in >> view[i];
}
in >> scale;
file.close();
}
void GLWidget::orient(QString ori){
if (ori=="i") {
glLoadIdentity();
glRotatef(180,0,1,0);
glGetFloatv(GL_MODELVIEW_MATRIX, view);
o = "";
}
if (ori=="a") {
glLoadIdentity();
glRotatef(90,0,1,0);
glRotatef(-90,1,0,0);
glRotatef(90,0,0,1);
glGetFloatv(GL_MODELVIEW_MATRIX, view);
o = "";
}
if (ori=="p") {
glLoadIdentity();
glRotatef(90,0,1,0);
glRotatef(-90,1,0,0);
glRotatef(-90,0,0,1);
glGetFloatv(GL_MODELVIEW_MATRIX, view);
o = "";
}
if (ori=="l") {
glLoadIdentity();
glRotatef(90,0,1,0);
glRotatef(-90,1,0,0);
glGetFloatv(GL_MODELVIEW_MATRIX, view);
o = "";
}
if (ori=="r") {
glLoadIdentity();
glRotatef(-90,0,1,0);
glRotatef(-90,1,0,0);
glGetFloatv(GL_MODELVIEW_MATRIX, view);
o = "";
}
if (ori=="s") {
glLoadIdentity();
glGetFloatv(GL_MODELVIEW_MATRIX, view);
o = "";
}
}