Commit 2b28db3e764ab147540b5bd987c965de4c3f049b
1 parent
5bd6c411
better render
Showing
3 changed files
with
182 additions
and
116 deletions
Show diff stats
stim/biomodels/network.h
... | ... | @@ -395,31 +395,40 @@ public: |
395 | 395 | stim::swc<T> S; // create swc variable |
396 | 396 | S.load(filename); // load the node information |
397 | 397 | S.create_tree(); // link those node according to their linking relationships as a tree |
398 | + S.resample(); | |
398 | 399 | |
399 | 400 | //NT.push_back(S.node[0].type); // set the neuronal_type value to the first vertex in the network |
400 | 401 | std::vector<unsigned> id2vert; // this list stores the SWC vertex ID associated with each network vertex |
401 | 402 | unsigned i[2]; // temporary, IDs associated with the first and last points |
402 | - for (unsigned int l = 1; l < S.numL(); l++) { // for every node starts from second one | |
403 | + | |
404 | + for (unsigned int l = 0; l < S.numE(); l++) { // for every edge | |
403 | 405 | //NT.push_back(S.node[l].type); |
404 | - stim::centerline<T> c3(2); // every fiber contains two vertices | |
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 | |
407 | - c3[1] = S.node[l].point; // store the end vertex | |
406 | + | |
407 | + std::vector< stim::vec3<T> > c; | |
408 | + S.get_points(l, c); | |
409 | + | |
410 | + stim::centerline<T> c3(c.size()); // new fiber | |
411 | + | |
412 | + for (unsigned j = 0; j < c.size(); j++) | |
413 | + c3[j] = c[j]; // copy the points | |
408 | 414 | |
409 | 415 | c3.update(); // update the L information |
410 | 416 | |
411 | 417 | stim::cylinder<T> C3(c3); // create a new cylinder in order to copy the origin radius information |
412 | 418 | // upadate the R information |
413 | 419 | std::vector<T> radius; |
414 | - radius.push_back(S.node[p_idx].radius); | |
415 | - radius.push_back(S.node[l].radius); | |
420 | + S.get_radius(l, radius); | |
421 | + | |
416 | 422 | C3.copy_r(radius); |
417 | 423 | |
418 | - edge new_edge(C3); // contains two points | |
424 | + edge new_edge(C3); // new edge | |
425 | + | |
426 | + //create an edge from the given centerline | |
427 | + unsigned int I = new_edge.size(); //calculate the number of points on the centerline | |
419 | 428 | |
420 | 429 | //get the first and last vertex IDs for the line |
421 | - i[0] = S.node[p_idx].idx; //get the SWC ID for the start point | |
422 | - i[1] = S.node[l].idx; //get the SWC ID for the end point | |
430 | + i[0] = S.E[l].front(); | |
431 | + i[1] = S.E[l].back(); | |
423 | 432 | |
424 | 433 | std::vector<unsigned>::iterator it; //create an iterator for searching the id2vert array |
425 | 434 | unsigned it_idx; //create an integer for the id2vert entry index |
... | ... | @@ -441,7 +450,7 @@ public: |
441 | 450 | |
442 | 451 | it = find(id2vert.begin(), id2vert.end(), i[1]); //look for the second ID |
443 | 452 | if (it == id2vert.end()) { //if i[1] hasn't already been used |
444 | - vertex new_vertex = new_edge[1]; //create a new vertex, assign it a position | |
453 | + vertex new_vertex = new_edge[I - 1]; //create a new vertex, assign it a position | |
445 | 454 | new_vertex.e[1].push_back(E.size()); //add the current edge as incoming |
446 | 455 | new_edge.v[1] = V.size(); //add the new vertex to the edge |
447 | 456 | V.push_back(new_vertex); //add the new vertex to the vertex list |
... | ... | @@ -620,8 +629,6 @@ public: |
620 | 629 | kdt.create(c, n_data, MaxTreeLevels); |
621 | 630 | |
622 | 631 | for(unsigned e = 0; e < R.E.size(); e++){ //for each edge in A |
623 | - R.E[e].add_mag(0); //add a new magnitude for the metric | |
624 | - size_t errormag_id = R.E[e].nmags() - 1; | |
625 | 632 | |
626 | 633 | size_t n = R.E[e].size(); // the number of points in current edge |
627 | 634 | T* query = new T[3 * n]; |
... | ... | @@ -634,8 +641,8 @@ public: |
634 | 641 | kdt.cpu_search(queryPt, n, nnIdx, dists); //find the distance between A and the current network |
635 | 642 | |
636 | 643 | for(unsigned p = 0; p < R.E[e].size(); p++){ |
637 | - m1[p] = 1.0f - gaussianFunction((T)dists[p], sigma); //calculate the metric value based on the distance | |
638 | - R.E[e].set_mag(errormag_id, p, m1[p]); //set the error for the second point in the segment | |
644 | + m1[p] = 1.0f - gaussianFunction((T)dists[p], sigma); //calculate the metric value based on the distance | |
645 | + R.E[e].set_r(p, m1[p]); //set the error for the second point in the segment | |
639 | 646 | } |
640 | 647 | } |
641 | 648 | #endif |
... | ... | @@ -746,10 +753,8 @@ public: |
746 | 753 | edge_point_num[ee] = B.E[ee].size(); |
747 | 754 | |
748 | 755 | for(unsigned e = 0; e < A.E.size(); e++){ //for each edge in A |
749 | - A.E[e].add_mag(0); //add a new magnitude for the metric | |
750 | - size_t errormag_id = A.E[e].nmags() - 1; | |
751 | - | |
752 | - size_t n = A.E[e].size(); // the number of edges in A | |
756 | + | |
757 | + size_t n = A.E[e].size(); //the number of edges in A | |
753 | 758 | |
754 | 759 | T* queryPt = new T[3 * n]; |
755 | 760 | T* m1 = new T[n]; |
... | ... | @@ -761,7 +766,7 @@ public: |
761 | 766 | |
762 | 767 | for(unsigned p = 0; p < A.E[e].size(); p++){ |
763 | 768 | m1[p] = 1.0f - gaussianFunction((T)dists[p], sigma); //calculate the metric value based on the distance |
764 | - A.E[e].set_mag(errormag_id, p, m1[p]); //set the error for the second point in the segment | |
769 | + A.E[e].set_r(p, m1[p]); //set the error for the second point in the segment | |
765 | 770 | |
766 | 771 | unsigned id = 0; //mapping edge's idx |
767 | 772 | size_t num = 0; //total number of points before #th edge |
... | ... | @@ -909,9 +914,8 @@ public: |
909 | 914 | |
910 | 915 | for(unsigned e = 0; e < R.E.size(); e++){ // for each edge in A |
911 | 916 | T M; // the sum of metrics of current edge |
912 | - unsigned errormag_id = R.E[e].nmags() - 1; | |
913 | 917 | for(unsigned p = 0; p < R.E[e].size(); p++) |
914 | - M += A.E[e].m(p, errormag_id); | |
918 | + M += A.E[e].r(p); | |
915 | 919 | M = M / A.E[e].size(); |
916 | 920 | if(M > threshold) |
917 | 921 | C[e] = (unsigned)-1; | ... | ... |
stim/visualization/gl_network.h
... | ... | @@ -115,6 +115,8 @@ public: |
115 | 115 | if (!glIsList(dlist)) { // if dlist isn't a display list, create it |
116 | 116 | dlist = glGenLists(1); // generate a display list |
117 | 117 | glNewList(dlist, GL_COMPILE); // start a new display list |
118 | + glEnable(GL_COLOR_MATERIAL); | |
119 | + glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); | |
118 | 120 | for (unsigned e = 0; e < E.size(); e++) { // for each edge in the network |
119 | 121 | for (unsigned p = 1; p < E[e].size(); p++) { // for each point on that edge |
120 | 122 | stim::circle<T> C1 = E[e].circ(p - 1); |
... | ... | @@ -125,7 +127,7 @@ public: |
125 | 127 | std::vector< stim::vec3<T> >Cp2 = C2.glpoints(20); |
126 | 128 | glBegin(GL_QUAD_STRIP); |
127 | 129 | for (unsigned i = 0; i < Cp1.size(); i++) { // for every point on the circle(+1 means closing the circle) |
128 | - glTexCoord1f(E[e].r(p-1)); | |
130 | + glTexCoord1f(E[e].r(p - 1)); | |
129 | 131 | glVertex3f(Cp1[i][0], Cp1[i][1], Cp1[i][2]); |
130 | 132 | glTexCoord1f(E[e].r(p)); |
131 | 133 | glVertex3f(Cp2[i][0], Cp2[i][1], Cp2[i][2]); |
... | ... | @@ -150,77 +152,67 @@ public: |
150 | 152 | glCallList(dlist); // render the display list |
151 | 153 | } |
152 | 154 | |
153 | - ///render the GT network cylinder as series of tubes | |
154 | - ///@param dlist1 is the display list | |
155 | - ///@param map is the mapping relationship between two networks | |
156 | - ///@param colormap is the random generated color set for render | |
157 | - void glRandColorCylinder1(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap, float sigma, float radius) { | |
155 | + ///render a T as a adjoint network of GT in transparancy(darkgreen, overlaid) | |
156 | + void glAdjointCylinder(float sigma, float radius) { | |
158 | 157 | |
159 | - if (radius != sigma) // if render radius was changed by user, create a new display list | |
160 | - glDeleteLists(dlist1, 1); | |
161 | - if (!glIsList(dlist1)) { // if dlist1 isn't a display list, create it | |
162 | - dlist1 = glGenLists(1); // generate a display list | |
163 | - glNewList(dlist1, GL_COMPILE); // start a new display list | |
164 | - for (unsigned e = 0; e < E.size(); e++) { // for each edge in the network | |
165 | - if (map[e] != unsigned(-1)) { | |
166 | - glColor3f(colormap[e * 3 + 0], colormap[e * 3 + 1], colormap[e * 3 + 2]); | |
167 | - for (unsigned p = 1; p < E[e].size(); p++) {// for each point on that edge | |
168 | - stim::circle<T> C1 = E[e].circ(p - 1); | |
169 | - stim::circle<T> C2 = E[e].circ(p); | |
170 | - C1.set_R(2*radius); // scale the circle to the same | |
171 | - C2.set_R(2*radius); | |
172 | - std::vector< stim::vec3<T> >Cp1 = C1.glpoints(20); | |
173 | - std::vector< stim::vec3<T> >Cp2 = C2.glpoints(20); | |
174 | - renderCylinder(Cp1, Cp2); | |
175 | - } | |
176 | - } | |
177 | - else { | |
178 | - glColor3f(1.0f, 1.0f, 1.0f); // white color for the un-mapping edges | |
179 | - for (unsigned p = 1; p < E[e].size(); p++) { // for each point on that edge | |
180 | - stim::circle<T> C1 = E[e].circ(p - 1); | |
181 | - stim::circle<T> C2 = E[e].circ(p); | |
182 | - C1.set_R(2*radius); // scale the circle to the same | |
183 | - C2.set_R(2*radius); | |
184 | - std::vector< stim::vec3<T> >Cp1 = C1.glpoints(20); | |
185 | - std::vector< stim::vec3<T> >Cp2 = C2.glpoints(20); | |
186 | - renderCylinder(Cp1, Cp2); | |
158 | + if (radius != sigma) // if render radius was changed by user, create a new display list | |
159 | + glDeleteLists(dlist+4, 1); | |
160 | + if (!glIsList(dlist+4)) { | |
161 | + glNewList(dlist+4, GL_COMPILE); | |
162 | + for (unsigned e = 0; e < E.size(); e++) { // for each edge in the network | |
163 | + for (unsigned p = 1; p < E[e].size(); p++) { // for each point on that edge | |
164 | + stim::circle<T> C1 = E[e].circ(p - 1); | |
165 | + stim::circle<T> C2 = E[e].circ(p); | |
166 | + C1.set_R(2 * radius); // scale the circle to the same | |
167 | + C2.set_R(2 * radius); | |
168 | + std::vector< stim::vec3<T> >Cp1 = C1.glpoints(20); | |
169 | + std::vector< stim::vec3<T> >Cp2 = C2.glpoints(20); | |
170 | + glBegin(GL_QUAD_STRIP); | |
171 | + for (unsigned i = 0; i < Cp1.size(); i++) { // for every point on the circle(+1 means closing the circle) | |
172 | + glVertex3f(Cp1[i][0], Cp1[i][1], Cp1[i][2]); | |
173 | + glVertex3f(Cp2[i][0], Cp2[i][1], Cp2[i][2]); | |
187 | 174 | } |
188 | - } | |
175 | + glEnd(); | |
176 | + } // set the texture coordinate based on the specified magnitude index | |
189 | 177 | } |
190 | - for (unsigned v = 0; v < V.size(); v++) { | |
191 | - size_t num_edge = V[v].e[0].size() + V[v].e[1].size(); | |
192 | - if (num_edge > 1) { // if it is the joint vertex | |
193 | - glColor3f(0.3, 0.3, 0.3); // gray color | |
194 | - renderBall(V[v][0], V[v][1], V[v][2], 3*radius, 20); | |
178 | + for (unsigned n = 0; n < V.size(); n++) { | |
179 | + size_t num = V[n].e[0].size(); // store the number of outgoing edge of that vertex | |
180 | + if (num != 0) { // if it has outgoing edge | |
181 | + unsigned idx = V[n].e[0][0]; // find the index of first outgoing edge of that vertex | |
195 | 182 | } |
196 | - else { // if it is the terminal vertex | |
197 | - glColor3f(0.6, 0.6, 0.6); // more white gray | |
198 | - renderBall(V[v][0], V[v][1], V[v][2], 3*radius, 20); | |
183 | + else { | |
184 | + unsigned idx = V[n].e[1][0]; // find the index of first incoming edge of that vertex | |
199 | 185 | } |
186 | + renderBall(V[n][0], V[n][1], V[n][2], 2 * radius, 20); | |
200 | 187 | } |
201 | 188 | glEndList(); |
202 | 189 | } |
203 | - glCallList(dlist1); | |
190 | + glCallList(dlist+4); | |
204 | 191 | } |
205 | 192 | |
206 | - ///render the T network cylinder as series of tubes | |
207 | - ///@param dlist2 is the display list | |
193 | + ///render the network cylinder as series of tubes | |
194 | + ///@param I is a indicator: 0 -> GT, 1 -> T | |
208 | 195 | ///@param map is the mapping relationship between two networks |
209 | 196 | ///@param colormap is the random generated color set for render |
210 | - void glRandColorCylinder2(GLuint &dlist2, std::vector<unsigned> map, std::vector<T> colormap, float sigma, float radius) { | |
197 | + void glRandColorCylinder(int I, std::vector<unsigned> map, std::vector<T> colormap, float sigma, float radius) { | |
211 | 198 | |
212 | - if (radius != sigma) // if render radius was changed by user, create a new display list | |
213 | - glDeleteLists(dlist2, 1); | |
214 | - if (!glIsList(dlist2)) { | |
215 | - dlist2 = glGenLists(1); | |
216 | - glNewList(dlist2, GL_COMPILE); | |
217 | - for (unsigned e = 0; e < E.size(); e++) { // for each edge in the network | |
199 | + if (radius != sigma) // if render radius was changed by user, create a new display list | |
200 | + glDeleteLists(dlist+2, 1); | |
201 | + if (!glIsList(dlist+2)) { // if dlist isn't a display list, create it | |
202 | + glNewList(dlist+2, GL_COMPILE); // start a new display list | |
203 | + glEnable(GL_COLOR_MATERIAL); | |
204 | + glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); | |
205 | + for (unsigned e = 0; e < E.size(); e++) { // for each edge in the network | |
218 | 206 | if (map[e] != unsigned(-1)) { |
219 | - glColor3f(colormap[map[e] * 3 + 0], colormap[map[e] * 3 + 1], colormap[map[e] * 3 + 2]); | |
220 | - for (unsigned p = 1; p < E[e].size(); p++) { // for each point on that edge(except last one) | |
207 | + if(I == 0) // if it is to render GT | |
208 | + glColor3f(colormap[e * 3 + 0], colormap[e * 3 + 1], colormap[e * 3 + 2]); | |
209 | + else // if it is to render T | |
210 | + glColor3f(colormap[map[e] * 3 + 0], colormap[map[e] * 3 + 1], colormap[map[e] * 3 + 2]); | |
211 | + | |
212 | + for (unsigned p = 1; p < E[e].size(); p++) {// for each point on that edge | |
221 | 213 | stim::circle<T> C1 = E[e].circ(p - 1); |
222 | 214 | stim::circle<T> C2 = E[e].circ(p); |
223 | - C1.set_R(2*radius); // scale the circle to the same | |
215 | + C1.set_R(2*radius); // scale the circle to the same | |
224 | 216 | C2.set_R(2*radius); |
225 | 217 | std::vector< stim::vec3<T> >Cp1 = C1.glpoints(20); |
226 | 218 | std::vector< stim::vec3<T> >Cp2 = C2.glpoints(20); |
... | ... | @@ -252,52 +244,27 @@ public: |
252 | 244 | } |
253 | 245 | } |
254 | 246 | glEndList(); |
247 | + glDisable(GL_COLOR_MATERIAL); | |
255 | 248 | } |
256 | - glCallList(dlist2); | |
249 | + glCallList(dlist+2); | |
257 | 250 | } |
258 | 251 | |
259 | - /// Render the GT network centerline as a series of line strips in random different color | |
252 | + ///render the network centerline as a series of line strips in random different color | |
253 | + ///@param I is a indicator: 0 -> GT, 1 -> T | |
260 | 254 | ///@param dlist1 is the display list |
261 | 255 | ///@param map is the mapping relationship between two networks |
262 | 256 | ///@param colormap is the random generated color set for render |
263 | - void glRandColorCenterline1(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap) { | |
257 | + void glRandColorCenterline(int I, GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap) { | |
264 | 258 | if (!glIsList(dlist1)) { |
265 | 259 | dlist1 = glGenLists(1); |
266 | 260 | glNewList(dlist1, GL_COMPILE); |
267 | 261 | for (unsigned e = 0; e < E.size(); e++) { |
268 | - if (map[e] != unsigned(-1)) { // if it has corresponding edge in another network | |
269 | - glColor3f(colormap[e * 3 + 0], colormap[e * 3 + 1], colormap[e * 3 + 2]); | |
270 | - glBegin(GL_LINE_STRIP); | |
271 | - for (unsigned p = 0; p < E[e].size(); p++) { | |
272 | - glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); | |
273 | - } | |
274 | - glEnd(); | |
275 | - } | |
276 | - else { | |
277 | - glColor3f(1.0, 1.0, 1.0); // white color | |
278 | - glBegin(GL_LINE_STRIP); | |
279 | - for (unsigned p = 0; p < E[e].size(); p++) { | |
280 | - glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); | |
281 | - } | |
282 | - glEnd(); | |
283 | - } | |
284 | - } | |
285 | - glEndList(); | |
286 | - } | |
287 | - glCallList(dlist1); | |
288 | - } | |
262 | + if (map[e] != unsigned(-1)) { // if it has corresponding edge in another network | |
263 | + if (I == 0) // if it is to render GT | |
264 | + glColor3f(colormap[e * 3 + 0], colormap[e * 3 + 1], colormap[e * 3 + 2]); | |
265 | + else // if it is to render T | |
266 | + glColor3f(colormap[map[e] * 3 + 0], colormap[map[e] * 3 + 1], colormap[map[e] * 3 + 2]); | |
289 | 267 | |
290 | - /// Render the T network centerline as a series of line strips in random different color | |
291 | - ///@param dlist2 is the display list | |
292 | - ///@param map is the mapping relationship between two networks | |
293 | - ///@param colormap is the random generated color set for render | |
294 | - void glRandColorCenterline2(GLuint &dlist2, std::vector<unsigned> map, std::vector<T> colormap) { | |
295 | - if (!glIsList(dlist2)) { | |
296 | - dlist2 = glGenLists(1); | |
297 | - glNewList(dlist2, GL_COMPILE); | |
298 | - for (unsigned e = 0; e < E.size(); e++) { | |
299 | - if (map[e] != unsigned(-1)) { // if it has corresponding edge in another network | |
300 | - glColor3f(colormap[map[e] * 3 + 0], colormap[map[e] * 3 + 1], colormap[map[e] * 3 + 2]); | |
301 | 268 | glBegin(GL_LINE_STRIP); |
302 | 269 | for (unsigned p = 0; p < E[e].size(); p++) { |
303 | 270 | glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); |
... | ... | @@ -305,7 +272,7 @@ public: |
305 | 272 | glEnd(); |
306 | 273 | } |
307 | 274 | else { |
308 | - glColor3f(1.0, 1.0, 1.0); // white color | |
275 | + glColor3f(1.0, 1.0, 1.0); // white color | |
309 | 276 | glBegin(GL_LINE_STRIP); |
310 | 277 | for (unsigned p = 0; p < E[e].size(); p++) { |
311 | 278 | glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); |
... | ... | @@ -315,7 +282,7 @@ public: |
315 | 282 | } |
316 | 283 | glEndList(); |
317 | 284 | } |
318 | - glCallList(dlist2); | |
285 | + glCallList(dlist1); | |
319 | 286 | } |
320 | 287 | |
321 | 288 | //void glRandColorCenterlineGT(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap){ | ... | ... |
stim/visualization/swc.h
... | ... | @@ -86,6 +86,8 @@ namespace stim { |
86 | 86 | class swc { |
87 | 87 | public: |
88 | 88 | std::vector< typename swc_tree::swc_node<T> > node; |
89 | + std::vector< std::vector<int> > E; // list of nodes | |
90 | + | |
89 | 91 | swc() {}; // default constructor |
90 | 92 | |
91 | 93 | // load the swc as tree nodes |
... | ... | @@ -170,11 +172,104 @@ namespace stim { |
170 | 172 | } |
171 | 173 | } |
172 | 174 | |
175 | + // create a new edge | |
176 | + void create_up(std::vector<int>& edge,swc_tree::swc_node<T> cur_node, int target) { | |
177 | + while (cur_node.parent_idx != target) { | |
178 | + edge.push_back(cur_node.idx); | |
179 | + cur_node = node[cur_node.parent_idx - 1]; // move to next node | |
180 | + } | |
181 | + edge.push_back(cur_node.idx); // push back the start/end vertex of current edge | |
182 | + | |
183 | + std::reverse(edge.begin(), edge.end()); // follow the original flow direction | |
184 | + } | |
185 | + void create_down(std::vector<int>& edge, swc_tree::swc_node<T> cur_node, int j) { | |
186 | + while (cur_node.son_idx.size() != 0) { | |
187 | + edge.push_back(cur_node.idx); | |
188 | + if (cur_node.son_idx.size() > 1) | |
189 | + cur_node = node[cur_node.son_idx[j] - 1]; // move to next node | |
190 | + else | |
191 | + cur_node = node[cur_node.son_idx[0] - 1]; | |
192 | + } | |
193 | + edge.push_back(cur_node.idx); // push back the start/end vertex of current edge | |
194 | + } | |
195 | + | |
196 | + // resample the tree-like SWC | |
197 | + void resample() { | |
198 | + unsigned n = node.size(); | |
199 | + | |
200 | + std::vector<int> joint_node; | |
201 | + for (unsigned i = 1; i < n; i++) { // search all nodes(except the first one) to find joint nodes | |
202 | + if (node[i].son_idx.size() > 1) { | |
203 | + joint_node.push_back(node[i].idx); // store the original index | |
204 | + } | |
205 | + } | |
206 | + | |
207 | + std::vector<int> new_edge; // new edge in the network | |
208 | + | |
209 | + n = joint_node.size(); | |
210 | + | |
211 | + for (unsigned i = 0; i < n; i++) { // for every joint nodes | |
212 | + std::vector<int> new_edge; // new edge in the network | |
213 | + swc_tree::swc_node<T> cur_node = node[joint_node[i] - 1]; // store current node | |
214 | + | |
215 | + // go up | |
216 | + swc_tree::swc_node<T> tmp_node = node[cur_node.parent_idx - 1]; | |
217 | + while (tmp_node.parent_idx != -1 && tmp_node.son_idx.size() == 1) { | |
218 | + tmp_node = node[tmp_node.parent_idx - 1]; | |
219 | + } | |
220 | + int target = tmp_node.parent_idx; // store the go-up target | |
221 | + create_up(new_edge, cur_node, target); | |
222 | + E.push_back(new_edge); | |
223 | + new_edge.clear(); | |
224 | + | |
225 | + // go down | |
226 | + unsigned t = cur_node.son_idx.size(); | |
227 | + for (unsigned j = 0; j < t; j++) { // for every son node | |
228 | + tmp_node = node[cur_node.son_idx[j] - 1]; // move down | |
229 | + while (tmp_node.son_idx.size() == 1) { | |
230 | + tmp_node = node[tmp_node.son_idx[0] - 1]; | |
231 | + } | |
232 | + if (tmp_node.son_idx.size() == 0) { | |
233 | + create_down(new_edge, cur_node, j); | |
234 | + E.push_back(new_edge); | |
235 | + new_edge.clear(); | |
236 | + } | |
237 | + } | |
238 | + } | |
239 | + } | |
240 | + | |
241 | + // get points in one edge | |
242 | + void get_points(int e, std::vector< stim::vec3<T> >& V) { | |
243 | + V.resize(E[e].size()); | |
244 | + for (unsigned i = 0; i < E[e].size(); i++) { | |
245 | + unsigned id = E[e][i] - 1; | |
246 | + | |
247 | + V[i][0] = node[id].point[0]; | |
248 | + V[i][1] = node[id].point[1]; | |
249 | + V[i][2] = node[id].point[2]; | |
250 | + } | |
251 | + } | |
252 | + | |
253 | + // get radius information in one edge | |
254 | + void get_radius(int e, std::vector<T>& radius) { | |
255 | + radius.resize(E[e].size()); | |
256 | + for (unsigned i = 0; i < E[e].size(); i++) { | |
257 | + unsigned id = E[e][i] - 1; | |
258 | + | |
259 | + radius[i] = node[id].radius; | |
260 | + } | |
261 | + } | |
262 | + | |
173 | 263 | // return the number of point in swc |
174 | - unsigned int numL() { | |
264 | + unsigned int numP() { | |
175 | 265 | return node.size(); |
176 | 266 | } |
177 | 267 | |
268 | + // return the number of edges in swc after resample | |
269 | + unsigned int numE() { | |
270 | + return E.size(); | |
271 | + } | |
272 | + | |
178 | 273 | |
179 | 274 | }; |
180 | 275 | } // end of namespace stim | ... | ... |