MNE-CPP  beta 1.0
brainview.cpp
1 //=============================================================================================================
36 //*************************************************************************************************************
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
41 #include "brainview.h"
42 
43 
44 //*************************************************************************************************************
45 //=============================================================================================================
46 // QT INCLUDES
47 //=============================================================================================================
48 
49 #include "qglbuilder.h"
50 #include "qglcube.h"
51 
52 #include <QMouseEvent>
53 
54 
55 //*************************************************************************************************************
56 //=============================================================================================================
57 // USED NAMESPACES
58 //=============================================================================================================
59 
60 using namespace DISP3DLIB;
61 //using namespace DISPLIB;
62 
63 
64 //*************************************************************************************************************
65 //=============================================================================================================
66 // DEFINE MEMBER METHODS
67 //=============================================================================================================
68 
70 : m_pSceneNodeBrain(NULL)
71 , m_pSceneNode(NULL)
72 , m_pLightModel(NULL)
73 , m_pLightParametersScene(NULL)
74 {
75  init();
76 }
77 
78 
79 //*************************************************************************************************************
80 
81 BrainView::BrainView(const QString &subject_id, qint32 hemi, const QString &surf, const QString &subjects_dir)
82 : m_SurfaceSet(subject_id, hemi, surf, subjects_dir)
83 , m_pSceneNodeBrain(NULL)
84 , m_pSceneNode(NULL)
85 , m_pLightModel(NULL)
86 , m_pLightParametersScene(NULL)
87 {
88  init();
89 }
90 
91 
92 //*************************************************************************************************************
93 
94 BrainView::BrainView(const QString &subject_id, qint32 hemi, const QString &surf, const QString &atlas, const QString &subjects_dir)
95 : m_SurfaceSet(subject_id, hemi, surf, subjects_dir)
96 , m_AnnotationSet(subject_id, hemi, atlas, subjects_dir)
97 , m_pSceneNodeBrain(NULL)
98 , m_pSceneNode(NULL)
99 , m_pLightModel(NULL)
100 , m_pLightParametersScene(NULL)
101 {
102  init();
103 }
104 
105 
106 //*************************************************************************************************************
107 
108 BrainView::BrainView(const QString& p_sFile)
109 : m_pSceneNodeBrain(NULL)
110 , m_pSceneNode(NULL)
111 , m_pLightModel(NULL)
112 , m_pLightParametersScene(NULL)
113 {
114  Surface t_Surf(p_sFile);
115  m_SurfaceSet.insert(t_Surf);
116 
117  init();
118 }
119 
120 
121 //*************************************************************************************************************
122 
124 {
125  if(m_pSceneNode)
126  {
127  delete m_pSceneNode;
128  m_pSceneNode = NULL;
129  }
130 }
131 
132 
133 //*************************************************************************************************************
134 
135 void BrainView::init()
136 {
137  m_bStereo = true;
138  m_bRenderPerVertex = false;
139  m_fOffsetZ = -100.0f;
140  m_fOffsetZEye = 60.0f;
141 }
142 
143 
144 //*************************************************************************************************************
145 
146 void BrainView::initializeGL(QGLPainter *painter)
147 {
148  //
149  // Generate surface scene
150  //
151  qDebug() << "m_SurfaceSet.surf()" << m_SurfaceSet.surf();
152  if(QString::compare(m_SurfaceSet.surf(),"inflated") == 0)// || m_viewOptionFlags.testFlag(BrainView::ShowCurvature))
153  {
154  genSurfacePerVertex();
155  }
156  else
157  {
158  genSurface();
159  }
160 
161 
162  //
163  // Create light models
164  //
165  m_pLightModel = new QGLLightModel(this);
166  m_pLightModel->setAmbientSceneColor(Qt::white);
167  m_pLightModel->setViewerPosition(QGLLightModel::LocalViewer);
168 
169  m_pLightParametersScene = new QGLLightParameters(this);
170  m_pLightParametersScene->setPosition(QVector3D(0.0f, 0.0f, 3.0f));
171  painter->setMainLight(m_pLightParametersScene);
172 
173  //
174  // Set stereo type
175  //
176  if (m_bStereo) {
177 // this->setStereoType(QGLView::RedCyanAnaglyph);
178  this->setStereoType(QGLView::StretchedLeftRight);
179 
180  camera()->setCenter(QVector3D(0,0,m_fOffsetZ));//0.8f*fac));
181  camera()->setEyeSeparation(0.4f);
182  camera()->setFieldOfView(30);
183  camera()->setEye(QVector3D(0,0,m_fOffsetZEye));
184  }
185  else
186  {
187  camera()->setCenter(QVector3D(0,0,m_fOffsetZ));//0.8f*fac));
188  camera()->setFieldOfView(30);
189  camera()->setEye(QVector3D(0,0,m_fOffsetZEye));
190  }
191 
192  //set background to light white
193  glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
194 }
195 
196 
197 //*************************************************************************************************************
198 
199 void BrainView::paintGL(QGLPainter *painter)
200 {
201  glEnable(GL_BLEND); // enable transparency
202 
203  // painter->modelViewMatrix().rotate(45.0f, 1.0f, 1.0f, 1.0f);
204 
205 
206  painter->modelViewMatrix().push();
207  painter->projectionMatrix().push();
208 
209  painter->setStandardEffect(QGL::LitMaterial);
210 // painter->setCamera(m_pCameraFrontal);
211  painter->setLightModel(m_pLightModel);
212 
213  if(m_bRenderPerVertex)
214  {
215  material.bind(painter);
216  material.prepareToDraw(painter, painter->attributes());
217  }
218 
219  if(m_pSceneNode)
220  m_pSceneNode->draw(painter);
221 
222 
223  painter->modelViewMatrix().pop();
224  painter->projectionMatrix().pop();
225 }
226 
227 
228 //*************************************************************************************************************
229 
230 void BrainView::keyPressEvent(QKeyEvent *e)
231 {
232  camera()->setCenter(QVector3D(0,0,0));
233 
234  float normEyeOld = sqrt(pow(camera()->eye().x(),2) + pow(camera()->eye().y(),2) + pow(camera()->eye().z(),2));
235 
236  QGLView::keyPressEvent(e);
237 
238  float dx = (camera()->eye().x()*m_fOffsetZ)/m_fOffsetZEye;
239  float dy = (camera()->eye().y()*m_fOffsetZ)/m_fOffsetZEye;
240  float dz = (camera()->eye().z()*m_fOffsetZ)/m_fOffsetZEye;
241 
242  float normEye = sqrt(pow(camera()->eye().x(),2) + pow(camera()->eye().y(),2) + pow(camera()->eye().z(),2));
243  float scaleEye = normEyeOld/normEye;//m_fOffsetZEye/normEye;
244  camera()->setEye(QVector3D(camera()->eye().x()*scaleEye,camera()->eye().y()*scaleEye,camera()->eye().z()*scaleEye));
245 
246  camera()->setCenter(QVector3D(dx,dy,dz));
247 }
248 
249 
250 //*************************************************************************************************************
251 
252 void BrainView::mouseMoveEvent(QMouseEvent *e)
253 {
254  camera()->setCenter(QVector3D(0,0,0));
255 
256  float normEyeOld = sqrt(pow(camera()->eye().x(),2) + pow(camera()->eye().y(),2) + pow(camera()->eye().z(),2));
257 
258  QGLView::mouseMoveEvent(e);
259 
260  float dx = (camera()->eye().x()*m_fOffsetZ)/m_fOffsetZEye;
261  float dy = (camera()->eye().y()*m_fOffsetZ)/m_fOffsetZEye;
262  float dz = (camera()->eye().z()*m_fOffsetZ)/m_fOffsetZEye;
263 
264  float normEye = sqrt(pow(camera()->eye().x(),2) + pow(camera()->eye().y(),2) + pow(camera()->eye().z(),2));
265  float scaleEye = normEyeOld/normEye;//m_fOffsetZEye/normEye;
266  camera()->setEye(QVector3D(camera()->eye().x()*scaleEye,camera()->eye().y()*scaleEye,camera()->eye().z()*scaleEye));
267 
268  camera()->setCenter(QVector3D(dx,dy,dz));
269 }
270 
271 
272 //*************************************************************************************************************
273 
274 void BrainView::mousePressEvent(QMouseEvent *e)
275 {
276 
277  if(e->buttons() & Qt::RightButton)
278  {
279  float normEye = sqrt(pow(camera()->eye().x(),2) + pow(camera()->eye().y(),2) + pow(camera()->eye().z(),2));
280  camera()->setCenter(QVector3D(0,0,m_fOffsetZ));
281  camera()->setEye(QVector3D(0,0,normEye));
282  }
283 
284  QGLView::mousePressEvent(e);
285 }
286 
287 
288 //private
289 //*************************************************************************************************************
290 
291 void BrainView::genSurfacePerVertex()
292 {
293  if(m_SurfaceSet.size() == 0)
294  return;
295 
296  if(m_pSceneNode)
297  {
298  delete m_pSceneNode;
299  m_pSceneNode = NULL;
300  }
301 
302  // in the constructor construct a builder on the stack
303  QGLBuilder builder;
304 
305  float fac = 100.0f; // too small vertices distances cause clipping errors --> 100 is a good value for freesurfer brain measures
306 
307  builder << QGL::Smooth;//QGL::Faceted;
308  m_pSceneNodeBrain = builder.currentNode();
309 
310  builder.pushNode();
311 
312  //
313  // get bounding box
314  //
315  calcBoundingBox();
316 
317  //
318  // Build each surface in its separate node
319  //
320  QMap<qint32, Surface>::const_iterator it = m_SurfaceSet.data().constBegin();
321  for (it = m_SurfaceSet.data().begin(); it != m_SurfaceSet.data().end(); ++it)
322  {
323  builder.pushNode();
324  {
325  Matrix3Xf rr = it.value().rr().transpose();
326 
327  //Centralize
328  for(qint32 i = 0; i < 3; ++i)
329  rr.row(i) = rr.row(i).array() - (m_vecBoundingBoxCenter[i] + it.value().offset()[i]);
330 
331 
332  QGeometryData t_GeometryDataTri;
333 
334  MatrixXf t_TriCoords = MatrixXf::Zero(3,3*(it.value().tris().rows()));
335  QArray<QColor4ub> cdata;
336  for(qint32 i = 0; i < it.value().tris().rows(); ++i)
337  {
338  for(qint32 j = 0; j < 3; ++j)
339  {
340  t_TriCoords.col(i*3+j) = rr.col( it.value().tris()(i,j) );
341 
342  if(it.value().curv()[it.value().tris()(i,j)] >= 0)
343  cdata.append(QColor( 50, 50, 50, 230));//Sulci
344  else
345  cdata.append(QColor( 200, 200, 200, 230));//Gyri
346  }
347  }
348 
349  t_TriCoords *= fac;
350  t_GeometryDataTri.appendVertexArray(QArray<QVector3D>::fromRawData( reinterpret_cast<const QVector3D*>(t_TriCoords.data()), t_TriCoords.cols() ));
351 
352  t_GeometryDataTri.appendColorArray(cdata);
353 
354  //
355  // Add triangles to current node
356  //
357  builder.addTriangles(t_GeometryDataTri);
358  }
359  // Go one level up
360  builder.popNode();
361  }
362 
363  m_bRenderPerVertex = true;
364 
365  // Optimze current scene for display and calculate lightning normals
366  m_pSceneNode = builder.finalizedSceneNode();
367 
368  m_pSceneNode->setParent(this);
369 }
370 
371 
372 //*************************************************************************************************************
373 
374 void BrainView::genSurfacePerRegion()
375 {
376  if(m_SurfaceSet.size() == 0)
377  return;
378 
379  if(m_pSceneNode)
380  {
381  delete m_pSceneNode;
382  m_pSceneNode = NULL;
383  }
384 
385  // in the constructor construct a builder on the stack
386  QGLBuilder builder;
387 
388  float fac = 100.0f; // too small vertices distances cause clipping errors --> 100 is a good value for freesurfer brain measures
389 
390  builder << QGL::Smooth;//QGL::Faceted;
391  m_pSceneNodeBrain = builder.currentNode();
392 
393  builder.pushNode();
394 
395  //
396  // Collor palette
397  //
398  qint32 index;
399  QSharedPointer<QGLMaterialCollection> palette = builder.sceneNode()->palette(); // register color palette within the root node
400 
401  //
402  // get bounding box
403  //
404  calcBoundingBox();
405 
406  //
407  // Build each surface in its separate node
408  //
409  QMap<qint32, Surface>::const_iterator it = m_SurfaceSet.data().constBegin();
410  for (it = m_SurfaceSet.data().begin(); it != m_SurfaceSet.data().end(); ++it)
411  {
412  builder.pushNode();
413  {
414  Matrix3Xf rr = it.value().rr().transpose();
415 
416  //Centralize
417  for(qint32 i = 0; i < 3; ++i)
418  rr.row(i) = rr.row(i).array() - m_vecBoundingBoxCenter[i];
419 
420 
421  QGeometryData t_GeometryDataTri;
422 
423  MatrixXf t_TriCoords = MatrixXf::Zero(3,3*(it.value().tris().rows()));
424  for(qint32 i = 0; i < it.value().tris().rows(); ++i)
425  for(qint32 j = 0; j < 3; ++j)
426  t_TriCoords.col(i*3+j) = rr.col( it.value().tris()(i,j) );
427 
428  t_TriCoords *= fac;
429  t_GeometryDataTri.appendVertexArray(QArray<QVector3D>::fromRawData( reinterpret_cast<const QVector3D*>(t_TriCoords.data()), t_TriCoords.cols() ));
430 
431  //
432  // Add triangles to current node
433  //
434  builder.addTriangles(t_GeometryDataTri);
435 
436  //
437  // Colorize Surface
438  //
439  QGLMaterial *t_pMaterialROI = new QGLMaterial();
440  t_pMaterialROI->setColor(QColor(100,100,100,230));
441  index = palette->addMaterial(t_pMaterialROI);
442  builder.currentNode()->setMaterialIndex(index);
443  }
444  // Go one level up
445  builder.popNode();
446  }
447 
448  m_bRenderPerVertex = false;
449 
450  // Optimze current scene for display and calculate lightning normals
451  m_pSceneNode = builder.finalizedSceneNode();
452 
453  m_pSceneNode->setParent(this);
454 }
455 
456 
457 //*************************************************************************************************************
458 
459 void BrainView::genSurface()
460 {
461  if(m_SurfaceSet.size() == 0)
462  return;
463 
464  if(m_pSceneNode)
465  {
466  delete m_pSceneNode;
467  m_pSceneNode = NULL;
468  }
469 
470  // in the constructor construct a builder on the stack
471  QGLBuilder builder;
472 
473  float fac = 100.0f; // too small vertices distances cause clipping errors --> 100 is a good value for freesurfer brain measures
474 
475  builder << QGL::Smooth;//QGL::Faceted;
476  m_pSceneNodeBrain = builder.currentNode();
477 
478  builder.pushNode();
479 
480  //
481  // Collor palette
482  //
483  qint32 index;
484  QSharedPointer<QGLMaterialCollection> palette = builder.sceneNode()->palette(); // register color palette within the root node
485 
486  //
487  // get bounding box
488  //
489  calcBoundingBox();
490 
491  //
492  // Build each surface in its separate node
493  //
494 
495  QMap<qint32, Surface>::const_iterator it = m_SurfaceSet.data().constBegin();
496  for (it = m_SurfaceSet.data().begin(); it != m_SurfaceSet.data().end(); ++it)
497  {
498  builder.pushNode();
499  {
500  Matrix3Xf rr = it.value().rr().transpose();
501 
502  //Centralize
503  for(qint32 i = 0; i < 3; ++i)
504  rr.row(i) = rr.row(i).array() - m_vecBoundingBoxCenter[i];
505 
506 
507  QGeometryData t_GeometryDataTri;
508 
509  MatrixXf t_TriCoords = MatrixXf::Zero(3,3*(it.value().tris().rows()));
510  for(qint32 i = 0; i < it.value().tris().rows(); ++i)
511  for(qint32 j = 0; j < 3; ++j)
512  t_TriCoords.col(i*3+j) = rr.col( it.value().tris()(i,j) );
513 
514  t_TriCoords *= fac;
515  t_GeometryDataTri.appendVertexArray(QArray<QVector3D>::fromRawData( reinterpret_cast<const QVector3D*>(t_TriCoords.data()), t_TriCoords.cols() ));
516 
517  //
518  // Add triangles to current node
519  //
520  builder.addTriangles(t_GeometryDataTri);
521 
522  //
523  // Colorize Surface
524  //
525  QGLMaterial *t_pMaterialROI = new QGLMaterial();
526  t_pMaterialROI->setColor(QColor(100,100,100,230));
527  index = palette->addMaterial(t_pMaterialROI);
528  builder.currentNode()->setMaterialIndex(index);
529  }
530  // Go one level up
531  builder.popNode();
532  }
533 
534  m_bRenderPerVertex = false;
535 
536  // Optimze current scene for display and calculate lightning normals
537  m_pSceneNode = builder.finalizedSceneNode();
538 
539  m_pSceneNode->setParent(this);
540 }
541 
542 
543 //*************************************************************************************************************
544 
545 void BrainView::calcBoundingBox()
546 {
547  QMap<qint32, Surface>::const_iterator it = m_SurfaceSet.data().constBegin();
548 
549  QVector3D min(it.value().rr().col(0).minCoeff(), it.value().rr().col(1).minCoeff(), it.value().rr().col(2).minCoeff());
550  QVector3D max(it.value().rr().col(0).maxCoeff(), it.value().rr().col(1).maxCoeff(), it.value().rr().col(2).maxCoeff());
551 
552  for (it = m_SurfaceSet.data().begin()+1; it != m_SurfaceSet.data().end(); ++it)
553  {
554  for(qint32 i = 0; i < 3; ++i)
555  {
556  min[i] = min[i] > it.value().rr().col(i).minCoeff() ? it.value().rr().col(i).minCoeff() : min[i];
557  max[i] = max[i] < it.value().rr().col(i).maxCoeff() ? it.value().rr().col(i).maxCoeff() : max[i];
558  }
559  }
560  m_vecBoundingBoxMin = min;
561  m_vecBoundingBoxMax = max;
562 
563  for(qint32 i = 0; i < 3; ++i)
564  m_vecBoundingBoxCenter[i] = (m_vecBoundingBoxMin[i]+m_vecBoundingBoxMax[i])/2.0f;
565 }
QString surf() const
Definition: surfaceset.h:269
void mouseMoveEvent(QMouseEvent *e)
Definition: brainview.cpp:252
void paintGL(QGLPainter *painter)
Definition: brainview.cpp:199
qint32 size() const
Definition: surfaceset.h:280
void insert(const Surface &p_Surface)
Definition: surfaceset.cpp:154
QMap< qint32, Surface > & data()
Definition: surfaceset.h:253
FreeSurfer surface mesh.
Definition: surface.h:92
void mousePressEvent(QMouseEvent *e)
Definition: brainview.cpp:274
void initializeGL(QGLPainter *painter)
Definition: brainview.cpp:146
void keyPressEvent(QKeyEvent *e)
Definition: brainview.cpp:230