37#ifndef _USE_MATH_DEFINES
38#define _USE_MATH_DEFINES
57[[maybe_unused]]
constexpr int FAIL = -1;
58[[maybe_unused]]
constexpr int X = 0;
59[[maybe_unused]]
constexpr int Y = 1;
60[[maybe_unused]]
constexpr int Z = 2;
83 double tot_angle, angle;
84 for (k = 0, tot_angle = 0.0; k <
ntri; k++) {
95 double a, b, c, v1, v2, det;
98 this_tri = &
tris[tri];
100 Eigen::Vector3d rDiff = (r - this_tri->
r1).cast<double>();
101 z = rDiff.dot(this_tri->
nn.cast<
double>());
103 a = this_tri->
r12.cast<
double>().squaredNorm();
104 b = this_tri->
r13.cast<
double>().squaredNorm();
105 c = this_tri->
r12.cast<
double>().dot(this_tri->
r13.cast<
double>());
107 v1 = rDiff.dot(this_tri->
r12.cast<
double>());
108 v2 = rDiff.dot(this_tri->
r13.cast<
double>());
112 x = (b * v1 - c * v2) / det;
113 y = (a * v2 - c * v1) / det;
120 double p, q, p0, q0, t0;
121 double a, b, c, v1, v2, det;
122 double best, distance, dist0;
126 this_tri = &
tris[tri];
127 Eigen::Vector3d rDiff = (r - this_tri->
r1).cast<double>();
128 distance = rDiff.dot(this_tri->
nn.cast<
double>());
137 a = this_tri->
r12.cast<
double>().squaredNorm();
138 b = this_tri->
r13.cast<
double>().squaredNorm();
139 c = this_tri->
r12.cast<
double>().dot(this_tri->
r13.cast<
double>());
142 v1 = rDiff.dot(this_tri->
r12.cast<
double>());
143 v2 = rDiff.dot(this_tri->
r13.cast<
double>());
147 p = (b * v1 - c * v2) / det;
148 q = (a * v2 - c * v1) / det;
150 if (p >= 0.0 && p <= 1.0 &&
151 q >= 0.0 && q <= 1.0 &&
161 p0 = p + 0.5 * (q * c) / a;
167 dist0 = sqrt((p - p0) * (p - p0) * a +
168 (q - q0) * (q - q0) * b +
169 (p - p0) * (q - q0) * c +
170 distance * distance);
178 t0 = 0.5 * ((2.0 * a - c) * (1.0 - p) + (2.0 * b - c) * q) / (a + b - c);
185 dist0 = sqrt((p - p0) * (p - p0) * a +
186 (q - q0) * (q - q0) * b +
187 (p - p0) * (q - q0) * c +
188 distance * distance);
199 q0 = q + 0.5 * (p * c) / b;
204 dist0 = sqrt((p - p0) * (p - p0) * a +
205 (q - q0) * (q - q0) * b +
206 (p - p0) * (q - q0) * c +
207 distance * distance);
230 return Eigen::Vector3f(
231 this_tri->
r1 + p * this_tri->
r12 + q * this_tri->
r13);
238 float p, q, distance;
254 for (best = -1, k = 0; k <
ntri; k++) {
256 if (best < 0 || std::fabs(distance) < std::fabs(dist0)) {
269 Eigen::VectorXi& nearest_tri,
270 Eigen::VectorXf& distances,
int nstep)
const
272 auto p = std::make_unique<MNEProjData>(
this);
275 qInfo(
"%s for %d points %d steps...", nearest_tri[0] < 0 ?
"Closest" :
"Approx closest", np_points, nstep);
277 for (k = 0; k < np_points; k++) {
278 Eigen::Vector3f pt = Eigen::Map<const Eigen::Vector3f>(r.row(k).data());
281 if (nearest_tri[k] < 0) {
295 const Eigen::Vector3f& r)
const
298 Eigen::Vector3f diff_vec;
299 float dist_val, mindist;
302 for (k = 0; k <
ntri; k++)
305 if (approx_best < 0) {
308 for (k = 0; k <
np; k++) {
309 diff_vec =
rr.row(k).transpose() - r;
310 dist_val = diff_vec.norm();
318 diff_vec = this_tri->
r1 - r;
319 mindist = diff_vec.norm();
320 minvert = this_tri->
vert[0];
322 diff_vec = this_tri->
r2 - r;
323 dist_val = diff_vec.norm();
324 if (dist_val < mindist) {
326 minvert = this_tri->
vert[1];
328 diff_vec = this_tri->
r3 - r;
329 dist_val = diff_vec.norm();
330 if (dist_val < mindist) {
332 minvert = this_tri->
vert[2];
390 QList<FiffDirNode::SPtr> surfs;
391 QList<FiffDirNode::SPtr> bems;
396 int nnode, ntri_count;
398 std::unique_ptr<MNESurface> s_ptr;
400 MatrixXf tmp_node_normals;
402 float sigmaLocal = -1.0;
404 MatrixXi tmp_triangles;
409 bems = stream->dirtree()->dir_tree_find(
FIFFB_BEM);
410 if (bems.size() > 0) {
417 if (surfs.size() == 0) {
418 qCritical(
"No BEM surfaces found in %s", name.toUtf8().constData());
423 for (k = 0; k < surfs.size(); ++k) {
426 id = *t_pTag->toInt();
432 qCritical(
"Desired surface not found in %s", name.toUtf8().constData());
443 nnode = *t_pTag->toInt();
449 ntri_count = *t_pTag->toInt();
455 tmp_nodes = t_pTag->toFloatMatrix().transpose();
458 tmp_node_normals = t_pTag->toFloatMatrix().transpose();
465 tmp_triangles = t_pTag->toIntMatrix().transpose();
473 sigmaLocal = *t_pTag->toFloat();
478 s_ptr = std::make_unique<MNESurface>();
480 tmp_triangles.array() -= 1;
481 s->
itris = tmp_triangles;
483 s->
sigma = sigmaLocal;
486 if (tmp_node_normals.rows() > 0)
487 s->
nn = tmp_node_normals;
488 s->
ntri = ntri_count;
496 s->
cm[0] = s->
cm[1] = s->
cm[2] = 0.0;
499 if (check_too_many_neighbors) {
508 }
else if (s->
nn.rows() == 0) {
516 s->
inuse = Eigen::VectorXi::Ones(s->
np);
517 s->
vertno = Eigen::VectorXi::LinSpaced(s->
np, 0, s->
np - 1);
529 if (this->
sigma > 0.0)
constexpr auto FIFF_MNE_COORD_FRAME
constexpr auto FIFFV_MNE_SURF_UNKNOWN
constexpr auto FIFFV_COORD_MRI
constexpr auto FIFFV_MNE_SPACE_SURFACE
FIFF binary tag-stream layer: wraps a QIODevice to read and write FIFF tags, directories,...
4x4 affine FIFF coordinate transform (FIFF_COORD_TRANS) annotated with source/destination coordinate-...
constexpr auto FIFF_BEM_SURF_TRIANGLES
constexpr auto FIFF_BEM_SURF_NNODE
constexpr auto FIFF_BEM_SURF_NORMALS
constexpr auto FIFF_BEM_SIGMA
constexpr auto FIFF_BEM_SURF_NODES
constexpr auto FIFF_BEM_SURF_ID
constexpr auto FIFFB_BEM_SURF
constexpr auto FIFF_BEM_SURF_NTRI
constexpr auto FIFF_BEM_COORD_FRAME
Legacy MNE-C aggregator for SSP projections plus the channel list they apply to.
Triangle descriptor with cached centroid, area and normal vectors.
Lightweight triangulated surface (vertices, triangles, normals) used by surface-based routines.
Single-hemisphere source space (cortical surface or volume grid) loaded from FIFF.
Core MNE data structures (source spaces, source estimates, hemispheres).
FIFF file I/O, in-memory data structures and high-level readers/writers.
QSharedPointer< FiffDirNode > SPtr
FIFF tag-stream reader/writer: wraps a QIODevice and exposes typed read_* / write_* methods for every...
fiff_long_t write_float_matrix(fiff_int_t kind, const Eigen::MatrixXf &mat)
fiff_long_t write_int_matrix(fiff_int_t kind, const Eigen::MatrixXi &mat)
QSharedPointer< FiffStream > SPtr
fiff_long_t write_int(fiff_int_t kind, const fiff_int_t *data, fiff_int_t nel=1, fiff_int_t next=FIFFV_NEXT_SEQ)
fiff_long_t write_float(fiff_int_t kind, const float *data, fiff_int_t nel=1)
std::unique_ptr< FiffTag > UPtr
Auxiliary projection data computed from MNEProjOp for efficient repeated application.
double sum_solids(const Eigen::Vector3f &from) const
Eigen::Vector3f project_to_triangle(int tri, float p, float q) const
static std::unique_ptr< MNESurface > read_bem_surface2(const QString &name, int which, bool add_geometry)
void triangle_coords(const Eigen::Vector3f &r, int tri, float &x, float &y, float &z) const
static std::unique_ptr< MNESurface > read_bem_surface(const QString &name, int which, bool add_geometry)
void find_closest_on_surface_approx(const PointsT &r, int np, Eigen::VectorXi &nearest_tri, Eigen::VectorXf &distances, int nstep) const
int project_to_surface(const MNEProjData *proj_data, const Eigen::Vector3f &r, float &distp) const
void decide_search_restriction(MNEProjData &p, int approx_best, int nstep, const Eigen::Vector3f &r) const
void writeToStream(FIFFLIB::FiffStream *p_pStream)
int nearest_triangle_point(const Eigen::Vector3f &r, const MNEProjData *user, int tri, float &x, float &y, float &z) const
void activate_neighbors(int start, Eigen::VectorXi &act, int nstep) const
std::vector< Eigen::VectorXi > neighbor_tri
std::vector< Eigen::VectorXi > neighbor_vert
int add_geometry_info(bool do_normals, bool check_too_many_neighbors)
Eigen::VectorXi nneighbor_vert
Eigen::VectorXi nneighbor_tri
static double solid_angle(const Eigen::Vector3f &from, const MNELIB::MNETriangle &tri)
std::vector< MNETriangle > tris
Eigen::Matrix< float, Eigen::Dynamic, 3, Eigen::RowMajor > PointsT
int add_geometry_info2(bool do_normals)
Per-triangle geometric data for a cortical or BEM surface.