v2.0.0
Loading...
Searching...
No Matches
mne_bem_surface.cpp
Go to the documentation of this file.
1//=============================================================================================================
36
37//=============================================================================================================
38// INCLUDES
39//=============================================================================================================
40
41#include "mne_bem_surface.h"
42#include <fstream>
43
44//=============================================================================================================
45// USED NAMESPACES
46//=============================================================================================================
47
48using namespace MNELIB;
49using namespace Eigen;
50using namespace FIFFLIB;
51
52//=============================================================================================================
53// DEFINE MEMBER METHODS
54//=============================================================================================================
55
57: MNESurface()
58, tri_cent(MatrixX3d::Zero(0,3))
59, tri_nn(MatrixX3d::Zero(0,3))
60, tri_area(VectorXd::Zero(0))
61{
62 id = -1;
63 np = -1;
64 ntri = -1;
65 coord_frame = -1;
66 sigma = -1;
67}
68
69//=============================================================================================================
70
72: MNESurface()
73, tri_cent(p_MNEBemSurface.tri_cent)
74, tri_nn(p_MNEBemSurface.tri_nn)
75, tri_area(p_MNEBemSurface.tri_area)
76{
77 id = p_MNEBemSurface.id;
78 np = p_MNEBemSurface.np;
79 ntri = p_MNEBemSurface.ntri;
80 coord_frame = p_MNEBemSurface.coord_frame;
81 sigma = p_MNEBemSurface.sigma;
82 rr = p_MNEBemSurface.rr;
83 nn = p_MNEBemSurface.nn;
84 itris = p_MNEBemSurface.itris;
85 neighbor_tri = p_MNEBemSurface.neighbor_tri;
86 neighbor_vert = p_MNEBemSurface.neighbor_vert;
87}
88
89//=============================================================================================================
90
94
95//=============================================================================================================
96
98{
99 id = -1;
100 np = -1;
101 ntri = -1;
102 coord_frame = -1;
103 sigma = -1;
104 rr.resize(0, 3);
105 nn.resize(0, 3);
106 itris.resize(0, 3);
107 tri_cent = MatrixX3d::Zero(0,3);
108 tri_nn = MatrixX3d::Zero(0,3);
109 tri_area = VectorXd::Zero(0);
110 neighbor_tri.clear();
111 neighbor_vert.clear();
112}
113
114//=============================================================================================================
115
117{
118 //
119 // Main triangulation
120 //
121 printf("\tCompleting triangulation info...");
122 this->tri_cent = MatrixX3d::Zero(this->ntri,3);
123 this->tri_nn = MatrixX3d::Zero(this->ntri,3);
124 this->tri_area = VectorXd::Zero(this->ntri);
125
126 Matrix3d r;
127 Vector3d a, b;
128 int k = 0;
129 float size = 0;
130 for (qint32 i = 0; i < this->ntri; ++i)
131 {
132 for ( qint32 j = 0; j < 3; ++j)
133 {
134 k = this->itris(i, j);
135
136 r(j,0) = this->rr(k, 0);
137 r(j,1) = this->rr(k, 1);
138 r(j,2) = this->rr(k, 2);
139
140 this->tri_cent(i, 0) += this->rr(k, 0);
141 this->tri_cent(i, 1) += this->rr(k, 1);
142 this->tri_cent(i, 2) += this->rr(k, 2);
143 }
144 this->tri_cent.row(i) /= 3.0f;
145
146 //cross product {cross((r2-r1),(r3-r1))}
147 a = r.row(1) - r.row(0 );
148 b = r.row(2) - r.row(0);
149 this->tri_nn(i,0) = a(1)*b(2)-a(2)*b(1);
150 this->tri_nn(i,1) = a(2)*b(0)-a(0)*b(2);
151 this->tri_nn(i,2) = a(0)*b(1)-a(1)*b(0);
152
153 //area
154 size = this->tri_nn.row(i)*this->tri_nn.row(i).transpose();
155 size = std::pow(size, 0.5f );
156
157 this->tri_area(i) = size/2.0f;
158 this->tri_nn.row(i) /= size;
159 }
160
161 std::fstream doc("./Output/tri_area.dat", std::ofstream::out | std::ofstream::trunc);
162 if(doc) // if succesfully opened
163 {
164 // instructions
165 doc << this->tri_area << "\n";
166 doc.close();
167 }
168
169 printf("Adding additional geometry info\n");
171
172 printf("[done]\n");
173
174 return true;
175}
176
177//=============================================================================================================
178
180{
181 int k,c,p,q;
182 bool found;
183
184 //Create neighboring triangle vector using temporary std::vector for efficient appending
185 {
186 std::vector<std::vector<int>> temp_ntri(this->itris.rows());
187 for (p = 0; p < this->itris.rows(); p++) {
188 for (k = 0; k < 3; k++) {
189 temp_ntri[this->itris(p,k)].push_back(p);
190 }
191 }
192 neighbor_tri.resize(this->itris.rows());
193 for (k = 0; k < static_cast<int>(temp_ntri.size()); k++) {
194 neighbor_tri[k] = Eigen::Map<Eigen::VectorXi>(temp_ntri[k].data(), temp_ntri[k].size());
195 }
196 }
197
198 //Create the neighboring vertices vector using temporary std::vector
199 {
200 std::vector<std::vector<int>> temp_nvert(this->np);
201 for (k = 0; k < this->np; k++) {
202 for (p = 0; p < neighbor_tri[k].size(); p++) {
203 //Fit in the other vertices of the neighboring triangle
204 for (c = 0; c < 3; c++) {
205 int vert = this->itris(neighbor_tri[k][p], c);
206
207 if (vert != k) {
208 found = false;
209
210 for (q = 0; q < static_cast<int>(temp_nvert[k].size()); q++) {
211 if (temp_nvert[k][q] == vert) {
212 found = true;
213 break;
214 }
215 }
216
217 if(!found) {
218 temp_nvert[k].push_back(vert);
219 }
220 }
221 }
222 }
223 }
224 neighbor_vert.resize(this->np);
225 for (k = 0; k < this->np; k++) {
226 neighbor_vert[k] = Eigen::Map<Eigen::VectorXi>(temp_nvert[k].data(), temp_nvert[k].size());
227 }
228 }
229
230 return true;
231}
232
233//=============================================================================================================
234
236{
237
238 //
239 // Accumulate the vertex normals
240 //
241
242// this->nn.resize(this->np,3);
243
244 for (qint32 p = 0; p < this->ntri; ++p) //check each triangle
245 {
246 for (qint32 j = 0; j < 3 ; ++j)
247 {
248 int nodenr;
249 nodenr = this->itris(p,j); //find the corners(nodes) of the triangles
250 this->nn(nodenr,0) += this->tri_nn(p,0); //add the triangle normal to the nodenormal
251 this->nn(nodenr,1) += this->tri_nn(p,1);
252 this->nn(nodenr,2) += this->tri_nn(p,2);
253 }
254 }
255
256 // normalize
257 for (qint32 p = 0; p < this->np; ++p)
258 {
259 float size = 0;
260 size = this->nn.row(p)*this->nn.row(p).transpose();
261 size = std::pow(size, 0.5f );
262 this->nn.row(p) /= size;
263 }
264
265return true;
266}
267
268//=============================================================================================================
269
271{
272 if(this->id <=0)
273 this->id=FIFFV_MNE_SURF_UNKNOWN;
274 if(this->sigma>0.0)
275 p_pStream->write_float(FIFF_BEM_SIGMA, &this->sigma);
276 p_pStream->write_int(FIFF_BEM_SURF_ID, &this->id);
277 p_pStream->write_int(FIFF_MNE_COORD_FRAME, &this->coord_frame);
278 p_pStream->write_int(FIFF_BEM_SURF_NNODE, &this->np);
279 p_pStream->write_int(FIFF_BEM_SURF_NTRI, &this->ntri);
280 p_pStream->write_float_matrix(FIFF_BEM_SURF_NODES, Eigen::MatrixXf(this->rr));
281 if (this->ntri > 0)
282 p_pStream->write_int_matrix(FIFF_BEM_SURF_TRIANGLES, Eigen::MatrixXi(this->itris.array() + 1));
283 p_pStream->write_float_matrix(FIFF_BEM_SURF_NORMALS, Eigen::MatrixXf(this->nn));
284}
285
286//=============================================================================================================
287
289{
290 switch(id) {
291 case FIFFV_BEM_SURF_ID_BRAIN: return "Brain";
292 case FIFFV_BEM_SURF_ID_SKULL: return "Skull";
293 case FIFFV_BEM_SURF_ID_HEAD: return "Head";
294 case FIFFV_BEM_SURF_ID_UNKNOWN: return "Unknown";
295 default: return "Unknown";
296 }
297}
#define FIFF_MNE_COORD_FRAME
#define FIFFV_MNE_SURF_UNKNOWN
#define FIFFV_BEM_SURF_ID_UNKNOWN
Definition fiff_file.h:748
#define FIFF_BEM_SURF_NNODE
Definition fiff_file.h:733
#define FIFFV_BEM_SURF_ID_SKULL
Definition fiff_file.h:751
#define FIFF_BEM_SURF_NODES
Definition fiff_file.h:735
#define FIFF_BEM_SURF_TRIANGLES
Definition fiff_file.h:736
#define FIFF_BEM_SURF_ID
Definition fiff_file.h:731
#define FIFF_BEM_SURF_NTRI
Definition fiff_file.h:734
#define FIFF_BEM_SIGMA
Definition fiff_file.h:744
#define FIFFV_BEM_SURF_ID_HEAD
Definition fiff_file.h:752
#define FIFF_BEM_SURF_NORMALS
Definition fiff_file.h:737
#define FIFFV_BEM_SURF_ID_BRAIN
Definition fiff_file.h:749
MNEBemSurface class declaration.
Core MNE data structures (source spaces, source estimates, hemispheres).
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
FIFF File I/O routines.
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)
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)
Eigen::VectorXd tri_area
void writeToStream(FIFFLIB::FiffStream *p_pStream)
Eigen::MatrixX3d tri_nn
Eigen::MatrixX3d tri_cent
static QString id_name(int id)
std::vector< Eigen::VectorXi > neighbor_tri
std::vector< Eigen::VectorXi > neighbor_vert