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 <math/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.row(tri->vert[0]);
426 tri->r2 = rr.row(tri->vert[1]);
427 tri->r3 = rr.row(tri->vert[2]);
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.row(tri->vert[0]);
449 tri->r2 = rr.row(tri->vert[1]);
450 tri->r3 = rr.row(tri->vert[2]);
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 TRUE
#define FALSE
#define OK
#define FAIL
#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.
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 FsSurface or Volume (MNESurfaceOrVolume) class declaration.
Sphere class declaration.
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 FsSurface 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 FsSurface 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
Eigen::Vector3f r2
Eigen::Vector3f r1
Eigen::Vector3f r3