Commit 4f63a044f4987b62d393c0826cb66189128bb153

Authored by David Mayerich
2 parents 83c3121c 6b317c71

Merge branch 'JACK' into 'master'

add function to render the cylinders perfectly

See merge request !22
stim/biomodels/network.h
@@ -46,7 +46,6 @@ __global__ void d_findedge(size_t* I, size_t n, unsigned* R, size_t* E, size_t n @@ -46,7 +46,6 @@ __global__ void d_findedge(size_t* I, size_t n, unsigned* R, size_t* E, size_t n
46 46
47 //hard-coded factor 47 //hard-coded factor
48 int threshold_fac = 10; 48 int threshold_fac = 10;
49 -float metric_fac = 0.6f; // might be related to the distance field  
50 49
51 namespace stim{ 50 namespace stim{
52 /** This is the a class that interfaces with gl_spider in order to store the currently 51 /** This is the a class that interfaces with gl_spider in order to store the currently
@@ -579,7 +578,7 @@ public: @@ -579,7 +578,7 @@ public:
579 /// @param B is the corresponding mapping network 578 /// @param B is the corresponding mapping network
580 /// @param sigma is the user-defined tolerance value - smaller values provide a stricter comparison 579 /// @param sigma is the user-defined tolerance value - smaller values provide a stricter comparison
581 /// @param device is the device that user want to use 580 /// @param device is the device that user want to use
582 - void split(stim::network<T> A, stim::network<T> B, float sigma, int device){ 581 + void split(stim::network<T> A, stim::network<T> B, float sigma, int device, float threshold){
583 582
584 T *c; 583 T *c;
585 size_t n_data = B.total_points(); 584 size_t n_data = B.total_points();
@@ -728,7 +727,7 @@ public: @@ -728,7 +727,7 @@ public:
728 T G = 0; // test to see whether it has its nearest neighbor 727 T G = 0; // test to see whether it has its nearest neighbor
729 for(unsigned i = 0; i < E[e].size(); i++) 728 for(unsigned i = 0; i < E[e].size(); i++)
730 G += E[e].r(i); // won't split special edges 729 G += E[e].r(i); // won't split special edges
731 - if(G / E[e].size() > metric_fac) // should based on the color map 730 + if(G / E[e].size() > threshold) // should based on the color map
732 id = E[e].size() - 1; // set split idx to outgoing direction vertex 731 id = E[e].size() - 1; // set split idx to outgoing direction vertex
733 732
734 std::vector<edge> tmpe; 733 std::vector<edge> tmpe;
@@ -761,7 +760,7 @@ public: @@ -761,7 +760,7 @@ public:
761 /// @param B is the network that the current network is going to map to 760 /// @param B is the network that the current network is going to map to
762 /// @param C is the mapping relationship: C[e1] = _e1 means e1 edge in current network is mapping the _e1 edge in B 761 /// @param C is the mapping relationship: C[e1] = _e1 means e1 edge in current network is mapping the _e1 edge in B
763 /// @param device is the device that user want to use 762 /// @param device is the device that user want to use
764 - void mapping(stim::network<T> B, std::vector<unsigned> &C, int device){ 763 + void mapping(stim::network<T> B, std::vector<unsigned> &C, int device, float threshold){
765 stim::network<T> A; //generate a network storing the result of the comparison 764 stim::network<T> A; //generate a network storing the result of the comparison
766 A = (*this); 765 A = (*this);
767 766
@@ -803,7 +802,7 @@ public: @@ -803,7 +802,7 @@ public:
803 for(unsigned p = 0; p < A.E[e].size(); p++) 802 for(unsigned p = 0; p < A.E[e].size(); p++)
804 M += A.E[e].r(p); 803 M += A.E[e].r(p);
805 M = M / A.E[e].size(); 804 M = M / A.E[e].size();
806 - if(M > metric_fac) 805 + if(M > threshold)
807 C[e] = (unsigned)-1; //set the nearest edge of impossibly mapping edges to maximum of unsigned 806 C[e] = (unsigned)-1; //set the nearest edge of impossibly mapping edges to maximum of unsigned
808 else{ 807 else{
809 T* queryPt = new T[3]; 808 T* queryPt = new T[3];
@@ -840,7 +839,7 @@ public: @@ -840,7 +839,7 @@ public:
840 for(unsigned p = 0; p < R.E[e].size(); p++) 839 for(unsigned p = 0; p < R.E[e].size(); p++)
841 M += A.E[e].m(p, errormag_id); 840 M += A.E[e].m(p, errormag_id);
842 M = M / A.E[e].size(); 841 M = M / A.E[e].size();
843 - if(M > metric_fac) // if the sum is larger than the metric_fac, we assume that it doesn't has corresponding edge in B 842 + if(M > threshold)
844 C[e] = (unsigned)-1; 843 C[e] = (unsigned)-1;
845 else{ // if it should have corresponding edge in B, then... 844 else{ // if it should have corresponding edge in B, then...
846 p1 = R.E[e][R.E[e].size()/2]; 845 p1 = R.E[e][R.E[e].size()/2];
stim/math/circle.h
@@ -111,6 +111,14 @@ public: @@ -111,6 +111,14 @@ public:
111 R *= factor; 111 R *= factor;
112 } 112 }
113 113
  114 + ///set the radius of circle to a certain value
  115 + ///@param value: the new radius of the circle
  116 + CUDA_CALLABLE
  117 + void set_R(T value)
  118 + {
  119 + R = value;
  120 + }
  121 +
114 ///sets the normal for the cirlce 122 ///sets the normal for the cirlce
115 ///@param n: x,y,z direction of the normal. 123 ///@param n: x,y,z direction of the normal.
116 CUDA_CALLABLE void 124 CUDA_CALLABLE void
stim/visualization/cylinder.h
@@ -179,12 +179,12 @@ public: @@ -179,12 +179,12 @@ public:
179 T sum = 0; //initialize the integral to zero 179 T sum = 0; //initialize the integral to zero
180 T m0, m1; //allocate space for both magnitudes in a single segment 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 181 m0 = R[0]; //initialize the first point and magnitude to the first point in the cylinder
182 - T len = L[0]; //allocate space for the segment length 182 + T len = L[1]; //allocate space for the segment length
183 183
184 184
185 for (unsigned p = 1; p < size(); p++) { //for every consecutive point in the cylinder 185 for (unsigned p = 1; p < size(); p++) { //for every consecutive point in the cylinder
186 m1 = R[p]; 186 m1 = R[p];
187 - if (p > 1) len = (L[p - 1] - L[p - 2]); //calculate the segment length using the L array 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 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 189 m0 = m1; //move to the next segment by shifting points
190 } 190 }
stim/visualization/gl_network.h
@@ -43,28 +43,44 @@ public: @@ -43,28 +43,44 @@ 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); // distance between two points = length/height  
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; 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 59
60 - glPushMatrix();  
61 - glTranslatef(x1, y1, z1);  
62 - glRotatef(ax, rx, ry, 0.0); 60 + // glPushMatrix();
  61 + // glTranslatef(x1, y1, z1);
  62 + // glRotatef(ax, rx, ry, 0.0);
63 63
64 - glutSolidCylinder(radius, d, subdivisions, 1);  
65 - glPopMatrix(); 64 + // glutSolidCylinder(radius, d, subdivisions, 1);
  65 + // glPopMatrix();
  66 + //}
  67 +
  68 + ///render cylinder based on points from the top/bottom hat
  69 + ///@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) {
  71 + glBegin(GL_QUAD_STRIP);
  72 + for (unsigned i = 0; i < C1.size(); i++) { // for every point on the circle
  73 + glVertex3f(C1[i][0], C1[i][1], C1[i][2]);
  74 + glVertex3f(C2[i][0], C2[i][1], C2[i][2]);
  75 + }
  76 + glEnd();
  77 + //glFlush();
66 } 78 }
67 79
  80 + ///render the vertex as sphere
  81 + ///@param x, y, z are the three coordinates of the center point
  82 + ///@param radius is the radius of the sphere
  83 + ///@param subdivisions is the slice/stride along/around z-axis
68 void renderBall(T x, T y, T z, T radius, int subdivisions) { 84 void renderBall(T x, T y, T z, T radius, int subdivisions) {
69 glPushMatrix(); 85 glPushMatrix();
70 glTranslatef(x, y, z); 86 glTranslatef(x, y, z);
@@ -72,7 +88,6 @@ public: @@ -72,7 +88,6 @@ public:
72 glPopMatrix(); 88 glPopMatrix();
73 } 89 }
74 90
75 -  
76 /// Render the network centerline as a series of line strips. 91 /// Render the network centerline as a series of line strips.
77 /// glCenterline0 is for only one input 92 /// glCenterline0 is for only one input
78 void glCenterline0(){ 93 void glCenterline0(){
@@ -92,7 +107,6 @@ public: @@ -92,7 +107,6 @@ public:
92 glCallList(dlist); // render the display list 107 glCallList(dlist); // render the display list
93 } 108 }
94 109
95 - /// @param m specifies the magnitude value used as the vertex weight (radius, error, etc.)  
96 void glCenterline(){ 110 void glCenterline(){
97 111
98 if(!glIsList(dlist)){ //if dlist isn't a display list, create it 112 if(!glIsList(dlist)){ //if dlist isn't a display list, create it
@@ -109,83 +123,245 @@ public: @@ -109,83 +123,245 @@ public:
109 } 123 }
110 glEndList(); //end the display list 124 glEndList(); //end the display list
111 } 125 }
112 - glCallList(dlist); // render the display list 126 + glCallList(dlist); //render the display list
113 } 127 }
114 128
115 - void glRandColorCenterlineGT(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap){  
116 - if(!glIsList(dlist1)){ 129 + ///render the GT network cylinder as series of tubes
  130 + ///@param dlist1 is the display list
  131 + ///@param map is the mapping relationship between two networks
  132 + ///@param colormap is the random generated color set for render
  133 + void glCylinderGT(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap) {
  134 + if (!glIsList(dlist1)) { // if dlist1 isn't a display list, create it
  135 + dlist1 = glGenLists(1); // generate a display list
  136 + glNewList(dlist1, GL_COMPILE); // start a new display list
  137 + for (unsigned e = 0; e < E.size(); e++) { // for each edge in the network
  138 + if (map[e] != unsigned(-1)) {
  139 + glColor3f(colormap[e * 3 + 0], colormap[e * 3 + 1], colormap[e * 3 + 2]);
  140 + for (unsigned p = 1; p < E[e].size(); p++) {// for each point on that edge
  141 + stim::circle<T> C1 = E[e].circ(p - 1);
  142 + stim::circle<T> C2 = E[e].circ(p);
  143 + C1.set_R(10); // scale the circle to the same
  144 + C2.set_R(10);
  145 + std::vector< stim::vec3<T> >Cp1 = C1.points(20);
  146 + std::vector< stim::vec3<T> >Cp2 = C2.points(20);
  147 + renderCylinder(Cp1, Cp2);
  148 + }
  149 + }
  150 + else {
  151 + glColor3f(1.0f, 1.0f, 1.0f); // white color for the un-mapping edges
  152 + for (unsigned p = 1; p < E[e].size(); p++) {// for each point on that edge
  153 + stim::circle<T> C1 = E[e].circ(p - 1);
  154 + stim::circle<T> C2 = E[e].circ(p);
  155 + C1.set_R(10); // scale the circle to the same
  156 + C2.set_R(10);
  157 + std::vector< stim::vec3<T> >Cp1 = C1.points(20);
  158 + std::vector< stim::vec3<T> >Cp2 = C2.points(20);
  159 + renderCylinder(Cp1, Cp2);
  160 + }
  161 + }
  162 + }
  163 + for (unsigned v = 0; v < V.size(); v++) {
  164 + size_t num_edge = V[v].e[0].size() + V[v].e[1].size();
  165 + if (num_edge > 1) { // if it is the joint vertex
  166 + glColor3f(0.3, 0.3, 0.3); // gray color
  167 + renderBall(V[v][0], V[v][1], V[v][2], 20, 20);
  168 + }
  169 + else { // if it is the terminal vertex
  170 + glColor3f(0.6, 0.6, 0.6); // more white gray
  171 + renderBall(V[v][0], V[v][1], V[v][2], 20, 20);
  172 + }
  173 + }
  174 + glEndList();
  175 + }
  176 + glCallList(dlist1);
  177 + }
  178 +
  179 + ///render the T network cylinder as series of tubes
  180 + ///@param dlist2 is the display list
  181 + ///@param map is the mapping relationship between two networks
  182 + ///@param colormap is the random generated color set for render
  183 + void glCylinderT(GLuint &dlist2, std::vector<unsigned> map, std::vector<T> colormap) {
  184 + if (!glIsList(dlist2)) {
  185 + dlist2 = glGenLists(1);
  186 + glNewList(dlist2, GL_COMPILE);
  187 + for (unsigned e = 0; e < E.size(); e++) { // for each edge in the network
  188 + if (map[e] != unsigned(-1)) {
  189 + glColor3f(colormap[map[e] * 3 + 0], colormap[map[e] * 3 + 1], colormap[map[e] * 3 + 2]);
  190 + for (unsigned p = 0; p < E[e].size() - 1; p++) {// for each point on that edge
  191 + stim::circle<T> C1 = E[e].circ(p);
  192 + stim::circle<T> C2 = E[e].circ(p + 1);
  193 + C1.set_R(10); // scale the circle to the same
  194 + C2.set_R(10);
  195 + std::vector< stim::vec3<T> >Cp1 = C1.points(20);
  196 + std::vector< stim::vec3<T> >Cp2 = C2.points(20);
  197 + renderCylinder(Cp1, Cp2);
  198 + }
  199 + }
  200 + else {
  201 + glColor3f(1.0f, 1.0f, 1.0f); // white color for the un-mapping edges
  202 + for (unsigned p = 0; p < E[e].size() - 1; p++) {// for each point on that edge
  203 + stim::circle<T> C1 = E[e].circ(p);
  204 + stim::circle<T> C2 = E[e].circ(p + 1);
  205 + C1.set_R(10); // scale the circle to the same
  206 + C2.set_R(10);
  207 + std::vector< stim::vec3<T> >Cp1 = C1.points(20);
  208 + std::vector< stim::vec3<T> >Cp2 = C2.points(20);
  209 + renderCylinder(Cp1, Cp2);
  210 + }
  211 + }
  212 + }
  213 + for (unsigned v = 0; v < V.size(); v++) {
  214 + size_t num_edge = V[v].e[0].size() + V[v].e[1].size();
  215 + if (num_edge > 1) { // if it is the joint vertex
  216 + glColor3f(0.3, 0.3, 0.3); // gray color
  217 + renderBall(V[v][0], V[v][1], V[v][2], 20, 20);
  218 + }
  219 + else { // if it is the terminal vertex
  220 + glColor3f(0.6, 0.6, 0.6); // more white gray
  221 + renderBall(V[v][0], V[v][1], V[v][2], 20, 20);
  222 + }
  223 + }
  224 + glEndList();
  225 + }
  226 + glCallList(dlist2);
  227 + }
  228 +
  229 + /// Render the GT network centerline as a series of line strips in random different color
  230 + ///@param dlist1 is the display list
  231 + ///@param map is the mapping relationship between two networks
  232 + ///@param colormap is the random generated color set for render
  233 + void glRandColorCenterlineGT(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap) {
  234 + if (!glIsList(dlist1)) {
117 dlist1 = glGenLists(1); 235 dlist1 = glGenLists(1);
118 glNewList(dlist1, GL_COMPILE); 236 glNewList(dlist1, GL_COMPILE);
119 - for(unsigned e = 0; e < E.size(); e++){  
120 - if(map[e] != unsigned(-1)){ 237 + for (unsigned e = 0; e < E.size(); e++) {
  238 + if (map[e] != unsigned(-1)) { // if it has corresponding edge in another network
121 glColor3f(colormap[e * 3 + 0], colormap[e * 3 + 1], colormap[e * 3 + 2]); 239 glColor3f(colormap[e * 3 + 0], colormap[e * 3 + 1], colormap[e * 3 + 2]);
122 glBegin(GL_LINE_STRIP); 240 glBegin(GL_LINE_STRIP);
123 - for(unsigned p = 0; p < E[e].size(); p++){ 241 + for (unsigned p = 0; p < E[e].size(); p++) {
124 glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); 242 glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]);
125 } 243 }
126 glEnd(); 244 glEnd();
127 - for (unsigned p = 0; p < E[e].size() - 1; p++) {  
128 - renderCylinder(E[e][p][0], E[e][p][1], E[e][p][2], E[e][p + 1][0], E[e][p + 1][1], E[e][p + 1][2], 10, 20);  
129 - }  
130 } 245 }
131 - else{  
132 - glColor3f(1.0, 1.0, 1.0); 246 + else {
  247 + glColor3f(1.0, 1.0, 1.0); // white color
133 glBegin(GL_LINE_STRIP); 248 glBegin(GL_LINE_STRIP);
134 - for(unsigned p = 0; p < E[e].size(); p++){ 249 + for (unsigned p = 0; p < E[e].size(); p++) {
135 glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); 250 glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]);
136 } 251 }
137 glEnd(); 252 glEnd();
138 } 253 }
139 } 254 }
140 - for (unsigned v = 0; v < V.size(); v++) {  
141 - size_t num_edge = V[v].e[0].size() + V[v].e[1].size();  
142 - if (num_edge > 1) {  
143 - glColor3f(0.3, 0.3, 0.3); // gray color for vertex  
144 - renderBall(V[v][0], V[v][1], V[v][2], 20, 20);  
145 - }  
146 - }  
147 glEndList(); 255 glEndList();
148 } 256 }
149 glCallList(dlist1); 257 glCallList(dlist1);
150 } 258 }
151 259
152 - void glRandColorCenterlineT(GLuint &dlist2, std::vector<unsigned> map, std::vector<T> colormap){  
153 - if(!glIsList(dlist2)){ 260 + /// Render the T network centerline as a series of line strips in random different color
  261 + ///@param dlist2 is the display list
  262 + ///@param map is the mapping relationship between two networks
  263 + ///@param colormap is the random generated color set for render
  264 + void glRandColorCenterlineT(GLuint &dlist2, std::vector<unsigned> map, std::vector<T> colormap) {
  265 + if (!glIsList(dlist2)) {
154 dlist2 = glGenLists(1); 266 dlist2 = glGenLists(1);
155 glNewList(dlist2, GL_COMPILE); 267 glNewList(dlist2, GL_COMPILE);
156 - for(unsigned e = 0; e < E.size(); e++){  
157 - if(map[e] != unsigned(-1)){ 268 + for (unsigned e = 0; e < E.size(); e++) {
  269 + if (map[e] != unsigned(-1)) { // if it has corresponding edge in another network
158 glColor3f(colormap[map[e] * 3 + 0], colormap[map[e] * 3 + 1], colormap[map[e] * 3 + 2]); 270 glColor3f(colormap[map[e] * 3 + 0], colormap[map[e] * 3 + 1], colormap[map[e] * 3 + 2]);
159 glBegin(GL_LINE_STRIP); 271 glBegin(GL_LINE_STRIP);
160 - for(unsigned p = 0; p < E[e].size(); p++){ 272 + for (unsigned p = 0; p < E[e].size(); p++) {
161 glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); 273 glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]);
162 } 274 }
163 glEnd(); 275 glEnd();
164 - for (unsigned p = 0; p < E[e].size() - 1; p++) {  
165 - renderCylinder(E[e][p][0], E[e][p][1], E[e][p][2], E[e][p + 1][0], E[e][p + 1][1], E[e][p + 1][2], 10, 20);  
166 - }  
167 } 276 }
168 - else{  
169 - glColor3f(1.0, 1.0, 1.0); 277 + else {
  278 + glColor3f(1.0, 1.0, 1.0); // white color
170 glBegin(GL_LINE_STRIP); 279 glBegin(GL_LINE_STRIP);
171 - for(unsigned p = 0; p < E[e].size(); p++){ 280 + for (unsigned p = 0; p < E[e].size(); p++) {
172 glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); 281 glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]);
173 } 282 }
174 glEnd(); 283 glEnd();
175 } 284 }
176 } 285 }
177 - for (unsigned v = 0; v < V.size(); v++) {  
178 - size_t num_edge = V[v].e[0].size() + V[v].e[1].size();  
179 - if (num_edge > 1) {  
180 - glColor3f(0.3, 0.3, 0.3); // gray color for vertex  
181 - renderBall(V[v][0], V[v][1], V[v][2], 20, 20);  
182 - }  
183 - }  
184 glEndList(); 286 glEndList();
185 } 287 }
186 glCallList(dlist2); 288 glCallList(dlist2);
187 } 289 }
188 290
  291 + //void glRandColorCenterlineGT(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap){
  292 + // if(!glIsList(dlist1)){
  293 + // dlist1 = glGenLists(1);
  294 + // glNewList(dlist1, GL_COMPILE);
  295 + // for(unsigned e = 0; e < E.size(); e++){
  296 + // if(map[e] != unsigned(-1)){
  297 + // glColor3f(colormap[e * 3 + 0], colormap[e * 3 + 1], colormap[e * 3 + 2]);
  298 + // glBegin(GL_LINE_STRIP);
  299 + // for(unsigned p = 0; p < E[e].size(); p++){
  300 + // glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]);
  301 + // }
  302 + // glEnd();
  303 + // for (unsigned p = 0; p < E[e].size() - 1; p++) {
  304 + // renderCylinder(E[e][p][0], E[e][p][1], E[e][p][2], E[e][p + 1][0], E[e][p + 1][1], E[e][p + 1][2], 10, 20);
  305 + // }
  306 + // }
  307 + // else{
  308 + // glColor3f(1.0, 1.0, 1.0);
  309 + // glBegin(GL_LINE_STRIP);
  310 + // for(unsigned p = 0; p < E[e].size(); p++){
  311 + // glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]);
  312 + // }
  313 + // glEnd();
  314 + // }
  315 + // }
  316 + // for (unsigned v = 0; v < V.size(); v++) {
  317 + // size_t num_edge = V[v].e[0].size() + V[v].e[1].size();
  318 + // if (num_edge > 1) {
  319 + // glColor3f(0.3, 0.3, 0.3); // gray color for vertex
  320 + // renderBall(V[v][0], V[v][1], V[v][2], 20, 20);
  321 + // }
  322 + // }
  323 + // glEndList();
  324 + // }
  325 + // glCallList(dlist1);
  326 + //}
  327 +
  328 + //void glRandColorCenterlineT(GLuint &dlist2, std::vector<unsigned> map, std::vector<T> colormap){
  329 + // if(!glIsList(dlist2)){
  330 + // dlist2 = glGenLists(1);
  331 + // glNewList(dlist2, GL_COMPILE);
  332 + // for(unsigned e = 0; e < E.size(); e++){
  333 + // if(map[e] != unsigned(-1)){
  334 + // glColor3f(colormap[map[e] * 3 + 0], colormap[map[e] * 3 + 1], colormap[map[e] * 3 + 2]);
  335 + // glBegin(GL_LINE_STRIP);
  336 + // for(unsigned p = 0; p < E[e].size(); p++){
  337 + // glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]);
  338 + // }
  339 + // glEnd();
  340 + // for (unsigned p = 0; p < E[e].size() - 1; p++) {
  341 + // renderCylinder(E[e][p][0], E[e][p][1], E[e][p][2], E[e][p + 1][0], E[e][p + 1][1], E[e][p + 1][2], 10, 20);
  342 + // }
  343 + // }
  344 + // else{
  345 + // glColor3f(1.0, 1.0, 1.0);
  346 + // glBegin(GL_LINE_STRIP);
  347 + // for(unsigned p = 0; p < E[e].size(); p++){
  348 + // glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]);
  349 + // }
  350 + // glEnd();
  351 + // }
  352 + // }
  353 + // for (unsigned v = 0; v < V.size(); v++) {
  354 + // size_t num_edge = V[v].e[0].size() + V[v].e[1].size();
  355 + // if (num_edge > 1) {
  356 + // glColor3f(0.3, 0.3, 0.3); // gray color for vertex
  357 + // renderBall(V[v][0], V[v][1], V[v][2], 20, 20);
  358 + // }
  359 + // }
  360 + // glEndList();
  361 + // }
  362 + // glCallList(dlist2);
  363 + //}
  364 +
189 }; //end stim::gl_network class 365 }; //end stim::gl_network class
190 }; //end stim namespace 366 }; //end stim namespace
191 367