52 #define MALLOC_47(x,t) (t *)malloc((x)*sizeof(t))
54 #define FREE_47(x) if ((char *)(x) != Q_NULLPTR) free((char *)(x))
56 #define REALLOC_47(x,y,t) (t *)((x == NULL) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t)))
78 #define SURF_LEFT_HEMI FIFFV_MNE_SURF_LEFT_HEMI
79 #define SURF_RIGHT_HEMI FIFFV_MNE_SURF_RIGHT_HEMI
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];\
87 #define SHOW_CURVATURE_NONE 0
88 #define SHOW_CURVATURE_OVERLAY 1
89 #define SHOW_OVERLAY_HEAT 1
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)
94 #define POS_CURV_COLOR 0.25
95 #define NEG_CURV_COLOR 0.375
96 #define EVEN_CURV_COLOR 0.375
100 static int neyes = 0;
101 static int current_eyes = -1;
102 static int ndefault = 8;
116 using namespace MNELIB;
124 default_eyes.name = Q_NULLPTR;
126 default_eyes.left[0] = -0.2f;
127 default_eyes.left[0] = 0.0f;
128 default_eyes.left[0] = 0.0f;
130 default_eyes.right[0] = 0.2f;
131 default_eyes.right[0] = 0.0f;
132 default_eyes.right[0] = 0.0f;
134 default_eyes.left_up[0] = 0.0f;
135 default_eyes.left_up[0] = 0.0f;
136 default_eyes.left_up[0] = 1.0f;
138 default_eyes.right_up[0] = 0.0f;
139 default_eyes.right_up[0] = 0.0f;
140 default_eyes.right_up[0] = 1.0f;
148 patch_rot = MALLOC_47(nsurf,
float);
149 active = MALLOC_47(nsurf,
int);
150 drawable = MALLOC_47(nsurf,
int);
152 for (
k = 0;
k < nsurf;
k++) {
153 surfs[
k] = Q_NULLPTR;
156 patches[
k] = Q_NULLPTR;
163 drawable = Q_NULLPTR;
164 patch_rot= Q_NULLPTR;
167 morph_subj = Q_NULLPTR;
173 user_data = Q_NULLPTR;
174 user_data_free = Q_NULLPTR;
207 for (
k = 0;
k < nsurf;
k++)
210 for (
k = 0;
k < nsurf;
k++)
225 user_data_free(user_data);
230 MneMshDisplaySurfaceSet* MneMshDisplaySurfaceSet::load_new_surface(
const QString &subject_id,
const QString &surf,
const QString &subjects_dir)
237 char *left_file = Q_NULLPTR;
238 char *right_file = Q_NULLPTR;
239 char *this_surf = Q_NULLPTR;
240 char *this_curv = Q_NULLPTR;
243 QString pathLh, pathLhCurv, pathRh, pathRhCurv;
244 QByteArray ba_surf, ba_curv;
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();
250 if (this_surf == Q_NULLPTR)
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();
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)
264 left_file = this_surf; this_surf = Q_NULLPTR;
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();
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();
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)
282 right_file = this_surf; this_surf = Q_NULLPTR;
290 surfs->active[0] = TRUE;
291 surfs->active[1] = FALSE;
292 surfs->drawable[0] = TRUE;
293 surfs->drawable[1] = TRUE;
295 pThis = surfs->surfs[0];
296 pThis->filename = left_file;
299 pThis->s->id = SURF_LEFT_HEMI;
300 pThis->subj = subject_id.toUtf8().data();
301 pThis->surf_name = surf.toUtf8().data();
303 decide_surface_extent(pThis,
"Left hemisphere");
304 decide_curv_display(surf.toUtf8().data(),pThis);
305 setup_curvature_colors (pThis);
307 pThis = surfs->surfs[1];
308 pThis->filename = right_file;
311 pThis->s->id = SURF_RIGHT_HEMI;
312 pThis->subj = subject_id.toUtf8().data();
313 pThis->surf_name = surf.toUtf8().data();
315 decide_surface_extent(pThis,
"Right hemisphere");
316 decide_curv_display(surf.toUtf8().data(),pThis);
317 setup_curvature_colors (pThis);
319 apply_left_right_eyes(surfs);
321 setup_current_surface_lights(surfs);
343 float minv[3],maxv[3];
348 VEC_COPY_47(minv,s->rr[0]);
349 VEC_COPY_47(maxv,s->rr[0]);
350 for (
k = 0;
k < s->np;
k++) {
352 for (c = 0; c < 3; c++) {
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]);
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]);
373 VEC_COPY_47(surf->minv,minv);
374 VEC_COPY_47(surf->maxv,maxv);
375 surf->fov_scale = 1.1f;
381 void MneMshDisplaySurfaceSet::decide_curv_display(
const char *name,
385 if (strstr(name,
"inflated") == name || strstr(name,
"sphere") == name || strstr(name,
"white") == name)
386 s->curvature_color_mode = SHOW_CURVATURE_OVERLAY;
388 s->curvature_color_mode = SHOW_CURVATURE_NONE;
389 s->overlay_color_mode = SHOW_OVERLAY_HEAT;
409 QByteArray baFilepath = filepath.toLatin1();
410 char* filename = baFilepath.data();
412 QByteArray baBemname = bemname.toLatin1();
413 char* name = baBemname.data();
416 qWarning(
"Cannot add to nonexisting surface set.");
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)
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);
434 newSurf->filename = MneSurfaceOld::mne_strdup(filename);
437 newSurf->s->id = kind;
438 newSurf->subj = Q_NULLPTR;
439 newSurf->surf_name = MneSurfaceOld::mne_strdup(name);
441 newSurf->curvature_color_mode = SHOW_CURVATURE_NONE;
442 newSurf->overlay_color_mode = SHOW_OVERLAY_HEAT;
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);
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;
481 surfs->surfs[
k] = newSurf;
483 surfs->active[
k] = FALSE;
484 surfs->drawable[
k] = FALSE;
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;
517 if (surf == NULL || surf->s == NULL)
522 ncolor = surf->nvertex_colors;
524 if (!surf->vertex_colors)
525 surf->vertex_colors = MALLOC_47(ncolor*s->np,
float);
526 col = surf->vertex_colors;
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;
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;
550 printf(
"Average curvature : %f\n",curv_sum/s->np);
566 if (neyes == 0 || current_eyes < 0 || current_eyes > neyes-1) {
567 eyes = &default_eyes;
569 eyes = all_eyes+current_eyes;
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);
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);
586 VEC_COPY_47(surf->eye,eyes->left);
587 VEC_COPY_47(surf->up,eyes->left_up);
600 if (surfs == Q_NULLPTR)
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);
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);
622 initialize_custom_lights();
623 setup_these_surface_lights(surfs,custom_lights);
629 void MneMshDisplaySurfaceSet::initialize_custom_lights()
631 if (!custom_lights) {
633 s->nlight = ndefault;
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);
645 s->lights = default_lights;
647 custom_lights = dup_light_set(s);
662 res->nlight = s->nlight;
664 for (
k = 0;
k < s->nlight;
k++)
676 delete surfs->lights;
677 surfs->lights = Q_NULLPTR;
678 surfs->lights = dup_light_set(set);