v2.0.0
Loading...
Searching...
No Matches
mne_surface_or_volume.cpp
Go to the documentation of this file.
1//=============================================================================================================
36
37//=============================================================================================================
38// INCLUDES
39//=============================================================================================================
40
42#include "mne_surface.h"
43#include "mne_source_space.h"
44#include "mne_patch_info.h"
45//#include "fwd_bem_model.h"
46#include "mne_nearest.h"
47#include "filter_thread_arg.h"
48#include "mne_triangle.h"
50#include "mne_proj_data.h"
51#include "mne_vol_geom.h"
52#include "mne_mgh_tag_group.h"
53#include "mne_mgh_tag.h"
54
55#include <fiff/fiff_stream.h>
58#include <fiff/fiff_dig_point.h>
59
60#include <utils/sphere.h>
61#include <utils/ioutils.h>
62
63#include <QFile>
64#include <QTextStream>
65#include <QCoreApplication>
66#include <QtConcurrent>
67
68#define _USE_MATH_DEFINES
69#include <math.h>
70
71#include <Eigen/Dense>
72#include <Eigen/Sparse>
73
74#include <algorithm>
75
76//ToDo don't use access and unlink -> use QT stuff instead
77#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
78#include <io.h>
79#else
80#include <unistd.h>
81#endif
82
83//=============================================================================================================
84// USED NAMESPACES
85//=============================================================================================================
86
87using namespace Eigen;
88using namespace FIFFLIB;
89using namespace MNELIB;
90
91//============================= dot.h =============================
92
93#ifndef TRUE
94#define TRUE 1
95#endif
96
97#ifndef FALSE
98#define FALSE 0
99#endif
100
101#ifndef FAIL
102#define FAIL -1
103#endif
104
105#ifndef OK
106#define OK 0
107#endif
108
109#define X_17 0
110#define Y_17 1
111#define Z_17 2
112
113#define VEC_DOT_17(x,y) ((x)[X_17]*(y)[X_17] + (x)[Y_17]*(y)[Y_17] + (x)[Z_17]*(y)[Z_17])
114
115#define VEC_LEN_17(x) sqrt(VEC_DOT_17(x,x))
116
117#define VEC_DIFF_17(from,to,diff) {\
118 (diff)[X_17] = (to)[X_17] - (from)[X_17];\
119 (diff)[Y_17] = (to)[Y_17] - (from)[Y_17];\
120 (diff)[Z_17] = (to)[Z_17] - (from)[Z_17];\
121 }
122
123#define VEC_COPY_17(to,from) {\
124 (to)[X_17] = (from)[X_17];\
125 (to)[Y_17] = (from)[Y_17];\
126 (to)[Z_17] = (from)[Z_17];\
127 }
128
129#define CROSS_PRODUCT_17(x,y,xy) {\
130 (xy)[X_17] = (x)[Y_17]*(y)[Z_17]-(y)[Y_17]*(x)[Z_17];\
131 (xy)[Y_17] = -((x)[X_17]*(y)[Z_17]-(y)[X_17]*(x)[Z_17]);\
132 (xy)[Z_17] = (x)[X_17]*(y)[Y_17]-(y)[X_17]*(x)[Y_17];\
133 }
134
135#define MALLOC_17(x,t) (t *)malloc((x)*sizeof(t))
136
137#define REALLOC_17(x,y,t) (t *)((x == NULL) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t)))
138
139#define ALLOC_INT_17(x) MALLOC_17(x,int)
140
141#define ALLOC_CMATRIX_17(x,y) mne_cmatrix_17((x),(y))
142
143static void matrix_error_17(int kind, int nr, int nc)
144
145{
146 if (kind == 1)
147 printf("Failed to allocate memory pointers for a %d x %d matrix\n",nr,nc);
148 else if (kind == 2)
149 printf("Failed to allocate memory for a %d x %d matrix\n",nr,nc);
150 else
151 printf("Allocation error for a %d x %d matrix\n",nr,nc);
152 if (sizeof(void *) == 4) {
153 printf("This is probably because you seem to be using a computer with 32-bit architecture.\n");
154 printf("Please consider moving to a 64-bit platform.");
155 }
156 printf("Cannot continue. Sorry.\n");
157 exit(1);
158}
159
160float** mne_cmatrix_17(int numPoints,int numDim)
161{
162 float** m;
163 float* whole;
164
165 m = MALLOC_17(numPoints, float *);
166 if (!m)
167 {
168 matrix_error_17( 1, numPoints, numDim);
169 }
170
171 whole = MALLOC_17( numPoints * numDim, float);
172 if (!whole)
173 {
174 matrix_error_17(2, numPoints, numDim);
175 }
176
177 for(int i = 0; i < numPoints; ++i)
178 {
179 m[i] = &whole[ i * numDim ];
180 }
181
182 return m;
183}
184
185#define FREE_17(x) if ((char *)(x) != NULL) free((char *)(x))
186
187#define FREE_CMATRIX_17(m) mne_free_cmatrix_17((m))
188
189#define FREE_ICMATRIX_17(m) mne_free_icmatrix_17((m))
190
191void mne_free_cmatrix_17 (float **m)
192{
193 if (m) {
194 FREE_17(*m);
195 FREE_17(m);
196 }
197}
198
200
201{
202 if (m) {
203 FREE_17(*m);
204 FREE_17(m);
205 }
206}
207
208#define NNEIGHBORS 26
209
210#define CURVATURE_FILE_MAGIC_NUMBER (16777215)
211
212#define TAG_MGH_XFORM 31
213#define TAG_SURF_GEOM 21
214#define TAG_OLD_USEREALRAS 2
215#define TAG_COLORTABLE 5
216#define TAG_OLD_MGH_XFORM 30
217#define TAG_OLD_COLORTABLE 1
218
219#define TAG_USEREALRAS 4
220
221#define ALLOC_ICMATRIX_17(x,y) mne_imatrix_17((x),(y))
222
223int **mne_imatrix_17(int nr,int nc)
224
225{
226 int i,**m;
227 int *whole;
228
229 m = MALLOC_17(nr,int *);
230 if (!m) matrix_error_17(1,nr,nc);
231 whole = MALLOC_17(nr*nc,int);
232 if (!whole) matrix_error_17(2,nr,nc);
233 for(i=0;i<nr;i++)
234 m[i] = whole + i*nc;
235 return m;
236}
237
238//float
239Eigen::MatrixXf toFloatEigenMatrix_17(float **mat, const int m, const int n)
240{
241 Eigen::MatrixXf eigen_mat(m,n);
242
243 for ( int i = 0; i < m; ++i)
244 for ( int j = 0; j < n; ++j)
245 eigen_mat(i,j) = mat[i][j];
246
247 return eigen_mat;
248}
249
250void fromFloatEigenMatrix_17(const Eigen::MatrixXf& from_mat, float **& to_mat, const int m, const int n)
251{
252 for ( int i = 0; i < m; ++i)
253 for ( int j = 0; j < n; ++j)
254 to_mat[i][j] = from_mat(i,j);
255}
256
257void fromFloatEigenMatrix_17(const Eigen::MatrixXf& from_mat, float **& to_mat)
258{
259 fromFloatEigenMatrix_17(from_mat, to_mat, from_mat.rows(), from_mat.cols());
260}
261
262void fromIntEigenMatrix_17(const Eigen::MatrixXi& from_mat, int **&to_mat, const int m, const int n)
263{
264 for ( int i = 0; i < m; ++i)
265 for ( int j = 0; j < n; ++j)
266 to_mat[i][j] = from_mat(i,j);
267}
268
269void fromIntEigenMatrix_17(const Eigen::MatrixXi& from_mat, int **&to_mat)
270{
271 fromIntEigenMatrix_17(from_mat, to_mat, from_mat.rows(), from_mat.cols());
272}
273
274//============================= make_volume_source_space.c =============================
275
276static std::optional<FiffCoordTrans> make_voxel_ras_trans(float *r0,
277 float *x_ras,
278 float *y_ras,
279 float *z_ras,
280 float *voxel_size)
281
282{
283 float rot[3][3],move[3];
284 int j,k;
285
286 VEC_COPY_17(move,r0);
287
288 for (j = 0; j < 3; j++) {
289 rot[j][0] = x_ras[j];
290 rot[j][1] = y_ras[j];
291 rot[j][2] = z_ras[j];
292 }
293
294 for (j = 0; j < 3; j++)
295 for (k = 0; k < 3; k++)
296 rot[j][k] = voxel_size[k]*rot[j][k];
297
299 Eigen::Map<Eigen::Matrix3f>(&rot[0][0]),
300 Eigen::Map<Eigen::Vector3f>(move));
301}
302
303//=============================================================================================================
304// DEFINE MEMBER METHODS
305//=============================================================================================================
306
310
311//=============================================================================================================
312
314{
315 if (curv.size() > 0)
316 return;
317 curv = Eigen::VectorXf::Ones(np);
318}
319
320//=============================================================================================================
321
323{
324 // rr, nn, itris, use_itris are Eigen matrices — auto-cleanup
325 // inuse, vertno are Eigen VectorXi — auto-cleanup
326 // tris, use_tris are std::vector<MNETriangle> — auto-cleanup
327 // neighbor_tri is std::vector<VectorXi> — auto-cleanup
328 // nneighbor_tri is Eigen VectorXi — auto-cleanup
329 // curv is Eigen VectorXf — auto-cleanup
330
331 // neighbor_vert is std::vector<VectorXi> — auto-cleanup
332 // nneighbor_vert is Eigen VectorXi — auto-cleanup
333 // vert_dist is std::vector<VectorXf> — auto-cleanup
334 // nearest is std::vector<MNENearest> — auto-cleanup
335 // patches is std::vector<optional<MNEPatchInfo>> — auto-cleanup
336 // dist is FiffSparseMatrix value, interpolator/vol_geom/mgh_tags are optional — auto-cleanup
337 // voxel_surf_RAS_t, MRI_voxel_surf_RAS_t, MRI_surf_RAS_RAS_t are optional — auto-cleanup
338 this->MRI_volume.clear();
339}
340
341//=============================================================================================================
342
344{
345 Eigen::VectorXi result(static_cast<int>(nearest.size()));
346 for (int i = 0; i < result.size(); ++i)
347 result[i] = nearest[i].nearest;
348 return result;
349}
350
351//=============================================================================================================
352
354{
355 Eigen::VectorXd result(static_cast<int>(nearest.size()));
356 for (int i = 0; i < result.size(); ++i)
357 result[i] = static_cast<double>(nearest[i].dist);
358 return result;
359}
360
361//=============================================================================================================
362
363void MNESurfaceOrVolume::setNearestData(const Eigen::VectorXi& nearestIdx, const Eigen::VectorXd& nearestDist)
364{
365 const int n = nearestIdx.size();
366 nearest.resize(n);
367 for (int i = 0; i < n; ++i) {
368 nearest[i].vert = i;
369 nearest[i].nearest = nearestIdx[i];
370 nearest[i].dist = static_cast<float>(nearestDist[i]);
371 nearest[i].patch = nullptr;
372 }
373}
374
375//=============================================================================================================
376
377double MNESurfaceOrVolume::solid_angle(const Eigen::Vector3f& from, const MNETriangle& tri) /* ...to this triangle */
378/*
379 * Compute the solid angle according to van Oosterom's
380 * formula
381 */
382{
383 double v1[3],v2[3],v3[3];
384 double l1,l2,l3,s,triple;
385 double cross[3];
386
387 VEC_DIFF_17 (from,tri.r1,v1);
388 VEC_DIFF_17 (from,tri.r2,v2);
389 VEC_DIFF_17 (from,tri.r3,v3);
390
391 CROSS_PRODUCT_17(v1,v2,cross);
392 triple = VEC_DOT_17(cross,v3);
393
394 l1 = VEC_LEN_17(v1);
395 l2 = VEC_LEN_17(v2);
396 l3 = VEC_LEN_17(v3);
397 s = (l1*l2*l3+VEC_DOT_17(v1,v2)*l3+VEC_DOT_17(v1,v3)*l2+VEC_DOT_17(v2,v3)*l1);
398
399 return (2.0*atan2(triple,s));
400}
401
402//=============================================================================================================
403
405/*
406 * Add the triangle data structures
407 */
408{
409 int k;
410 MNETriangle* tri;
411
413 return;
414
415 tris.clear();
416 use_tris.clear();
417 /*
418 * Add information for the complete triangulation
419 */
420 if (itris.rows() > 0 && ntri > 0) {
421 tris.resize(ntri);
422 tot_area = 0.0;
423 for (k = 0, tri = tris.data(); k < ntri; k++, tri++) {
424 tri->vert = &itris(k,0);
425 tri->r1 = &rr(tri->vert[0],0);
426 tri->r2 = &rr(tri->vert[1],0);
427 tri->r3 = &rr(tri->vert[2],0);
428 tri->compute_data();
429 tot_area += tri->area;
430 }
431#ifdef TRIANGLE_SIZE_WARNING
432 for (k = 0, tri = tris.data(); k < ntri; k++, tri++)
433 if (tri->area < 1e-5*tot_area/ntri)
434 printf("Warning: Triangle area is only %g um^2 (%.5f %% of expected average)\n",
435 1e12*tri->area,100*ntri*tri->area/tot_area);
436#endif
437 }
438#ifdef DEBUG
439 printf("\ttotal area = %-.1f cm^2\n",1e4*tot_area);
440#endif
441 /*
442 * Add information for the selected subset if applicable
443 */
444 if (use_itris.rows() > 0 && nuse_tri > 0) {
445 use_tris.resize(nuse_tri);
446 for (k = 0, tri = use_tris.data(); k < nuse_tri; k++, tri++) {
447 tri->vert = &use_itris(k,0);
448 tri->r1 = &rr(tri->vert[0],0);
449 tri->r2 = &rr(tri->vert[1],0);
450 tri->r3 = &rr(tri->vert[2],0);
451 tri->compute_data();
452 }
453 }
454 return;
455}
456
457//=============================================================================================================
458
460/*
461 * Compute the center of mass of a set of points
462 */
463{
464 int q;
465 cm[0] = cm[1] = cm[2] = 0.0;
466 for (q = 0; q < np; q++) {
467 cm[0] += rr(q,0);
468 cm[1] += rr(q,1);
469 cm[2] += rr(q,2);
470 }
471 if (np > 0) {
472 cm[0] = cm[0]/np;
473 cm[1] = cm[1]/np;
474 cm[2] = cm[2]/np;
475 }
476 return;
477}
478
479//=============================================================================================================
480
482/*
483 * Compute the center of mass of a surface
484 */
485{
487 return;
488}
489
490//=============================================================================================================
491
493{
494 int k,p,ndist;
495 float diff[3];
496 int nneigh;
497
498 if (neighbor_vert.empty() || nneighbor_vert.size() == 0)
499 return;
500
501 vert_dist.clear();
502 vert_dist.resize(np);
503 printf("\tDistances between neighboring vertices...");
504 for (k = 0, ndist = 0; k < np; k++) {
505 nneigh = nneighbor_vert[k];
506 vert_dist[k] = Eigen::VectorXf(nneigh);
507 const Eigen::VectorXi& neigh = neighbor_vert[k];
508 for (p = 0; p < nneigh; p++) {
509 if (neigh[p] >= 0) {
510 VEC_DIFF_17(&rr(k,0),&rr(neigh[p],0),diff);
511 vert_dist[k][p] = VEC_LEN_17(diff);
512 }
513 else
514 vert_dist[k][p] = -1.0;
515 ndist++;
516 }
517 }
518 printf("[%d distances done]\n",ndist);
519 return;
520}
521
522//=============================================================================================================
523
525{
526 int k,c,p;
527 int *ii;
528 float w,size;
529 MNETriangle* tri;
530
532 return OK;
533 /*
534 * Reallocate the stuff and initialize
535 */
536 nn = MNESurfaceOrVolume::NormalsT::Zero(np,3);
537
538 for (k = 0; k < np; k++) {
539 nn(k,X_17) = nn(k,Y_17) = nn(k,Z_17) = 0.0;
540 }
541 /*
542 * One pass through the triangles will do it
543 */
545 for (p = 0, tri = tris.data(); p < ntri; p++, tri++) {
546 ii = tri->vert;
547 w = 1.0; /* This should be related to the triangle size */
548 /*
549 * Then the vertex normals
550 */
551 for (k = 0; k < 3; k++)
552 for (c = 0; c < 3; c++)
553 nn(ii[k],c) += w*tri->nn[c];
554 }
555 for (k = 0; k < np; k++) {
556 size = VEC_LEN_17(&nn(k,0));
557 if (size > 0.0)
558 for (c = 0; c < 3; c++)
559 nn(k,c) = nn(k,c)/size;
560 }
562 return OK;
563}
564
565//=============================================================================================================
566
567int MNESurfaceOrVolume::add_geometry_info(int do_normals, int check_too_many_neighbors)
568/*
569 * Add vertex normals and neighbourhood information
570 */
571{
572 int k,c,p,q;
573 int vert;
574 int *ii;
575 int nneighbors;
576 float w,size;
577 int found;
578 int nfix_distinct,nfix_no_neighbors,nfix_defect;
579 MNETriangle* tri;
580
583 return OK;
584 }
586 return OK;
587 /*
588 * Reallocate the stuff and initialize
589 */
590 if (do_normals) {
591 nn = MNESurfaceOrVolume::NormalsT::Zero(np,3);
592 }
593 neighbor_tri.clear();
594 neighbor_tri.resize(np);
595 nneighbor_tri = Eigen::VectorXi::Zero(np);
596
597 for (k = 0; k < np; k++) {
598 if (do_normals)
599 nn(k,X_17) = nn(k,Y_17) = nn(k,Z_17) = 0.0;
600 }
601 /*
602 * One pass through the triangles will do it
603 */
605 for (p = 0, tri = tris.data(); p < ntri; p++, tri++)
606 if (tri->area == 0)
607 printf("\tWarning : zero size triangle # %d\n",p);
608 printf("\tTriangle ");
609 if (do_normals)
610 printf("and vertex ");
611 printf("normals and neighboring triangles...");
612 for (p = 0, tri = tris.data(); p < ntri; p++, tri++) {
613 ii = tri->vert;
614 w = 1.0; /* This should be related to the triangle size */
615 for (k = 0; k < 3; k++) {
616 /*
617 * Then the vertex normals
618 */
619 if (do_normals)
620 for (c = 0; c < 3; c++)
621 nn(ii[k],c) += w*tri->nn[c];
622 /*
623 * Add to the list of neighbors
624 */
625 neighbor_tri[ii[k]].conservativeResize(nneighbor_tri[ii[k]]+1);
626 neighbor_tri[ii[k]][nneighbor_tri[ii[k]]] = p;
627 nneighbor_tri[ii[k]]++;
628 }
629 }
630 nfix_no_neighbors = 0;
631 nfix_defect = 0;
632 for (k = 0; k < np; k++) {
633 if (nneighbor_tri[k] <= 0) {
634#ifdef STRICT_ERROR
635 err_printf_set_error("Vertex %d does not have any neighboring triangles!",k);
636 return FAIL;
637#else
638#ifdef REPORT_WARNINGS
639 printf("Warning: Vertex %d does not have any neighboring triangles!\n",k);
640#endif
641#endif
642 nfix_no_neighbors++;
643 }
644 else if (nneighbor_tri[k] < 3) {
645#ifdef REPORT_WARNINGS
646 printf("\n\tTopological defect: Vertex %d has only %d neighboring triangle%s Vertex omitted.\n\t",
647 k,nneighbor_tri[k],nneighbor_tri[k] > 1 ? "s." : ".");
648#endif
649 nfix_defect++;
650 nneighbor_tri[k] = 0;
651 neighbor_tri[k].resize(0);
652 }
653 }
654 /*
655 * Scale the vertex normals to unit length
656 */
657 for (k = 0; k < np; k++)
658 if (nneighbor_tri[k] > 0) {
659 size = VEC_LEN_17(&nn(k,0));
660 if (size > 0.0)
661 for (c = 0; c < 3; c++)
662 nn(k,c) = nn(k,c)/size;
663 }
664 printf("[done]\n");
665 /*
666 * Determine the neighboring vertices
667 */
668 printf("\tVertex neighbors...");
669 neighbor_vert.clear();
670 neighbor_vert.resize(np);
671 nneighbor_vert = VectorXi::Zero(np);
672 /*
673 * We know the number of neighbors beforehand
674 */
675 for (k = 0; k < np; k++) {
676 if (nneighbor_tri[k] > 0) {
677 neighbor_vert[k] = VectorXi(nneighbor_tri[k]);
679 }
680 else {
681 nneighbor_vert[k] = 0;
682 }
683 }
684 nfix_distinct = 0;
685 for (k = 0; k < np; k++) {
686 Eigen::VectorXi& neighbors = neighbor_vert[k];
687 nneighbors = 0;
688 for (p = 0; p < nneighbor_tri[k]; p++) {
689 /*
690 * Fit in the other vertices of the neighboring triangle
691 */
692 for (c = 0; c < 3; c++) {
693 vert = tris[neighbor_tri[k][p]].vert[c];
694 if (vert != k) {
695 for (q = 0, found = FALSE; q < nneighbors; q++) {
696 if (neighbors[q] == vert) {
697 found = TRUE;
698 break;
699 }
700 }
701 if (!found) {
702 if (nneighbors < nneighbor_vert[k])
703 neighbors[nneighbors++] = vert;
704 else {
705 if (check_too_many_neighbors) {
706 printf("Too many neighbors for vertex %d.",k);
707 return FAIL;
708 }
709 else
710 printf("\tWarning: Too many neighbors for vertex %d\n",k);
711 }
712 }
713 }
714 }
715 }
716 if (nneighbors != nneighbor_vert[k]) {
717#ifdef REPORT_WARNINGS
718 printf("\n\tIncorrect number of distinct neighbors for vertex %d (%d instead of %d) [fixed].",
719 k,nneighbors,nneighbor_vert[k]);
720#endif
721 nfix_distinct++;
722 nneighbor_vert[k] = nneighbors;
723 }
724 }
725 printf("[done]\n");
726 /*
727 * Distance calculation follows
728 */
731 /*
732 * Summarize the defects
733 */
734 if (nfix_defect > 0)
735 printf("\tWarning: %d topological defects were fixed.\n",nfix_defect);
736 if (nfix_distinct > 0)
737 printf("\tWarning: %d vertices had incorrect number of distinct neighbors (fixed).\n",nfix_distinct);
738 if (nfix_no_neighbors > 0)
739 printf("\tWarning: %d vertices did not have any neighboring triangles (fixed)\n",nfix_no_neighbors);
740#ifdef DEBUG
741 for (k = 0; k < np; k++) {
742 if (nneighbor_vert[k] <= 0)
743 printf("No neighbors for vertex %d\n",k);
744 if (nneighbor_tri[k] <= 0)
745 printf("No neighbor tris for vertex %d\n",k);
746 }
747#endif
748 return OK;
749}
750
751//=============================================================================================================
752
754{
755 return add_geometry_info(do_normals,TRUE);
756}
757
758//=============================================================================================================
759
761
762{
763 return add_geometry_info(do_normals,FALSE);
764}
765
766//=============================================================================================================
#define FIFFV_MNE_COORD_MRI_VOXEL
#define FIFFV_COORD_MRI
FiffStream class declaration.
FiffDigitizerData class declaration.
FiffCoordTrans class declaration.
FiffDigPoint class declaration.
IOUtils class declaration.
Sphere class declaration.
MNETriangle class declaration.
#define MALLOC_17(x, t)
#define VEC_COPY_17(to, from)
void fromIntEigenMatrix_17(const Eigen::MatrixXi &from_mat, int **&to_mat, const int m, const int n)
float ** mne_cmatrix_17(int numPoints, int numDim)
#define FREE_17(x)
int ** mne_imatrix_17(int nr, int nc)
void mne_free_cmatrix_17(float **m)
void fromFloatEigenMatrix_17(const Eigen::MatrixXf &from_mat, float **&to_mat, const int m, const int n)
Eigen::MatrixXf toFloatEigenMatrix_17(float **mat, const int m, const int n)
void mne_free_icmatrix_17(int **m)
MNEMghTagGroup class declaration.
MNEVolGeom class declaration.
Filter Thread Argument (FilterThreadArg) class declaration.
MNE Patch Information (MNEPatchInfo) class declaration.
#define MNE_SOURCE_SPACE_SURFACE
Definition mne_types.h:103
#define MNE_SOURCE_SPACE_VOLUME
Definition mne_types.h:104
MNESurface class declaration.
#define Z_17
#define Y_17
#define X_17
#define CROSS_PRODUCT_17(x, y, xy)
#define VEC_DIFF_17(from, to, diff)
#define VEC_LEN_17(x)
#define VEC_DOT_17(x, y)
MNEMghTag class declaration.
MNEMshDisplaySurface class declaration.
MNEProjData class declaration.
MNENearest class declaration.
MNESourceSpace class declaration.
MNE Surface or Volume (MNESurfaceOrVolume) class declaration.
#define TRUE
#define FALSE
#define OK
#define FAIL
Core MNE data structures (source spaces, source estimates, hemispheres).
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
Coordinate transformation description.
std::vector< Eigen::VectorXi > neighbor_tri
void setNearestData(const Eigen::VectorXi &nearestIdx, const Eigen::VectorXd &nearestDist)
int add_geometry_info(int do_normals, int check_too_many_neighbors)
std::vector< Eigen::VectorXi > neighbor_vert
MNESurfaceOrVolume()
Constructs the MNE Surface or Volume.
Eigen::VectorXd nearestDistVec() const
FIFFLIB::FiffSparseMatrix dist
std::vector< MNENearest > nearest
static void compute_cm(const PointsT &rr, int np, float(&cm)[3])
static double solid_angle(const Eigen::Vector3f &from, const MNELIB::MNETriangle &tri)
virtual ~MNESurfaceOrVolume()
Destroys the MNE Surface or Volume description.
std::vector< MNETriangle > tris
std::vector< Eigen::VectorXf > vert_dist
Eigen::Matrix< float, Eigen::Dynamic, 3, Eigen::RowMajor > PointsT
Eigen::VectorXi nearestVertIdx() const
std::vector< MNETriangle > use_tris
Per-triangle geometric data for a cortical or BEM surface.
Eigen::Vector3f nn