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,31 +395,40 @@ public: | ||
395 | stim::swc<T> S; // create swc variable | 395 | stim::swc<T> S; // create swc variable |
396 | S.load(filename); // load the node information | 396 | S.load(filename); // load the node information |
397 | S.create_tree(); // link those node according to their linking relationships as a tree | 397 | S.create_tree(); // link those node according to their linking relationships as a tree |
398 | + S.resample(); | ||
398 | 399 | ||
399 | //NT.push_back(S.node[0].type); // set the neuronal_type value to the first vertex in the network | 400 | //NT.push_back(S.node[0].type); // set the neuronal_type value to the first vertex in the network |
400 | std::vector<unsigned> id2vert; // this list stores the SWC vertex ID associated with each network vertex | 401 | std::vector<unsigned> id2vert; // this list stores the SWC vertex ID associated with each network vertex |
401 | unsigned i[2]; // temporary, IDs associated with the first and last points | 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 | //NT.push_back(S.node[l].type); | 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 | c3.update(); // update the L information | 415 | c3.update(); // update the L information |
410 | 416 | ||
411 | stim::cylinder<T> C3(c3); // create a new cylinder in order to copy the origin radius information | 417 | stim::cylinder<T> C3(c3); // create a new cylinder in order to copy the origin radius information |
412 | // upadate the R information | 418 | // upadate the R information |
413 | std::vector<T> radius; | 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 | C3.copy_r(radius); | 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 | //get the first and last vertex IDs for the line | 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 | std::vector<unsigned>::iterator it; //create an iterator for searching the id2vert array | 433 | std::vector<unsigned>::iterator it; //create an iterator for searching the id2vert array |
425 | unsigned it_idx; //create an integer for the id2vert entry index | 434 | unsigned it_idx; //create an integer for the id2vert entry index |
@@ -441,7 +450,7 @@ public: | @@ -441,7 +450,7 @@ public: | ||
441 | 450 | ||
442 | it = find(id2vert.begin(), id2vert.end(), i[1]); //look for the second ID | 451 | it = find(id2vert.begin(), id2vert.end(), i[1]); //look for the second ID |
443 | if (it == id2vert.end()) { //if i[1] hasn't already been used | 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 | new_vertex.e[1].push_back(E.size()); //add the current edge as incoming | 454 | new_vertex.e[1].push_back(E.size()); //add the current edge as incoming |
446 | new_edge.v[1] = V.size(); //add the new vertex to the edge | 455 | new_edge.v[1] = V.size(); //add the new vertex to the edge |
447 | V.push_back(new_vertex); //add the new vertex to the vertex list | 456 | V.push_back(new_vertex); //add the new vertex to the vertex list |
@@ -620,8 +629,6 @@ public: | @@ -620,8 +629,6 @@ public: | ||
620 | kdt.create(c, n_data, MaxTreeLevels); | 629 | kdt.create(c, n_data, MaxTreeLevels); |
621 | 630 | ||
622 | for(unsigned e = 0; e < R.E.size(); e++){ //for each edge in A | 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 | size_t n = R.E[e].size(); // the number of points in current edge | 633 | size_t n = R.E[e].size(); // the number of points in current edge |
627 | T* query = new T[3 * n]; | 634 | T* query = new T[3 * n]; |
@@ -634,8 +641,8 @@ public: | @@ -634,8 +641,8 @@ public: | ||
634 | kdt.cpu_search(queryPt, n, nnIdx, dists); //find the distance between A and the current network | 641 | kdt.cpu_search(queryPt, n, nnIdx, dists); //find the distance between A and the current network |
635 | 642 | ||
636 | for(unsigned p = 0; p < R.E[e].size(); p++){ | 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 | #endif | 648 | #endif |
@@ -746,10 +753,8 @@ public: | @@ -746,10 +753,8 @@ public: | ||
746 | edge_point_num[ee] = B.E[ee].size(); | 753 | edge_point_num[ee] = B.E[ee].size(); |
747 | 754 | ||
748 | for(unsigned e = 0; e < A.E.size(); e++){ //for each edge in A | 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 | T* queryPt = new T[3 * n]; | 759 | T* queryPt = new T[3 * n]; |
755 | T* m1 = new T[n]; | 760 | T* m1 = new T[n]; |
@@ -761,7 +766,7 @@ public: | @@ -761,7 +766,7 @@ public: | ||
761 | 766 | ||
762 | for(unsigned p = 0; p < A.E[e].size(); p++){ | 767 | for(unsigned p = 0; p < A.E[e].size(); p++){ |
763 | m1[p] = 1.0f - gaussianFunction((T)dists[p], sigma); //calculate the metric value based on the distance | 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 | unsigned id = 0; //mapping edge's idx | 771 | unsigned id = 0; //mapping edge's idx |
767 | size_t num = 0; //total number of points before #th edge | 772 | size_t num = 0; //total number of points before #th edge |
@@ -909,9 +914,8 @@ public: | @@ -909,9 +914,8 @@ public: | ||
909 | 914 | ||
910 | for(unsigned e = 0; e < R.E.size(); e++){ // for each edge in A | 915 | for(unsigned e = 0; e < R.E.size(); e++){ // for each edge in A |
911 | T M; // the sum of metrics of current edge | 916 | T M; // the sum of metrics of current edge |
912 | - unsigned errormag_id = R.E[e].nmags() - 1; | ||
913 | for(unsigned p = 0; p < R.E[e].size(); p++) | 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 | M = M / A.E[e].size(); | 919 | M = M / A.E[e].size(); |
916 | if(M > threshold) | 920 | if(M > threshold) |
917 | C[e] = (unsigned)-1; | 921 | C[e] = (unsigned)-1; |
stim/visualization/gl_network.h
@@ -115,6 +115,8 @@ public: | @@ -115,6 +115,8 @@ public: | ||
115 | if (!glIsList(dlist)) { // if dlist isn't a display list, create it | 115 | if (!glIsList(dlist)) { // if dlist isn't a display list, create it |
116 | dlist = glGenLists(1); // generate a display list | 116 | dlist = glGenLists(1); // generate a display list |
117 | glNewList(dlist, GL_COMPILE); // start a new display list | 117 | glNewList(dlist, GL_COMPILE); // start a new display list |
118 | + glEnable(GL_COLOR_MATERIAL); | ||
119 | + glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); | ||
118 | for (unsigned e = 0; e < E.size(); e++) { // for each edge in the network | 120 | for (unsigned e = 0; e < E.size(); e++) { // for each edge in the network |
119 | for (unsigned p = 1; p < E[e].size(); p++) { // for each point on that edge | 121 | for (unsigned p = 1; p < E[e].size(); p++) { // for each point on that edge |
120 | stim::circle<T> C1 = E[e].circ(p - 1); | 122 | stim::circle<T> C1 = E[e].circ(p - 1); |
@@ -125,7 +127,7 @@ public: | @@ -125,7 +127,7 @@ public: | ||
125 | std::vector< stim::vec3<T> >Cp2 = C2.glpoints(20); | 127 | std::vector< stim::vec3<T> >Cp2 = C2.glpoints(20); |
126 | glBegin(GL_QUAD_STRIP); | 128 | glBegin(GL_QUAD_STRIP); |
127 | for (unsigned i = 0; i < Cp1.size(); i++) { // for every point on the circle(+1 means closing the circle) | 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 | glVertex3f(Cp1[i][0], Cp1[i][1], Cp1[i][2]); | 131 | glVertex3f(Cp1[i][0], Cp1[i][1], Cp1[i][2]); |
130 | glTexCoord1f(E[e].r(p)); | 132 | glTexCoord1f(E[e].r(p)); |
131 | glVertex3f(Cp2[i][0], Cp2[i][1], Cp2[i][2]); | 133 | glVertex3f(Cp2[i][0], Cp2[i][1], Cp2[i][2]); |
@@ -150,77 +152,67 @@ public: | @@ -150,77 +152,67 @@ public: | ||
150 | glCallList(dlist); // render the display list | 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 | glEndList(); | 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 | ///@param map is the mapping relationship between two networks | 195 | ///@param map is the mapping relationship between two networks |
209 | ///@param colormap is the random generated color set for render | 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 | if (map[e] != unsigned(-1)) { | 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 | stim::circle<T> C1 = E[e].circ(p - 1); | 213 | stim::circle<T> C1 = E[e].circ(p - 1); |
222 | stim::circle<T> C2 = E[e].circ(p); | 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 | C2.set_R(2*radius); | 216 | C2.set_R(2*radius); |
225 | std::vector< stim::vec3<T> >Cp1 = C1.glpoints(20); | 217 | std::vector< stim::vec3<T> >Cp1 = C1.glpoints(20); |
226 | std::vector< stim::vec3<T> >Cp2 = C2.glpoints(20); | 218 | std::vector< stim::vec3<T> >Cp2 = C2.glpoints(20); |
@@ -252,52 +244,27 @@ public: | @@ -252,52 +244,27 @@ public: | ||
252 | } | 244 | } |
253 | } | 245 | } |
254 | glEndList(); | 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 | ///@param dlist1 is the display list | 254 | ///@param dlist1 is the display list |
261 | ///@param map is the mapping relationship between two networks | 255 | ///@param map is the mapping relationship between two networks |
262 | ///@param colormap is the random generated color set for render | 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 | if (!glIsList(dlist1)) { | 258 | if (!glIsList(dlist1)) { |
265 | dlist1 = glGenLists(1); | 259 | dlist1 = glGenLists(1); |
266 | glNewList(dlist1, GL_COMPILE); | 260 | glNewList(dlist1, GL_COMPILE); |
267 | for (unsigned e = 0; e < E.size(); e++) { | 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 | glBegin(GL_LINE_STRIP); | 268 | glBegin(GL_LINE_STRIP); |
302 | for (unsigned p = 0; p < E[e].size(); p++) { | 269 | for (unsigned p = 0; p < E[e].size(); p++) { |
303 | glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); | 270 | glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); |
@@ -305,7 +272,7 @@ public: | @@ -305,7 +272,7 @@ public: | ||
305 | glEnd(); | 272 | glEnd(); |
306 | } | 273 | } |
307 | else { | 274 | else { |
308 | - glColor3f(1.0, 1.0, 1.0); // white color | 275 | + glColor3f(1.0, 1.0, 1.0); // white color |
309 | glBegin(GL_LINE_STRIP); | 276 | glBegin(GL_LINE_STRIP); |
310 | for (unsigned p = 0; p < E[e].size(); p++) { | 277 | for (unsigned p = 0; p < E[e].size(); p++) { |
311 | glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); | 278 | glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); |
@@ -315,7 +282,7 @@ public: | @@ -315,7 +282,7 @@ public: | ||
315 | } | 282 | } |
316 | glEndList(); | 283 | glEndList(); |
317 | } | 284 | } |
318 | - glCallList(dlist2); | 285 | + glCallList(dlist1); |
319 | } | 286 | } |
320 | 287 | ||
321 | //void glRandColorCenterlineGT(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap){ | 288 | //void glRandColorCenterlineGT(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap){ |
stim/visualization/swc.h
@@ -86,6 +86,8 @@ namespace stim { | @@ -86,6 +86,8 @@ namespace stim { | ||
86 | class swc { | 86 | class swc { |
87 | public: | 87 | public: |
88 | std::vector< typename swc_tree::swc_node<T> > node; | 88 | std::vector< typename swc_tree::swc_node<T> > node; |
89 | + std::vector< std::vector<int> > E; // list of nodes | ||
90 | + | ||
89 | swc() {}; // default constructor | 91 | swc() {}; // default constructor |
90 | 92 | ||
91 | // load the swc as tree nodes | 93 | // load the swc as tree nodes |
@@ -170,11 +172,104 @@ namespace stim { | @@ -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 | // return the number of point in swc | 263 | // return the number of point in swc |
174 | - unsigned int numL() { | 264 | + unsigned int numP() { |
175 | return node.size(); | 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 | } // end of namespace stim | 275 | } // end of namespace stim |