MNE-CPP 0.1.9
A Framework for Electrophysiology
Loading...
Searching...
No Matches
mne_msh_display_surface_set.cpp
Go to the documentation of this file.
1//=============================================================================================================
36//=============================================================================================================
37// INCLUDES
38//=============================================================================================================
39
41
43#include "mne_surface_old.h"
44#include "mne_surface_patch.h"
46#include "mne_msh_light_set.h"
47#include "mne_msh_light.h"
48#include "mne_msh_eyes.h"
49
51
52#define MALLOC_47(x,t) (t *)malloc((x)*sizeof(t))
53
54#define FREE_47(x) if ((char *)(x) != Q_NULLPTR) free((char *)(x))
55
56#define REALLOC_47(x,y,t) (t *)((x == NULL) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t)))
57
58#ifndef TRUE
59#define TRUE 1
60#endif
61
62#ifndef FALSE
63#define FALSE 0
64#endif
65
66#ifndef FAIL
67#define FAIL -1
68#endif
69
70#ifndef OK
71#define OK 0
72#endif
73
74#define X_47 0
75#define Y_47 1
76#define Z_47 2
77
78#define SURF_LEFT_HEMI FIFFV_MNE_SURF_LEFT_HEMI
79#define SURF_RIGHT_HEMI FIFFV_MNE_SURF_RIGHT_HEMI
80
81#define VEC_COPY_47(to,from) {\
82 (to)[X_47] = (from)[X_47];\
83 (to)[Y_47] = (from)[Y_47];\
84 (to)[Z_47] = (from)[Z_47];\
85}
86
87#define SHOW_CURVATURE_NONE 0
88#define SHOW_CURVATURE_OVERLAY 1
89#define SHOW_OVERLAY_HEAT 1
90
91#define SURF_LEFT_MORPH_HEMI (1 << 16 | FIFFV_MNE_SURF_LEFT_HEMI)
92#define SURF_RIGHT_MORPH_HEMI (1 << 16 | FIFFV_MNE_SURF_RIGHT_HEMI)
93
94#define POS_CURV_COLOR 0.25
95#define NEG_CURV_COLOR 0.375
96#define EVEN_CURV_COLOR 0.375
97
98static MNELIB::MneMshEyes default_eyes;
99static MNELIB::MneMshEyes* all_eyes = Q_NULLPTR;
100static int neyes = 0;
101static int current_eyes = -1;
102static int ndefault = 8;
103
104static MNELIB::MneMshLightSet* custom_lights = Q_NULLPTR;
105
106//=============================================================================================================
107// QT INCLUDES
108//=============================================================================================================
109
110#include <qmath.h>
111
112//=============================================================================================================
113// USED NAMESPACES
114//=============================================================================================================
115
116using namespace MNELIB;
117
118//=============================================================================================================
119// DEFINE MEMBER METHODS
120//=============================================================================================================
121
123{
124 default_eyes.name = Q_NULLPTR;
125
126 default_eyes.left[0] = -0.2f;
127 default_eyes.left[0] = 0.0f;
128 default_eyes.left[0] = 0.0f;
129
130 default_eyes.right[0] = 0.2f;
131 default_eyes.right[0] = 0.0f;
132 default_eyes.right[0] = 0.0f;
133
134 default_eyes.left_up[0] = 0.0f;
135 default_eyes.left_up[0] = 0.0f;
136 default_eyes.left_up[0] = 1.0f;
137
138 default_eyes.right_up[0] = 0.0f;
139 default_eyes.right_up[0] = 0.0f;
140 default_eyes.right_up[0] = 1.0f;
141
142 int k;
143
144 this->nsurf = nsurf;
145 if (nsurf > 0) {
146 surfs = MALLOC_47(nsurf,MneMshDisplaySurface*);
147 patches = MALLOC_47(nsurf,MneSurfacePatch*);
148 patch_rot = MALLOC_47(nsurf,float);
149 active = MALLOC_47(nsurf,int);
150 drawable = MALLOC_47(nsurf,int);
151
152 for (k = 0; k < nsurf; k++) {
153 surfs[k] = Q_NULLPTR;
154 active[k] = FALSE;
155 drawable[k] = TRUE;
156 patches[k] = Q_NULLPTR;
157 patch_rot[k] = 0.0;
158 }
159 } else {
160 surfs = Q_NULLPTR;
161 active = Q_NULLPTR;
162 patches = Q_NULLPTR;
163 drawable = Q_NULLPTR;
164 patch_rot= Q_NULLPTR;
165 }
166 subj = Q_NULLPTR;
167 morph_subj = Q_NULLPTR;
168 main_t = Q_NULLPTR;
169 morph_t = Q_NULLPTR;
170
171 use_patches = FALSE;
172 lights = Q_NULLPTR;
173 user_data = Q_NULLPTR;
174 user_data_free = Q_NULLPTR;
175
176 rot[0] = 0.0;
177 rot[1] = 0.0;
178 rot[2] = 0.0;
179
180 move[0] = 0.0;
181 move[1] = 0.0;
182 move[2] = 0.0;
183
184 eye[0] = 1.0;
185 eye[1] = 0.0;
186 eye[2] = 0.0;
187
188 up[0] = 0.0;
189 up[1] = 0.0;
190 up[2] = 1.0;
191
192 bg_color[0] = 0.0;
193 bg_color[1] = 0.0;
194 bg_color[2] = 0.0;
195
196 text_color[0] = 1.0;
197 text_color[1] = 1.0;
198 text_color[2] = 1.0;
199}
200
201//=============================================================================================================
202
204{
205 int k;
206
207 for (k = 0; k < nsurf; k++)
208 delete surfs[k];
209 if (patches) {
210 for (k = 0; k < nsurf; k++)
211 delete patches[k];
212 delete patches;
213 }
214 delete main_t;
215 delete morph_t;
216 FREE_47(patch_rot);
217 FREE_47(surfs);
218 FREE_47(subj);
219 FREE_47(morph_subj);
220 FREE_47(active);
221 FREE_47(drawable);
222
223 delete lights;
224 if (user_data_free)
225 user_data_free(user_data);
226}
227
228//=============================================================================================================
229
230MneMshDisplaySurfaceSet* MneMshDisplaySurfaceSet::load_new_surface(const QString &subject_id, const QString &surf, const QString &subjects_dir)
231 /*
232 * Load new display surface data
233 */
234{
235 MneSourceSpaceOld* left = Q_NULLPTR;
236 MneSourceSpaceOld* right = Q_NULLPTR;
237 char *left_file = Q_NULLPTR;
238 char *right_file = Q_NULLPTR;
239 char *this_surf = Q_NULLPTR;
240 char *this_curv = Q_NULLPTR;
241 MneMshDisplaySurface* pThis = Q_NULLPTR;
242 MneMshDisplaySurfaceSet* surfs = Q_NULLPTR;
243 QString pathLh, pathLhCurv, pathRh, pathRhCurv;
244 QByteArray ba_surf, ba_curv;
245
246 pathLh = QString("%1/%2/surf/%3.%4").arg(subjects_dir).arg(subject_id).arg("lh").arg(surf);
247 ba_surf = pathLh.toLatin1();
248 this_surf = ba_surf.data();
249
250 if (this_surf == Q_NULLPTR)
251 goto bad;
252
253 pathLhCurv = QString("%1/%2/surf/%3.%4").arg(subjects_dir).arg(subject_id).arg("lh").arg("curv");
254 ba_curv = pathLhCurv.toLatin1();
255 this_curv = ba_curv.data();
256
257 printf("Loading surface %s ...\n",this_surf);
258 if ((left = MneSurfaceOrVolume::mne_load_surface(this_surf,this_curv)) == Q_NULLPTR) {
259 if ((left = MneSurfaceOrVolume::mne_load_surface(this_surf,Q_NULLPTR)) == Q_NULLPTR)
260 goto bad;
261 else
262 MneSurfaceOrVolume::add_uniform_curv((MneSurfaceOld*)left);
263 }
264 left_file = this_surf; this_surf = Q_NULLPTR;
265 FREE_47(this_curv);
266
267 pathRh = QString("%1/%2/surf/%3.%4").arg(subjects_dir).arg(subject_id).arg("rh").arg(surf);
268 ba_surf = pathRh.toLatin1();
269 this_surf = ba_surf.data();
270
271 pathRhCurv = QString("%1/%2/surf/%3.%4").arg(subjects_dir).arg(subject_id).arg("rh").arg("curv");
272 ba_curv = pathRhCurv.toLatin1();
273 this_curv = ba_curv.data();
274
275 printf("Loading surface %s ...\n",this_surf);
276 if ((right = MneSurfaceOrVolume::mne_load_surface(this_surf,this_curv)) == Q_NULLPTR) {
277 if ((right = MneSurfaceOrVolume::mne_load_surface(this_surf,Q_NULLPTR)) == Q_NULLPTR)
278 goto bad;
279 else
280 MneSurfaceOrVolume::add_uniform_curv((MneSurfaceOld*)right);
281 }
282 right_file = this_surf; this_surf = Q_NULLPTR;
283 FREE_47(this_curv);
284
285 surfs = new MneMshDisplaySurfaceSet(2);
286
287 surfs->surfs[0] = new MneMshDisplaySurface();
288 surfs->surfs[1] = new MneMshDisplaySurface();
289
290 surfs->active[0] = TRUE;
291 surfs->active[1] = FALSE;
292 surfs->drawable[0] = TRUE;
293 surfs->drawable[1] = TRUE;
294
295 pThis = surfs->surfs[0];
296 pThis->filename = left_file;
297 //pThis->time_loaded = time(Q_NULLPTR); //Comment out due to unknown timestemp function ToDo
298 pThis->s = (MneSurfaceOld*)left;
299 pThis->s->id = SURF_LEFT_HEMI;
300 pThis->subj = subject_id.toUtf8().data();
301 pThis->surf_name = surf.toUtf8().data();
302
303 decide_surface_extent(pThis,"Left hemisphere");
304 decide_curv_display(surf.toUtf8().data(),pThis);
305 setup_curvature_colors (pThis);
306
307 pThis = surfs->surfs[1];
308 pThis->filename = right_file;
309 //pThis->time_loaded = time(Q_NULLPTR); //Comment out due to unknown timestemp function ToDo
310 pThis->s = (MneSurfaceOld*)right;
311 pThis->s->id = SURF_RIGHT_HEMI;
312 pThis->subj = subject_id.toUtf8().data();
313 pThis->surf_name = surf.toUtf8().data();
314
315 decide_surface_extent(pThis,"Right hemisphere");
316 decide_curv_display(surf.toUtf8().data(),pThis);
317 setup_curvature_colors (pThis);
318
319 apply_left_right_eyes(surfs);
320
321 setup_current_surface_lights(surfs);
322
323 return surfs;
324
325bad : {
326 FREE_47(left_file);
327 FREE_47(right_file);
328 delete left;
329 delete right;
330 //The following deletes are obsolete since the two char* are point to data of the QStrings which are deleted automatically
331// FREE_47(this_surf);
332// FREE_47(this_curv);
333 return Q_NULLPTR;
334 }
335}
336
337//=============================================================================================================
338
339void MneMshDisplaySurfaceSet::decide_surface_extent(MneMshDisplaySurface* surf,
340 const char *tag)
341
342{
343 float minv[3],maxv[3];
344 int k,c;
345 float *r;
347
348 VEC_COPY_47(minv,s->rr[0]);
349 VEC_COPY_47(maxv,s->rr[0]);
350 for (k = 0; k < s->np; k++) {
351 r = s->rr[k];
352 for (c = 0; c < 3; c++) {
353 if (r[c] < minv[c])
354 minv[c] = r[c];
355 if (r[c] > maxv[c])
356 maxv[c] = r[c];
357 }
358 }
359#ifdef DEBUG
360 printf("%s:\n",tag);
361 printf("\tx = %f ... %f mm\n",1000*minv[X],1000*maxv[X]);
362 printf("\ty = %f ... %f mm\n",1000*minv[Y],1000*maxv[Y]);
363 printf("\tz = %f ... %f mm\n",1000*minv[Z],1000*maxv[Z]);
364#endif
365
366 surf->fov = 0;
367 for (c = 0; c < 3; c++) {
368 if (std::fabs(minv[c]) > surf->fov)
369 surf->fov = std::fabs(minv[c]);
370 if (std::fabs(maxv[c]) > surf->fov)
371 surf->fov = std::fabs(maxv[c]);
372 }
373 VEC_COPY_47(surf->minv,minv);
374 VEC_COPY_47(surf->maxv,maxv);
375 surf->fov_scale = 1.1f;
376 return;
377}
378
379//=============================================================================================================
380
381void MneMshDisplaySurfaceSet::decide_curv_display(const char *name,
383
384{
385 if (strstr(name,"inflated") == name || strstr(name,"sphere") == name || strstr(name,"white") == name)
386 s->curvature_color_mode = SHOW_CURVATURE_OVERLAY;
387 else
388 s->curvature_color_mode = SHOW_CURVATURE_NONE;
389 s->overlay_color_mode = SHOW_OVERLAY_HEAT;
390 /*
391 s->overlay_color_mode = SHOW_OVERLAY_NEGPOS;
392 */
393 return;
394}
395
396//=============================================================================================================
397
398int MneMshDisplaySurfaceSet::add_bem_surface(MneMshDisplaySurfaceSet* surfs,
399 QString filepath,
400 int kind,
401 QString bemname,
402 int full_geom,
403 int check)
404{
405 MneSurfaceOld* surf = Q_NULLPTR;
407
408 //Transform from QString to char*
409 QByteArray baFilepath = filepath.toLatin1();
410 char* filename = baFilepath.data();
411
412 QByteArray baBemname = bemname.toLatin1();
413 char* name = baBemname.data();
414
415 if (!surfs) {
416 qWarning("Cannot add to nonexisting surface set.");
417 goto bad;
418 }
419
420 printf("Loading BEM surface %s (id = %d) from %s ...\n",name,kind,filename);
421 if ((surf = MneSurfaceOld::mne_read_bem_surface2(filename,kind,full_geom,Q_NULLPTR)) == Q_NULLPTR)
422 goto bad;
423 if (check) {
424 double sum;
425 MneSurfaceOld::mne_compute_surface_cm(surf);
426 sum = MneSurfaceOld::sum_solids(surf->cm,surf)/(4*M_PI);
427 if (std::fabs(sum - 1.0) > 1e-4) {
428 printf( "%s surface is not closed "
429 "(sum of solid angles = %g * 4*PI).",name,sum);
430 goto bad;
431 }
432 }
433
434 newSurf->filename = MneSurfaceOld::mne_strdup(filename);
435 //newSurf->time_loaded = time(Q_NULLPTR); //Comment out due to unknown timestemp function ToDo
436 newSurf->s = surf;
437 newSurf->s->id = kind;
438 newSurf->subj = Q_NULLPTR;
439 newSurf->surf_name = MneSurfaceOld::mne_strdup(name);
440
441 newSurf->curvature_color_mode = SHOW_CURVATURE_NONE;
442 newSurf->overlay_color_mode = SHOW_OVERLAY_HEAT;
443
444 decide_surface_extent(newSurf,name);
445 add_replace_display_surface(surfs, newSurf, true, true);
446 apply_left_eyes(surfs);
447 setup_current_surface_lights(surfs);
448
449 return OK;
450
451bad :
452 {
453 if(surf)
454 {
455 delete surf;
456 }
457 if(newSurf)
458 {
459 delete newSurf;
460 }
461 return FAIL;
462 }
463}
464
465//=============================================================================================================
466
467void MneMshDisplaySurfaceSet::add_replace_display_surface(MneMshDisplaySurfaceSet* surfs,
468 MneMshDisplaySurface* newSurf,
469 bool replace,
470 bool drawable)
471{
473
474 if (replace) {
475 for (int k = 0; k < surfs->nsurf; k++) {
476 surf = surfs->surfs[k];
477 if (surf->s->id == newSurf->s->id) {
478 newSurf->transparent = surf->transparent;
479 newSurf->show_aux_data = surf->show_aux_data;
480 delete surf;
481 surfs->surfs[k] = newSurf;
482 if (!drawable) {
483 surfs->active[k] = FALSE;
484 surfs->drawable[k] = FALSE;
485 }
486 newSurf = Q_NULLPTR;
487 break;
488 }
489 }
490 }
491 if (newSurf) { /* New surface */
492 surfs->surfs = REALLOC_47(surfs->surfs,surfs->nsurf+1,MneMshDisplaySurface*);
493 surfs->patches = REALLOC_47(surfs->patches,surfs->nsurf+1,MneSurfacePatch*);
494 surfs->patch_rot = REALLOC_47(surfs->patch_rot,surfs->nsurf+1,float);
495 surfs->active = REALLOC_47(surfs->active,surfs->nsurf+1,int);
496 surfs->drawable = REALLOC_47(surfs->drawable,surfs->nsurf+1,int);
497 surfs->surfs[surfs->nsurf] = newSurf;
498 surfs->active[surfs->nsurf] = drawable;
499 surfs->drawable[surfs->nsurf] = drawable;
500 surfs->patches[surfs->nsurf] = NULL;
501 surfs->patch_rot[surfs->nsurf] = 0.0;
502 surfs->nsurf++;
503 }
504 return;
505}
506
507//=============================================================================================================
508
509void MneMshDisplaySurfaceSet::setup_curvature_colors(MneMshDisplaySurface* surf)
510{
511 int k,c;
512 MneSourceSpaceOld* s = NULL;;
513 float *col;
514 float curv_sum;
515 int ncolor;
516
517 if (surf == NULL || surf->s == NULL)
518 return;
519
520 s = (MneSourceSpaceOld*)surf->s;
521
522 ncolor = surf->nvertex_colors;
523
524 if (!surf->vertex_colors)
525 surf->vertex_colors = MALLOC_47(ncolor*s->np,float);
526 col = surf->vertex_colors;
527
528 curv_sum = 0.0;
529 if (surf->curvature_color_mode == SHOW_CURVATURE_OVERLAY) {
530 for (k = 0; k < s->np; k++) {
531 curv_sum += std::fabs(s->curv[k]);
532 for (c = 0; c < 3; c++)
533 col[c] = (s->curv[k] > 0) ? POS_CURV_COLOR : NEG_CURV_COLOR;
534 if (ncolor == 4)
535 col[3] = 1.0;
536 col = col+ncolor;
537 }
538 }
539 else {
540 for (k = 0; k < s->np; k++) {
541 curv_sum += std::fabs(s->curv[k]);
542 for (c = 0; c < 3; c++)
543 col[c] = EVEN_CURV_COLOR;
544 if (ncolor == 4)
545 col[3] = 1.0;
546 col = col+ncolor;
547 }
548 }
549#ifdef DEBUG
550 printf("Average curvature : %f\n",curv_sum/s->np);
551#endif
552 return;
553}
554
555//=============================================================================================================
556
557void MneMshDisplaySurfaceSet::apply_left_right_eyes(MneMshDisplaySurfaceSet* surfs)
558{
559 MneMshEyes* eyes = Q_NULLPTR;
560 MneMshDisplaySurface* surf = Q_NULLPTR;
561 int k;
562
563 if (surfs == NULL)
564 return;
565
566 if (neyes == 0 || current_eyes < 0 || current_eyes > neyes-1) {
567 eyes = &default_eyes;
568 } else {
569 eyes = all_eyes+current_eyes;
570 }
571
572 for (k = 0; k < surfs->nsurf; k++) {
573 surf = surfs->surfs[k];
574 switch(surf->s->id) {
575 case SURF_LEFT_HEMI :
576 case SURF_LEFT_MORPH_HEMI :
577 VEC_COPY_47(surf->eye,eyes->left);
578 VEC_COPY_47(surf->up,eyes->left_up);
579 break;
580 case SURF_RIGHT_HEMI :
581 case SURF_RIGHT_MORPH_HEMI :
582 VEC_COPY_47(surf->eye,eyes->right);
583 VEC_COPY_47(surf->up,eyes->right_up);
584 break;
585 default :
586 VEC_COPY_47(surf->eye,eyes->left);
587 VEC_COPY_47(surf->up,eyes->left_up);
588 break;
589 }
590 }
591 return;
592}
593
594//=============================================================================================================
595
596void MneMshDisplaySurfaceSet::apply_left_eyes(MneMshDisplaySurfaceSet* surfs)
597{
598 int k;
599
600 if (surfs == Q_NULLPTR)
601 return;
602
603 for (k = 0; k < surfs->nsurf; k++) {
604 if (neyes == 0 || current_eyes < 0 || current_eyes > neyes-1) {
605 VEC_COPY_47(surfs->surfs[k]->eye,default_eyes.left);
606 VEC_COPY_47(surfs->surfs[k]->up,default_eyes.left_up);
607 }
608 else {
609 VEC_COPY_47(surfs->surfs[k]->eye,all_eyes[current_eyes].left);
610 VEC_COPY_47(surfs->surfs[k]->up,all_eyes[current_eyes].left_up);
611 }
612 }
613 return;
614}
615
616//=============================================================================================================
617
618void MneMshDisplaySurfaceSet::setup_current_surface_lights(MneMshDisplaySurfaceSet* surfs)
619{
620 if (!surfs)
621 return;
622 initialize_custom_lights();
623 setup_these_surface_lights(surfs,custom_lights);
624 return;
625}
626
627//=============================================================================================================
628
629void MneMshDisplaySurfaceSet::initialize_custom_lights()
630{
631 if (!custom_lights) {
633 s->nlight = ndefault;
634
635 QList<MneMshLight*> default_lights;
636 default_lights << new MneMshLight(TRUE, 0.0f, 0.0f, 1.0f, 0.8f, 0.8f, 0.8f);
637 default_lights << new MneMshLight(TRUE, 0.0f, 0.0f, -1.0f, 0.8f, 0.8f, 0.8f);
638 default_lights << new MneMshLight(TRUE, 0.6f, -1.0f, -1.0f, 0.6f, 0.6f, 0.6f);
639 default_lights << new MneMshLight(TRUE, -0.6f, -1.0f, -1.0f, 0.6f, 0.6f, 0.6f);
640 default_lights << new MneMshLight(TRUE, 1.0f, 0.0f, 0.0f, 0.8f, 0.8f, 0.8f);
641 default_lights << new MneMshLight(TRUE, -1.0f, 0.0f, 0.0f, 0.8f, 0.8f, 0.8f);
642 default_lights << new MneMshLight(TRUE, 0.0f, 1.0f, 0.5f, 0.6f, 0.6f, 0.6f);
643 default_lights << new MneMshLight(FALSE, 0.0f, 0.0f, -1.0, 1.0f, 1.0f, 1.0f);
644
645 s->lights = default_lights;
646
647 custom_lights = dup_light_set(s);
648 delete s;
649 }
650}
651
652//=============================================================================================================
653
654MneMshLightSet* MneMshDisplaySurfaceSet::dup_light_set(MneMshLightSet* s)
655{
656 MneMshLightSet* res = Q_NULLPTR;
657 int k;
658
659 if (s) {
660 res = new MneMshLightSet();
661 //res->lights = MALLOC_47(s->nlight,mshLightRec);
662 res->nlight = s->nlight;
663
664 for (k = 0; k < s->nlight; k++)
665 res->lights.append(new MneMshLight(*s->lights[k]));
666 }
667 return res;
668}
669
670//=============================================================================================================
671
672void MneMshDisplaySurfaceSet::setup_these_surface_lights(MneMshDisplaySurfaceSet* surfs, MneMshLightSet* set)
673{
674 if (!surfs || !set)
675 return;
676 delete surfs->lights;
677 surfs->lights = Q_NULLPTR;
678 surfs->lights = dup_light_set(set);
679 return;
680}
681
FiffCoordTransSet class declaration.
int k
Definition fiff_tag.cpp:324
MneMshDisplaySurfaceSet class declaration.
MneMshLight class declaration.
MneSurfacePatch class declaration.
MneSourceSpaceOld class declaration.
MneMshDisplaySurface class declaration.
MneMshLightSet class declaration.
MneMshEyes class declaration.
MneSurfaceOld class declaration.
The MNE Msh Display Surface class holds information about a surface to be rendered.
The MNE Msh Display Surface Set class holds information about a set of surfaces to be rendered.
The MneMshEyes class.
The MneMshLight class.
The MneMshLightSet class.
This defines a source space.
This defines a surface.
The MneSurfacePatch class.