Commit 518edf128cc8c582389c1db882ceada9f40f5155
Merge branch 'JACK' into 'master'
fix minor error for loading and rendering networks from swc files See merge request !24
Showing
4 changed files
with
192 additions
and
54 deletions
Show diff stats
stim/biomodels/network.h
@@ -390,6 +390,7 @@ public: | @@ -390,6 +390,7 @@ public: | ||
390 | } | 390 | } |
391 | } | 391 | } |
392 | 392 | ||
393 | + //load a network from an SWC file | ||
393 | void load_swc(std::string filename) { | 394 | void load_swc(std::string filename) { |
394 | stim::swc<T> S; // create swc variable | 395 | stim::swc<T> S; // create swc variable |
395 | S.load(filename); // load the node information | 396 | S.load(filename); // load the node information |
@@ -401,16 +402,23 @@ public: | @@ -401,16 +402,23 @@ public: | ||
401 | for (unsigned int l = 1; l < S.numL(); l++) { // for every node starts from second one | 402 | for (unsigned int l = 1; l < S.numL(); l++) { // for every node starts from second one |
402 | NT.push_back(S.node[l].type); | 403 | NT.push_back(S.node[l].type); |
403 | stim::centerline<T> c3(2); // every fiber contains two vertices | 404 | stim::centerline<T> c3(2); // every fiber contains two vertices |
404 | - int id = S.node[l].parent_idx - 1; | ||
405 | - c3[0] = S.node[id].point; // store the begin vertex | 405 | + int p_idx = S.node[l].parent_idx - 1; // get the parent node loop idx of current node |
406 | + c3[0] = S.node[p_idx].point; // store the begin vertex | ||
406 | c3[1] = S.node[l].point; // store the end vertex | 407 | c3[1] = S.node[l].point; // store the end vertex |
407 | 408 | ||
408 | c3.update(); // update the L information | 409 | c3.update(); // update the L information |
409 | - | ||
410 | - edge new_edge(c3); // contains two points | ||
411 | - | 410 | + |
411 | + stim::cylinder<T> C3(c3); // create a new cylinder in order to copy the origin radius information | ||
412 | + // upadate the R information | ||
413 | + std::vector<T> radius; | ||
414 | + radius.push_back(S.node[p_idx].radius); | ||
415 | + radius.push_back(S.node[l].radius); | ||
416 | + C3.copy_r(radius); | ||
417 | + | ||
418 | + edge new_edge(C3); // contains two points | ||
419 | + | ||
412 | //get the first and last vertex IDs for the line | 420 | //get the first and last vertex IDs for the line |
413 | - i[0] = S.node[id].idx; //get the SWC ID for the start point | 421 | + i[0] = S.node[p_idx].idx; //get the SWC ID for the start point |
414 | i[1] = S.node[l].idx; //get the SWC ID for the end point | 422 | i[1] = S.node[l].idx; //get the SWC ID for the end point |
415 | 423 | ||
416 | std::vector<unsigned>::iterator it; //create an iterator for searching the id2vert array | 424 | std::vector<unsigned>::iterator it; //create an iterator for searching the id2vert array |
@@ -471,7 +479,7 @@ public: | @@ -471,7 +479,7 @@ public: | ||
471 | stim::network<T> resample(T spacing){ | 479 | stim::network<T> resample(T spacing){ |
472 | stim::network<T> n; //create a new network that will be an exact copy, with resampled fibers | 480 | stim::network<T> n; //create a new network that will be an exact copy, with resampled fibers |
473 | n.V = V; //copy all vertices | 481 | n.V = V; //copy all vertices |
474 | - | 482 | + n.NT = NT; //copy all the neuronal type information |
475 | n.E.resize(edges()); //allocate space for the edge list | 483 | n.E.resize(edges()); //allocate space for the edge list |
476 | 484 | ||
477 | //copy all fibers, resampling them in the process | 485 | //copy all fibers, resampling them in the process |
stim/visualization/cylinder.h
@@ -54,6 +54,12 @@ public: | @@ -54,6 +54,12 @@ public: | ||
54 | //add_mag(r); | 54 | //add_mag(r); |
55 | } | 55 | } |
56 | 56 | ||
57 | + //copy the original radius | ||
58 | + void copy_r(std::vector<T> radius) { | ||
59 | + for (unsigned i = 0; i < radius.size(); i++) | ||
60 | + R[i] = radius[i]; | ||
61 | + } | ||
62 | + | ||
57 | ///Returns magnitude i at the given length into the fiber (based on the pvalue). | 63 | ///Returns magnitude i at the given length into the fiber (based on the pvalue). |
58 | ///Interpolates the position along the line. | 64 | ///Interpolates the position along the line. |
59 | ///@param l: the location of the in the cylinder. | 65 | ///@param l: the location of the in the cylinder. |
@@ -175,20 +181,23 @@ public: | @@ -175,20 +181,23 @@ public: | ||
175 | /// Integrates a magnitude value along the cylinder. | 181 | /// Integrates a magnitude value along the cylinder. |
176 | /// @param m is the magnitude value to be integrated (this is usually the radius) | 182 | /// @param m is the magnitude value to be integrated (this is usually the radius) |
177 | T integrate() { | 183 | T integrate() { |
184 | + T sum = 0; //initialize the integral to zero | ||
185 | + if (L.size() == 1) | ||
186 | + return sum; | ||
187 | + else { | ||
188 | + T m0, m1; //allocate space for both magnitudes in a single segment | ||
189 | + m0 = R[0]; //initialize the first point and magnitude to the first point in the cylinder | ||
190 | + T len = L[1]; //allocate space for the segment length | ||
178 | 191 | ||
179 | - T sum = 0; //initialize the integral to zero | ||
180 | - T m0, m1; //allocate space for both magnitudes in a single segment | ||
181 | - m0 = R[0]; //initialize the first point and magnitude to the first point in the cylinder | ||
182 | - T len = L[1]; //allocate space for the segment length | ||
183 | - | ||
184 | - | ||
185 | - for (unsigned p = 1; p < size(); p++) { //for every consecutive point in the cylinder | ||
186 | - m1 = R[p]; | ||
187 | - if (p > 1) len = (L[p] - L[p - 1]); //calculate the segment length using the L array | ||
188 | - sum += (m0 + m1) / (T)2.0 * len; //add the average magnitude, weighted by the segment length | ||
189 | - m0 = m1; //move to the next segment by shifting points | 192 | + |
193 | + for (unsigned p = 1; p < size(); p++) { //for every consecutive point in the cylinder | ||
194 | + m1 = R[p]; | ||
195 | + if (p > 1) len = (L[p] - L[p - 1]); //calculate the segment length using the L array | ||
196 | + sum += (m0 + m1) / (T)2.0 * len; //add the average magnitude, weighted by the segment length | ||
197 | + m0 = m1; //move to the next segment by shifting points | ||
198 | + } | ||
199 | + return sum; //return the integral | ||
190 | } | 200 | } |
191 | - return sum; //return the integral | ||
192 | } | 201 | } |
193 | 202 | ||
194 | /// Resamples the cylinder to provide a maximum distance of "spacing" between centerline points. All current | 203 | /// Resamples the cylinder to provide a maximum distance of "spacing" between centerline points. All current |
stim/visualization/gl_network.h
@@ -43,28 +43,6 @@ public: | @@ -43,28 +43,6 @@ public: | ||
43 | return bb; //return the bounding box | 43 | return bb; //return the bounding box |
44 | } | 44 | } |
45 | 45 | ||
46 | - //void renderCylinder(T x1, T y1, T z1, T x2, T y2, T z2, T radius, int subdivisions) { | ||
47 | - // T dx = x2 - x1; | ||
48 | - // T dy = y2 - y1; | ||
49 | - // T dz = z2 - z1; | ||
50 | - // /// handle the degenerate case with an approximation | ||
51 | - // if (dz == 0) | ||
52 | - // dz = .00000001; | ||
53 | - // T d = sqrt(dx*dx + dy*dy + dz*dz); | ||
54 | - // T ax = 57.2957795*acos(dz / d); // 180°/pi | ||
55 | - // if (dz < 0.0) | ||
56 | - // ax = -ax; | ||
57 | - // T rx = -dy*dz; | ||
58 | - // T ry = dx*dz; | ||
59 | - | ||
60 | - // glPushMatrix(); | ||
61 | - // glTranslatef(x1, y1, z1); | ||
62 | - // glRotatef(ax, rx, ry, 0.0); | ||
63 | - | ||
64 | - // glutSolidCylinder(radius, d, subdivisions, 1); | ||
65 | - // glPopMatrix(); | ||
66 | - //} | ||
67 | - | ||
68 | ///render cylinder based on points from the top/bottom hat | 46 | ///render cylinder based on points from the top/bottom hat |
69 | ///@param C1 set of points from one of the hat | 47 | ///@param C1 set of points from one of the hat |
70 | void renderCylinder(std::vector< stim::vec3<T> > C1, std::vector< stim::vec3<T> > C2) { | 48 | void renderCylinder(std::vector< stim::vec3<T> > C1, std::vector< stim::vec3<T> > C2) { |
@@ -114,7 +92,7 @@ public: | @@ -114,7 +92,7 @@ public: | ||
114 | dlist = glGenLists(1); // generate a display list | 92 | dlist = glGenLists(1); // generate a display list |
115 | glNewList(dlist, GL_COMPILE); // start a new display list | 93 | glNewList(dlist, GL_COMPILE); // start a new display list |
116 | for (unsigned e = 0; e < E.size(); e++) { | 94 | for (unsigned e = 0; e < E.size(); e++) { |
117 | - int type = NT[e]; | 95 | + int type = NT[e]; // get the neuronal type |
118 | switch (type) { | 96 | switch (type) { |
119 | case 0: | 97 | case 0: |
120 | glColor3f(1.0f, 1.0f, 1.0f); // white for undefined | 98 | glColor3f(1.0f, 1.0f, 1.0f); // white for undefined |
@@ -187,8 +165,8 @@ public: | @@ -187,8 +165,8 @@ public: | ||
187 | glCallList(dlist); // render the display list | 165 | glCallList(dlist); // render the display list |
188 | } | 166 | } |
189 | 167 | ||
190 | - ///render the network centerline as a series of line strips | ||
191 | - ///colors is based on metric values | 168 | + ///render the network centerline as a series of line strips(when loading at least two networks, otherwise using glCenterline0()) |
169 | + ///colors are based on metric values | ||
192 | void glCenterline(){ | 170 | void glCenterline(){ |
193 | 171 | ||
194 | if(!glIsList(dlist)){ //if dlist isn't a display list, create it | 172 | if(!glIsList(dlist)){ //if dlist isn't a display list, create it |
@@ -208,11 +186,39 @@ public: | @@ -208,11 +186,39 @@ public: | ||
208 | glCallList(dlist); //render the display list | 186 | glCallList(dlist); //render the display list |
209 | } | 187 | } |
210 | 188 | ||
189 | + ///render the network cylinder as a series of tubes | ||
190 | + ///colors are based on metric values | ||
191 | + void glCylinder() { | ||
192 | + if (!glIsList(dlist)) { //if dlist isn't a display list, create it | ||
193 | + dlist = glGenLists(1); //generate a display list | ||
194 | + glNewList(dlist, GL_COMPILE); //start a new display list | ||
195 | + for (unsigned e = 0; e < E.size(); e++) { //for each edge in the network | ||
196 | + for (unsigned p = 1; p < E[e].size(); p++) { // for each point on that edge | ||
197 | + stim::circle<T> C1 = E[e].circ(p - 1); | ||
198 | + stim::circle<T> C2 = E[e].circ(p); | ||
199 | + C1.set_R(10); // scale the circle to the same | ||
200 | + C2.set_R(10); | ||
201 | + std::vector< stim::vec3<T> >Cp1 = C1.points(20); | ||
202 | + std::vector< stim::vec3<T> >Cp2 = C2.points(20); | ||
203 | + glBegin(GL_QUAD_STRIP); | ||
204 | + for (unsigned i = 0; i < Cp1.size(); i++) { // for every point on the circle | ||
205 | + glVertex3f(Cp1[i][0], Cp1[i][1], Cp1[i][2]); | ||
206 | + glVertex3f(Cp2[i][0], Cp2[i][1], Cp2[i][2]); | ||
207 | + glTexCoord1f(E[e].r(p)); | ||
208 | + } | ||
209 | + glEnd(); | ||
210 | + } //set the texture coordinate based on the specified magnitude index | ||
211 | + } | ||
212 | + glEndList(); //end the display list | ||
213 | + } | ||
214 | + glCallList(dlist); //render the display list | ||
215 | + } | ||
216 | + | ||
211 | ///render the GT network cylinder as series of tubes | 217 | ///render the GT network cylinder as series of tubes |
212 | ///@param dlist1 is the display list | 218 | ///@param dlist1 is the display list |
213 | ///@param map is the mapping relationship between two networks | 219 | ///@param map is the mapping relationship between two networks |
214 | ///@param colormap is the random generated color set for render | 220 | ///@param colormap is the random generated color set for render |
215 | - void glCylinderGT(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap) { | 221 | + void glRandColorCylinder1(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap) { |
216 | if (!glIsList(dlist1)) { // if dlist1 isn't a display list, create it | 222 | if (!glIsList(dlist1)) { // if dlist1 isn't a display list, create it |
217 | dlist1 = glGenLists(1); // generate a display list | 223 | dlist1 = glGenLists(1); // generate a display list |
218 | glNewList(dlist1, GL_COMPILE); // start a new display list | 224 | glNewList(dlist1, GL_COMPILE); // start a new display list |
@@ -258,11 +264,57 @@ public: | @@ -258,11 +264,57 @@ public: | ||
258 | glCallList(dlist1); | 264 | glCallList(dlist1); |
259 | } | 265 | } |
260 | 266 | ||
267 | + void glRandColorCylinder1_swc(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap) { | ||
268 | + if (!glIsList(dlist1)) { // if dlist1 isn't a display list, create it | ||
269 | + dlist1 = glGenLists(1); // generate a display list | ||
270 | + glNewList(dlist1, GL_COMPILE); // start a new display list | ||
271 | + for (unsigned e = 0; e < E.size(); e++) { // for each edge in the network | ||
272 | + if (map[e] != unsigned(-1)) { | ||
273 | + glColor3f(colormap[e * 3 + 0], colormap[e * 3 + 1], colormap[e * 3 + 2]); | ||
274 | + for (unsigned p = 1; p < E[e].size(); p++) {// for each point on that edge | ||
275 | + stim::circle<T> C1 = E[e].circ(p - 1); | ||
276 | + stim::circle<T> C2 = E[e].circ(p); | ||
277 | + C1.set_R(0.5); // scale the circle to the same | ||
278 | + C2.set_R(0.5); | ||
279 | + std::vector< stim::vec3<T> >Cp1 = C1.points(20); | ||
280 | + std::vector< stim::vec3<T> >Cp2 = C2.points(20); | ||
281 | + renderCylinder(Cp1, Cp2); | ||
282 | + } | ||
283 | + } | ||
284 | + else { | ||
285 | + glColor3f(1.0f, 1.0f, 1.0f); // white color for the un-mapping edges | ||
286 | + for (unsigned p = 1; p < E[e].size(); p++) { // for each point on that edge | ||
287 | + stim::circle<T> C1 = E[e].circ(p - 1); | ||
288 | + stim::circle<T> C2 = E[e].circ(p); | ||
289 | + C1.set_R(0.5); // scale the circle to the same | ||
290 | + C2.set_R(0.5); | ||
291 | + std::vector< stim::vec3<T> >Cp1 = C1.points(20); | ||
292 | + std::vector< stim::vec3<T> >Cp2 = C2.points(20); | ||
293 | + renderCylinder(Cp1, Cp2); | ||
294 | + } | ||
295 | + } | ||
296 | + } | ||
297 | + for (unsigned v = 0; v < V.size(); v++) { | ||
298 | + size_t num_edge = V[v].e[0].size() + V[v].e[1].size(); | ||
299 | + if (num_edge > 1) { // if it is the joint vertex | ||
300 | + glColor3f(0.3, 0.3, 0.3); // gray color | ||
301 | + renderBall(V[v][0], V[v][1], V[v][2], 1, 20); | ||
302 | + } | ||
303 | + else { // if it is the terminal vertex | ||
304 | + glColor3f(0.6, 0.6, 0.6); // more white gray | ||
305 | + renderBall(V[v][0], V[v][1], V[v][2], 1, 20); | ||
306 | + } | ||
307 | + } | ||
308 | + glEndList(); | ||
309 | + } | ||
310 | + glCallList(dlist1); | ||
311 | + } | ||
312 | + | ||
261 | ///render the T network cylinder as series of tubes | 313 | ///render the T network cylinder as series of tubes |
262 | ///@param dlist2 is the display list | 314 | ///@param dlist2 is the display list |
263 | ///@param map is the mapping relationship between two networks | 315 | ///@param map is the mapping relationship between two networks |
264 | ///@param colormap is the random generated color set for render | 316 | ///@param colormap is the random generated color set for render |
265 | - void glCylinderT(GLuint &dlist2, std::vector<unsigned> map, std::vector<T> colormap) { | 317 | + void glRandColorCylinder2(GLuint &dlist2, std::vector<unsigned> map, std::vector<T> colormap) { |
266 | if (!glIsList(dlist2)) { | 318 | if (!glIsList(dlist2)) { |
267 | dlist2 = glGenLists(1); | 319 | dlist2 = glGenLists(1); |
268 | glNewList(dlist2, GL_COMPILE); | 320 | glNewList(dlist2, GL_COMPILE); |
@@ -308,11 +360,57 @@ public: | @@ -308,11 +360,57 @@ public: | ||
308 | glCallList(dlist2); | 360 | glCallList(dlist2); |
309 | } | 361 | } |
310 | 362 | ||
363 | + void glRandColorCylinder2_swc(GLuint &dlist2, std::vector<unsigned> map, std::vector<T> colormap) { | ||
364 | + if (!glIsList(dlist2)) { | ||
365 | + dlist2 = glGenLists(1); | ||
366 | + glNewList(dlist2, GL_COMPILE); | ||
367 | + for (unsigned e = 0; e < E.size(); e++) { // for each edge in the network | ||
368 | + if (map[e] != unsigned(-1)) { | ||
369 | + glColor3f(colormap[map[e] * 3 + 0], colormap[map[e] * 3 + 1], colormap[map[e] * 3 + 2]); | ||
370 | + for (unsigned p = 0; p < E[e].size() - 1; p++) {// for each point on that edge | ||
371 | + stim::circle<T> C1 = E[e].circ(p); | ||
372 | + stim::circle<T> C2 = E[e].circ(p + 1); | ||
373 | + C1.set_R(0.5); // scale the circle to the same | ||
374 | + C2.set_R(0.5); | ||
375 | + std::vector< stim::vec3<T> >Cp1 = C1.points(20); | ||
376 | + std::vector< stim::vec3<T> >Cp2 = C2.points(20); | ||
377 | + renderCylinder(Cp1, Cp2); | ||
378 | + } | ||
379 | + } | ||
380 | + else { | ||
381 | + glColor3f(1.0f, 1.0f, 1.0f); // white color for the un-mapping edges | ||
382 | + for (unsigned p = 0; p < E[e].size() - 1; p++) {// for each point on that edge | ||
383 | + stim::circle<T> C1 = E[e].circ(p); | ||
384 | + stim::circle<T> C2 = E[e].circ(p + 1); | ||
385 | + C1.set_R(0.5); // scale the circle to the same | ||
386 | + C2.set_R(0.5); | ||
387 | + std::vector< stim::vec3<T> >Cp1 = C1.points(20); | ||
388 | + std::vector< stim::vec3<T> >Cp2 = C2.points(20); | ||
389 | + renderCylinder(Cp1, Cp2); | ||
390 | + } | ||
391 | + } | ||
392 | + } | ||
393 | + for (unsigned v = 0; v < V.size(); v++) { | ||
394 | + size_t num_edge = V[v].e[0].size() + V[v].e[1].size(); | ||
395 | + if (num_edge > 1) { // if it is the joint vertex | ||
396 | + glColor3f(0.3, 0.3, 0.3); // gray color | ||
397 | + renderBall(V[v][0], V[v][1], V[v][2], 1, 20); | ||
398 | + } | ||
399 | + else { // if it is the terminal vertex | ||
400 | + glColor3f(0.6, 0.6, 0.6); // more white gray | ||
401 | + renderBall(V[v][0], V[v][1], V[v][2], 1, 20); | ||
402 | + } | ||
403 | + } | ||
404 | + glEndList(); | ||
405 | + } | ||
406 | + glCallList(dlist2); | ||
407 | + } | ||
408 | + | ||
311 | /// Render the GT network centerline as a series of line strips in random different color | 409 | /// Render the GT network centerline as a series of line strips in random different color |
312 | ///@param dlist1 is the display list | 410 | ///@param dlist1 is the display list |
313 | ///@param map is the mapping relationship between two networks | 411 | ///@param map is the mapping relationship between two networks |
314 | ///@param colormap is the random generated color set for render | 412 | ///@param colormap is the random generated color set for render |
315 | - void glRandColorCenterlineGT(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap) { | 413 | + void glRandColorCenterline1(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap) { |
316 | if (!glIsList(dlist1)) { | 414 | if (!glIsList(dlist1)) { |
317 | dlist1 = glGenLists(1); | 415 | dlist1 = glGenLists(1); |
318 | glNewList(dlist1, GL_COMPILE); | 416 | glNewList(dlist1, GL_COMPILE); |
@@ -343,7 +441,7 @@ public: | @@ -343,7 +441,7 @@ public: | ||
343 | ///@param dlist2 is the display list | 441 | ///@param dlist2 is the display list |
344 | ///@param map is the mapping relationship between two networks | 442 | ///@param map is the mapping relationship between two networks |
345 | ///@param colormap is the random generated color set for render | 443 | ///@param colormap is the random generated color set for render |
346 | - void glRandColorCenterlineT(GLuint &dlist2, std::vector<unsigned> map, std::vector<T> colormap) { | 444 | + void glRandColorCenterline2(GLuint &dlist2, std::vector<unsigned> map, std::vector<T> colormap) { |
347 | if (!glIsList(dlist2)) { | 445 | if (!glIsList(dlist2)) { |
348 | dlist2 = glGenLists(1); | 446 | dlist2 = glGenLists(1); |
349 | glNewList(dlist2, GL_COMPILE); | 447 | glNewList(dlist2, GL_COMPILE); |
@@ -444,6 +542,29 @@ public: | @@ -444,6 +542,29 @@ public: | ||
444 | // glCallList(dlist2); | 542 | // glCallList(dlist2); |
445 | //} | 543 | //} |
446 | 544 | ||
545 | + | ||
546 | + //void renderCylinder(T x1, T y1, T z1, T x2, T y2, T z2, T radius, int subdivisions) { | ||
547 | + // T dx = x2 - x1; | ||
548 | + // T dy = y2 - y1; | ||
549 | + // T dz = z2 - z1; | ||
550 | + // /// handle the degenerate case with an approximation | ||
551 | + // if (dz == 0) | ||
552 | + // dz = .00000001; | ||
553 | + // T d = sqrt(dx*dx + dy*dy + dz*dz); | ||
554 | + // T ax = 57.2957795*acos(dz / d); // 180°/pi | ||
555 | + // if (dz < 0.0) | ||
556 | + // ax = -ax; | ||
557 | + // T rx = -dy*dz; | ||
558 | + // T ry = dx*dz; | ||
559 | + | ||
560 | + // glPushMatrix(); | ||
561 | + // glTranslatef(x1, y1, z1); | ||
562 | + // glRotatef(ax, rx, ry, 0.0); | ||
563 | + | ||
564 | + // glutSolidCylinder(radius, d, subdivisions, 1); | ||
565 | + // glPopMatrix(); | ||
566 | + //} | ||
567 | + | ||
447 | }; //end stim::gl_network class | 568 | }; //end stim::gl_network class |
448 | }; //end stim namespace | 569 | }; //end stim namespace |
449 | 570 |
stim/visualization/swc.h
@@ -20,7 +20,7 @@ namespace stim { | @@ -20,7 +20,7 @@ namespace stim { | ||
20 | enum node_information { INTEGER_LABEL, NEURONAL_TYPE, X_COORDINATE, Y_COORDINATE, Z_COORDINATE, RADIUS, PARENT_LABEL }; | 20 | enum node_information { INTEGER_LABEL, NEURONAL_TYPE, X_COORDINATE, Y_COORDINATE, Z_COORDINATE, RADIUS, PARENT_LABEL }; |
21 | 21 | ||
22 | public: | 22 | public: |
23 | - int idx; // the index of current node start from 1(ambiguity) | 23 | + int idx; // the index of current node start from 1(original index from the file) |
24 | neuronal_type type; // the type of neuronal segmemt | 24 | neuronal_type type; // the type of neuronal segmemt |
25 | stim::vec3<T> point; // the point coordinates | 25 | stim::vec3<T> point; // the point coordinates |
26 | T radius; // the radius at current node | 26 | T radius; // the radius at current node |
@@ -44,7 +44,7 @@ namespace stim { | @@ -44,7 +44,7 @@ namespace stim { | ||
44 | // for each information contained in the node point we got | 44 | // for each information contained in the node point we got |
45 | for (unsigned int i = 0; i < p.size(); i++) { | 45 | for (unsigned int i = 0; i < p.size(); i++) { |
46 | std::stringstream ss(p[i]); // create a stringstream object for casting | 46 | std::stringstream ss(p[i]); // create a stringstream object for casting |
47 | - | 47 | + |
48 | // store different information | 48 | // store different information |
49 | switch (i) { | 49 | switch (i) { |
50 | case INTEGER_LABEL: | 50 | case INTEGER_LABEL: |
@@ -103,8 +103,8 @@ namespace stim { | @@ -103,8 +103,8 @@ namespace stim { | ||
103 | std::string line; | 103 | std::string line; |
104 | // skip comment | 104 | // skip comment |
105 | while (getline(infile, line)) { | 105 | while (getline(infile, line)) { |
106 | - if ('#' == line[0]) // if it is comment line | ||
107 | - continue; | 106 | + if ('#' == line[0] || line.empty()) // if it is comment line or empty line |
107 | + continue; // keep read | ||
108 | else | 108 | else |
109 | break; | 109 | break; |
110 | } | 110 | } |
@@ -144,7 +144,7 @@ namespace stim { | @@ -144,7 +144,7 @@ namespace stim { | ||
144 | 144 | ||
145 | std::string line; | 145 | std::string line; |
146 | while (getline(infile, line)) { | 146 | while (getline(infile, line)) { |
147 | - if ('#' == line[0]) { | 147 | + if ('#' == line[0] || line.empty()) { |
148 | std::cout << line << std::endl; // print the comment line by line | 148 | std::cout << line << std::endl; // print the comment line by line |
149 | } | 149 | } |
150 | else | 150 | else |
@@ -165,7 +165,7 @@ namespace stim { | @@ -165,7 +165,7 @@ namespace stim { | ||
165 | if (node[i].parent_idx != node[i - 1].parent_idx) | 165 | if (node[i].parent_idx != node[i - 1].parent_idx) |
166 | cur_level = node[node[i].parent_idx - 1].level + 1; | 166 | cur_level = node[node[i].parent_idx - 1].level + 1; |
167 | node[i].level = cur_level; | 167 | node[i].level = cur_level; |
168 | - int tmp_parent_idx = node[i].parent_idx - 1; // get the parent node loop idx of current node | 168 | + int tmp_parent_idx = node[i].parent_idx - 1; // get the parent node loop idx of current node |
169 | node[tmp_parent_idx].son_idx.push_back(i + 1); // son_idx stores the real idx = loop idx + 1 | 169 | node[tmp_parent_idx].son_idx.push_back(i + 1); // son_idx stores the real idx = loop idx + 1 |
170 | } | 170 | } |
171 | } | 171 | } |