gl_network.h
5.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#ifndef STIM_GL_NETWORK
#define STIM_GL_NETWORK
#include <stim/biomodels/network.h>
#include <stim/visualization/aaboundingbox.h>
namespace stim{
template <typename T>
class gl_network : public stim::network<T>{
protected:
using stim::network<T>::E;
using stim::network<T>::V;
GLuint dlist;
public:
/// Default constructor
gl_network() : stim::network<T>(){
dlist = 0;
}
/// Constructor creates a gl_network from a stim::network
gl_network(stim::network<T> N) : stim::network<T>(N){
dlist = 0;
}
/// Fills the parameters with the minimum and maximum spatial positions in the network,
/// specifying a bounding box for the network geometry
aaboundingbox<T> boundingbox(){
aaboundingbox<T> bb; //create a bounding box
//loop through every edge
for(unsigned e = 0; e < E.size(); e++){
//loop through every point
for(unsigned p = 0; p < E[e].size(); p++)
bb.expand(E[e][p]); //expand the bounding box to include the point
}
return bb; //return the bounding box
}
void renderCylinder(T x1, T y1, T z1, T x2, T y2, T z2, T radius, int subdivisions) {
T dx = x2 - x1;
T dy = y2 - y1;
T dz = z2 - z1;
/// handle the degenerate case with an approximation
if (dz == 0)
dz = .00000001;
T d = sqrt(dx*dx + dy*dy + dz*dz); // distance between two points = length/height
T ax = 57.2957795*acos(dz / d); // 180°/pi
if (dz < 0.0)
ax = -ax;
T rx = -dy*dz;
T ry = dx*dz;
glPushMatrix();
glTranslatef(x1, y1, z1);
glRotatef(ax, rx, ry, 0.0);
glutSolidCylinder(radius, d, subdivisions, 1);
glPopMatrix();
}
void renderBall(T x, T y, T z, T radius, int subdivisions) {
glPushMatrix();
glTranslatef(x, y, z);
glutSolidSphere(radius, subdivisions, subdivisions);
glPopMatrix();
}
/// Render the network centerline as a series of line strips.
/// glCenterline0 is for only one input
void glCenterline0(){
if (!glIsList(dlist)) { //if dlist isn't a display list, create it
dlist = glGenLists(1); //generate a display list
glNewList(dlist, GL_COMPILE); //start a new display list
for (unsigned e = 0; e < E.size(); e++) { //for each edge in the network
glBegin(GL_LINE_STRIP);
for (unsigned p = 0; p < E[e].size(); p++) { //for each point on that edge
glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); //set the vertex position based on the current point
glTexCoord1f(0); //set white color
}
glEnd();
}
glEndList(); //end the display list
}
glCallList(dlist); // render the display list
}
/// @param m specifies the magnitude value used as the vertex weight (radius, error, etc.)
void glCenterline(){
if(!glIsList(dlist)){ //if dlist isn't a display list, create it
dlist = glGenLists(1); //generate a display list
glNewList(dlist, GL_COMPILE); //start a new display list
for(unsigned e = 0; e < E.size(); e++){ //for each edge in the network
//unsigned errormag_id = E[e].nmags() - 1;
glBegin(GL_LINE_STRIP);
for(unsigned p = 0; p < E[e].size(); p++){ //for each point on that edge
glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]); //set the vertex position based on the current point
glTexCoord1f(E[e].r(p)); //set the texture coordinate based on the specified magnitude index
}
glEnd();
}
glEndList(); //end the display list
}
glCallList(dlist); // render the display list
}
void glRandColorCenterlineGT(GLuint &dlist1, std::vector<unsigned> map, std::vector<T> colormap){
if(!glIsList(dlist1)){
dlist1 = glGenLists(1);
glNewList(dlist1, GL_COMPILE);
for(unsigned e = 0; e < E.size(); e++){
if(map[e] != unsigned(-1)){
glColor3f(colormap[e * 3 + 0], colormap[e * 3 + 1], colormap[e * 3 + 2]);
glBegin(GL_LINE_STRIP);
for(unsigned p = 0; p < E[e].size(); p++){
glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]);
}
glEnd();
for (unsigned p = 0; p < E[e].size() - 1; p++) {
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);
}
}
else{
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
for(unsigned p = 0; p < E[e].size(); p++){
glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]);
}
glEnd();
}
}
for (unsigned v = 0; v < V.size(); v++) {
size_t num_edge = V[v].e[0].size() + V[v].e[1].size();
if (num_edge > 1) {
glColor3f(0.3, 0.3, 0.3); // gray color for vertex
renderBall(V[v][0], V[v][1], V[v][2], 20, 20);
}
}
glEndList();
}
glCallList(dlist1);
}
void glRandColorCenterlineT(GLuint &dlist2, std::vector<unsigned> map, std::vector<T> colormap){
if(!glIsList(dlist2)){
dlist2 = glGenLists(1);
glNewList(dlist2, GL_COMPILE);
for(unsigned e = 0; e < E.size(); e++){
if(map[e] != unsigned(-1)){
glColor3f(colormap[map[e] * 3 + 0], colormap[map[e] * 3 + 1], colormap[map[e] * 3 + 2]);
glBegin(GL_LINE_STRIP);
for(unsigned p = 0; p < E[e].size(); p++){
glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]);
}
glEnd();
for (unsigned p = 0; p < E[e].size() - 1; p++) {
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);
}
}
else{
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINE_STRIP);
for(unsigned p = 0; p < E[e].size(); p++){
glVertex3f(E[e][p][0], E[e][p][1], E[e][p][2]);
}
glEnd();
}
}
for (unsigned v = 0; v < V.size(); v++) {
size_t num_edge = V[v].e[0].size() + V[v].e[1].size();
if (num_edge > 1) {
glColor3f(0.3, 0.3, 0.3); // gray color for vertex
renderBall(V[v][0], V[v][1], V[v][2], 20, 20);
}
}
glEndList();
}
glCallList(dlist2);
}
}; //end stim::gl_network class
}; //end stim namespace
#endif