65#include <QCoreApplication>
66#include <QtConcurrent>
69#define _USE_MATH_DEFINES
73#include <Eigen/Sparse>
103static std::optional<FiffCoordTrans> make_voxel_ras_trans(
const Eigen::Vector3f& r0,
104 const Eigen::Vector3f& x_ras,
105 const Eigen::Vector3f& y_ras,
106 const Eigen::Vector3f& z_ras,
107 const Eigen::Vector3f& voxel_size)
110 rot.row(0) = x_ras.transpose() * voxel_size[0];
111 rot.row(1) = y_ras.transpose() * voxel_size[1];
112 rot.row(2) = z_ras.transpose() * voxel_size[2];
131 curv = Eigen::VectorXf::Ones(
np);
159 Eigen::VectorXi result(
static_cast<int>(
nearest.size()));
160 for (
int i = 0; i < result.size(); ++i)
169 Eigen::VectorXd result(
static_cast<int>(
nearest.size()));
170 for (
int i = 0; i < result.size(); ++i)
179 const int n = nearestIdx.size();
181 for (
int i = 0; i < n; ++i) {
183 nearest[i].nearest = nearestIdx[i];
184 nearest[i].dist =
static_cast<float>(nearestDist[i]);
197 Eigen::Vector3d v1 = (tri.
r1 - from).cast<double>();
198 Eigen::Vector3d v2 = (tri.
r2 - from).cast<double>();
199 Eigen::Vector3d v3 = (tri.
r3 - from).cast<double>();
201 double triple = v1.cross(v2).dot(v3);
203 double l1 = v1.norm();
204 double l2 = v2.norm();
205 double l3 = v3.norm();
206 double s = (l1*l2*l3+v1.dot(v2)*l3+v1.dot(v3)*l2+v2.dot(v3)*l1);
208 return (2.0*atan2(triple,s));
232 for (k = 0, tri =
tris.data(); k <
ntri; k++, tri++) {
234 tri->
r1 =
rr.row(tri->
vert[0]).transpose();
235 tri->
r2 =
rr.row(tri->
vert[1]).transpose();
236 tri->
r3 =
rr.row(tri->
vert[2]).transpose();
240#ifdef TRIANGLE_SIZE_WARNING
241 for (k = 0, tri =
tris.data(); k <
ntri; k++, tri++)
243 qWarning(
"Warning: Triangle area is only %g um^2 (%.5f %% of expected average)\n",
248 qInfo(
"\ttotal area = %-.1f cm^2\n",1e4*
tot_area);
257 tri->
r1 =
rr.row(tri->
vert[0]).transpose();
258 tri->
r2 =
rr.row(tri->
vert[1]).transpose();
259 tri->
r3 =
rr.row(tri->
vert[2]).transpose();
274 cm[0] =
cm[1] =
cm[2] = 0.0;
275 for (q = 0; q <
np; q++) {
311 qInfo(
"\tDistances between neighboring vertices...");
312 for (k = 0, ndist = 0; k <
np; k++) {
316 for (p = 0; p < nneigh; p++) {
325 qInfo(
"[%d distances done]\n",ndist);
343 nn = MNESurfaceOrVolume::NormalsT::Zero(
np,3);
348 for (p = 0, tri =
tris.data(); p <
ntri; p++, tri++) {
354 for (k = 0; k < 3; k++)
355 for (c = 0; c < 3; c++)
356 nn(ii[k],c) += w*tri->
nn[c];
358 for (k = 0; k <
np; k++) {
359 size =
nn.row(k).norm();
380 int nfix_distinct,nfix_no_neighbors,nfix_defect;
393 nn = MNESurfaceOrVolume::NormalsT::Zero(
np,3);
404 for (p = 0, tri =
tris.data(); p <
ntri; p++, tri++)
406 qWarning(
"\tWarning : zero size triangle # %d\n",p);
407 qInfo(
"\tTriangle ");
409 qInfo(
"and vertex ");
410 qInfo(
"normals and neighboring triangles...");
411 for (p = 0, tri =
tris.data(); p <
ntri; p++, tri++) {
414 for (k = 0; k < 3; k++) {
419 for (c = 0; c < 3; c++)
420 nn(ii[k],c) += w*tri->
nn[c];
429 nfix_no_neighbors = 0;
431 for (k = 0; k <
np; k++) {
434 err_printf_set_error(
"Vertex %d does not have any neighboring triangles!",k);
437#ifdef REPORT_WARNINGS
438 qWarning(
"Warning: Vertex %d does not have any neighboring triangles!\n",k);
444#ifdef REPORT_WARNINGS
445 qWarning(
"\n\tTopological defect: Vertex %d has only %d neighboring triangle%s Vertex omitted.\n\t",
456 for (k = 0; k <
np; k++)
458 size =
nn.row(k).norm();
466 qInfo(
"\tVertex neighbors...");
473 for (k = 0; k <
np; k++) {
483 for (k = 0; k <
np; k++) {
490 for (c = 0; c < 3; c++) {
493 for (q = 0, found =
false; q < nneighbors; q++) {
494 if (neighbors[q] == vert) {
501 neighbors[nneighbors++] = vert;
503 if (check_too_many_neighbors) {
504 qCritical(
"Too many neighbors for vertex %d.",k);
508 qWarning(
"\tWarning: Too many neighbors for vertex %d\n",k);
515#ifdef REPORT_WARNINGS
516 qWarning(
"\n\tIncorrect number of distinct neighbors for vertex %d (%d instead of %d) [fixed].",
533 qWarning(
"\tWarning: %d topological defects were fixed.\n",nfix_defect);
534 if (nfix_distinct > 0)
535 qWarning(
"\tWarning: %d vertices had incorrect number of distinct neighbors (fixed).\n",nfix_distinct);
536 if (nfix_no_neighbors > 0)
537 qWarning(
"\tWarning: %d vertices did not have any neighboring triangles (fixed)\n",nfix_no_neighbors);
539 for (k = 0; k <
np; k++) {
541 qCritical(
"No neighbors for vertex %d\n",k);
543 qCritical(
"No neighbor tris for vertex %d\n",k);
IOUtils class declaration.
Sphere class declaration.
FiffDigitizerData class declaration.
FiffCoordTrans class declaration.
FiffStream class declaration.
#define FIFFV_MNE_COORD_MRI_VOXEL
FiffDigPoint class declaration.
#define MNE_SOURCE_SPACE_SURFACE
#define MNE_SOURCE_SPACE_VOLUME
MNESourceSpace class declaration.
MNEProjData class declaration.
MNE Patch Information (MNEPatchInfo) class declaration.
MNENearest class declaration.
MNE FsSurface or Volume (MNESurfaceOrVolume) class declaration.
MNEMshDisplaySurface class declaration.
MNEMghTagGroup class declaration.
MNEMghTag class declaration.
MNETriangle class declaration.
Filter Thread Argument (FilterThreadArg) class declaration.
MNESurface class declaration.
MNEVolGeom 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)
std::vector< Eigen::VectorXi > neighbor_vert
MNESurfaceOrVolume()
Constructs the MNE FsSurface or Volume.
Eigen::VectorXd nearestDistVec() const
int add_geometry_info(bool do_normals, bool check_too_many_neighbors)
FIFFLIB::FiffSparseMatrix dist
std::vector< MNENearest > nearest
Eigen::VectorXi nneighbor_vert
Eigen::VectorXi nneighbor_tri
void calculate_vertex_distances()
static void compute_cm(const PointsT &rr, int np, float(&cm)[3])
static double solid_angle(const Eigen::Vector3f &from, const MNELIB::MNETriangle &tri)
void compute_surface_cm()
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
int add_geometry_info2(bool do_normals)
Eigen::VectorXi nearestVertIdx() const
std::vector< MNETriangle > use_tris
Per-triangle geometric data for a cortical or BEM surface.