Commit 2e0f052a4108ad47246a9b2be824b8f87fc7e1c5
1 parent
6ada8448
minor changes to network
Showing
3 changed files
with
82 additions
and
60 deletions
Show diff stats
stim/biomodels/network.h
@@ -33,7 +33,10 @@ class network{ | @@ -33,7 +33,10 @@ class network{ | ||
33 | public: | 33 | public: |
34 | unsigned v[2]; //unique id's designating the starting and ending | 34 | unsigned v[2]; //unique id's designating the starting and ending |
35 | // default constructor | 35 | // default constructor |
36 | - edge() : cylinder<T>(){v[1] = -1; v[0] = -1;} | 36 | + edge() : cylinder<T>() |
37 | + { | ||
38 | + v[1] = -1; v[0] = -1; | ||
39 | + } | ||
37 | /// Constructor - creates an edge from a list of points by calling the stim::fiber constructor | 40 | /// Constructor - creates an edge from a list of points by calling the stim::fiber constructor |
38 | 41 | ||
39 | ///@param p is an array of positions in space | 42 | ///@param p is an array of positions in space |
@@ -54,7 +57,7 @@ class network{ | @@ -54,7 +57,7 @@ class network{ | ||
54 | /// Output the edge information as a string | 57 | /// Output the edge information as a string |
55 | std::string str(){ | 58 | std::string str(){ |
56 | std::stringstream ss; | 59 | std::stringstream ss; |
57 | - ss<<"("<<cylinder<T>::size()<<")\tl = "<<length()<<"\t"<<v[0]<<"----"<<v[1]; | 60 | + ss<<"("<<cylinder<T>::size()<<")\tl = "<<this.length()<<"\t"<<v[0]<<"----"<<v[1]; |
58 | return ss.str(); | 61 | return ss.str(); |
59 | } | 62 | } |
60 | 63 | ||
@@ -64,9 +67,9 @@ class network{ | @@ -64,9 +67,9 @@ class network{ | ||
64 | class vertex : public stim::vec3<T> | 67 | class vertex : public stim::vec3<T> |
65 | { | 68 | { |
66 | public: | 69 | public: |
67 | - //std::vector<unsigned int> edges; //indices of edges connected to this node. | ||
68 | - std::vector<unsigned int> e[2]; //indices of edges going out (e[0]) and coming in (e[1]) | ||
69 | - //stim::vec3<T> p; //position of this node in physical space. | 70 | + //std::vector<unsigned int> edges; //indices of edges connected to this node. |
71 | + std::vector<unsigned int> e[2]; //indices of edges going out (e[0]) and coming in (e[1]) | ||
72 | + //stim::vec3<T> p; //position of this node in physical space. | ||
70 | 73 | ||
71 | //constructor takes a stim::vec | 74 | //constructor takes a stim::vec |
72 | vertex(stim::vec3<T> p) : stim::vec3<T>(p){} | 75 | vertex(stim::vec3<T> p) : stim::vec3<T>(p){} |
@@ -99,6 +102,18 @@ protected: | @@ -99,6 +102,18 @@ protected: | ||
99 | 102 | ||
100 | public: | 103 | public: |
101 | 104 | ||
105 | + ///default constructor | ||
106 | + network() | ||
107 | + { | ||
108 | + | ||
109 | + } | ||
110 | + | ||
111 | + ///constructor with a file to load. | ||
112 | + network(std::string fileLocation) | ||
113 | + { | ||
114 | + load_obj(fileLocation); | ||
115 | + } | ||
116 | + | ||
102 | ///Returns the number of edges in the network. | 117 | ///Returns the number of edges in the network. |
103 | unsigned int edges(){ | 118 | unsigned int edges(){ |
104 | return E.size(); | 119 | return E.size(); |
@@ -110,71 +125,74 @@ public: | @@ -110,71 +125,74 @@ public: | ||
110 | } | 125 | } |
111 | 126 | ||
112 | stim::cylinder<T> get_cylinder(unsigned f){ | 127 | stim::cylinder<T> get_cylinder(unsigned f){ |
113 | - return E[f]; //return the specified edge (casting it to a fiber) | 128 | + return E[f]; //return the specified edge (casting it to a fiber) |
114 | } | 129 | } |
115 | 130 | ||
116 | //load a network from an OBJ file | 131 | //load a network from an OBJ file |
117 | void load_obj(std::string filename){ | 132 | void load_obj(std::string filename){ |
118 | 133 | ||
119 | - stim::obj<T> O; //create an OBJ object | ||
120 | - O.load(filename); //load the OBJ file as an object | 134 | + stim::obj<T> O; //create an OBJ object |
135 | + O.load(filename); //load the OBJ file as an object | ||
121 | 136 | ||
122 | - std::vector<unsigned> id2vert; //this list stores the OBJ vertex ID associated with each network vertex | 137 | + std::vector<unsigned> id2vert; //this list stores the OBJ vertex ID associated with each network vertex |
123 | 138 | ||
124 | - unsigned i[2]; //temporary, IDs associated with the first and last points in an OBJ line | 139 | + unsigned i[2]; //temporary, IDs associated with the first and last points in an OBJ line |
125 | 140 | ||
126 | //for each line in the OBJ object | 141 | //for each line in the OBJ object |
127 | for(unsigned int l = 1; l <= O.numL(); l++){ | 142 | for(unsigned int l = 1; l <= O.numL(); l++){ |
128 | 143 | ||
129 | - std::vector< stim::vec<T> > c; //allocate an array of points for the vessel centerline | 144 | + std::vector< stim::vec<T> > c; //allocate an array of points for the vessel centerline |
130 | O.getLine(l, c); //get the fiber centerline | 145 | O.getLine(l, c); //get the fiber centerline |
131 | 146 | ||
132 | std::vector< stim::vec3<T> > c3(c.size()); | 147 | std::vector< stim::vec3<T> > c3(c.size()); |
133 | for(size_t j = 0; j < c.size(); j++) | 148 | for(size_t j = 0; j < c.size(); j++) |
134 | c3[j] = c[j]; | 149 | c3[j] = c[j]; |
135 | 150 | ||
136 | - edge new_edge = c3; //create an edge from the given centerline | ||
137 | - unsigned int I = new_edge.size(); //calculate the number of points on the centerline | 151 | + // edge new_edge = c3; ///This is dangerous. |
152 | + edge new_edge(c3); | ||
153 | + | ||
154 | + //create an edge from the given centerline | ||
155 | + unsigned int I = new_edge.size(); //calculate the number of points on the centerline | ||
138 | 156 | ||
139 | //get the first and last vertex IDs for the line | 157 | //get the first and last vertex IDs for the line |
140 | - std::vector< unsigned > id; //create an array to store the centerline point IDs | 158 | + std::vector< unsigned > id; //create an array to store the centerline point IDs |
141 | O.getLinei(l, id); //get the list of point IDs for the line | 159 | O.getLinei(l, id); //get the list of point IDs for the line |
142 | i[0] = id.front(); //get the OBJ ID for the first element of the line | 160 | i[0] = id.front(); //get the OBJ ID for the first element of the line |
143 | i[1] = id.back(); //get the OBJ ID for the last element of the line | 161 | i[1] = id.back(); //get the OBJ ID for the last element of the line |
144 | 162 | ||
145 | - std::vector<unsigned>::iterator it; //create an iterator for searching the id2vert array | 163 | + std::vector<unsigned>::iterator it; //create an iterator for searching the id2vert array |
146 | unsigned it_idx; //create an integer for the id2vert entry index | 164 | unsigned it_idx; //create an integer for the id2vert entry index |
147 | 165 | ||
148 | //find out if the nodes for this fiber have already been created | 166 | //find out if the nodes for this fiber have already been created |
149 | - it = find(id2vert.begin(), id2vert.end(), i[0]); //look for the first node | 167 | + it = find(id2vert.begin(), id2vert.end(), i[0]); //look for the first node |
150 | it_idx = std::distance(id2vert.begin(), it); | 168 | it_idx = std::distance(id2vert.begin(), it); |
151 | - if(it == id2vert.end()){ //if i[0] hasn't already been used | 169 | + if(it == id2vert.end()){ //if i[0] hasn't already been used |
152 | vertex new_vertex = new_edge[0]; //create a new vertex, assign it a position | 170 | vertex new_vertex = new_edge[0]; //create a new vertex, assign it a position |
153 | - new_vertex.e[0].push_back(E.size()); //add the current edge as outgoing | ||
154 | - new_edge.v[0] = V.size(); //add the new vertex to the edge | ||
155 | - V.push_back(new_vertex); //add the new vertex to the vertex list | ||
156 | - id2vert.push_back(i[0]); //add the ID to the ID->vertex conversion list | 171 | + new_vertex.e[0].push_back(E.size()); //add the current edge as outgoing |
172 | + new_edge.v[0] = V.size(); //add the new edge to the edge | ||
173 | + V.push_back(new_vertex); //add the new vertex to the vertex list | ||
174 | + id2vert.push_back(i[0]); //add the ID to the ID->vertex conversion list | ||
157 | } | 175 | } |
158 | - else{ //if the vertex already exists | 176 | + else{ //if the vertex already exists |
159 | V[it_idx].e[0].push_back(E.size()); //add the current edge as outgoing | 177 | V[it_idx].e[0].push_back(E.size()); //add the current edge as outgoing |
160 | new_edge.v[0] = it_idx; | 178 | new_edge.v[0] = it_idx; |
161 | } | 179 | } |
162 | 180 | ||
163 | - it = find(id2vert.begin(), id2vert.end(), i[1]); //look for the second ID | 181 | + it = find(id2vert.begin(), id2vert.end(), i[1]); //look for the second ID |
164 | it_idx = std::distance(id2vert.begin(), it); | 182 | it_idx = std::distance(id2vert.begin(), it); |
165 | - if(it == id2vert.end()){ //if i[1] hasn't already been used | ||
166 | - vertex new_vertex = new_edge[I-1]; //create a new vertex, assign it a position | ||
167 | - new_vertex.e[1].push_back(E.size()); //add the current edge as incoming | 183 | + if(it == id2vert.end()){ //if i[1] hasn't already been used |
184 | + vertex new_vertex = new_edge[I-1]; //create a new vertex, assign it a position | ||
185 | + new_vertex.e[1].push_back(E.size()); //add the current edge as incoming | ||
168 | new_edge.v[1] = V.size(); | 186 | new_edge.v[1] = V.size(); |
169 | - V.push_back(new_vertex); //add the new vertex to the vertex list | ||
170 | - id2vert.push_back(i[1]); //add the ID to the ID->vertex conversion list | 187 | + V.push_back(new_vertex); //add the new vertex to the vertex list |
188 | + id2vert.push_back(i[1]); //add the ID to the ID->vertex conversion list | ||
171 | } | 189 | } |
172 | - else{ //if the vertex already exists | 190 | + else{ //if the vertex already exists |
173 | V[it_idx].e[1].push_back(E.size()); //add the current edge as incoming | 191 | V[it_idx].e[1].push_back(E.size()); //add the current edge as incoming |
174 | new_edge.v[1] = it_idx; | 192 | new_edge.v[1] = it_idx; |
175 | } | 193 | } |
176 | 194 | ||
177 | - E.push_back(new_edge); //push the edge to the list | 195 | + E.push_back(new_edge); //push the edge to the list |
178 | 196 | ||
179 | } | 197 | } |
180 | } | 198 | } |
@@ -199,17 +217,17 @@ public: | @@ -199,17 +217,17 @@ public: | ||
199 | /// This function resamples all fibers in a network given a desired minimum spacing | 217 | /// This function resamples all fibers in a network given a desired minimum spacing |
200 | /// @param spacing is the minimum distance between two points on the network | 218 | /// @param spacing is the minimum distance between two points on the network |
201 | stim::network<T> resample(T spacing){ | 219 | stim::network<T> resample(T spacing){ |
202 | - stim::network<T> n; //create a new network that will be an exact copy, with resampled fibers | ||
203 | - n.V = V; //copy all vertices | 220 | + stim::network<T> n; //create a new network that will be an exact copy, with resampled fibers |
221 | + n.V = V; //copy all vertices | ||
204 | 222 | ||
205 | - n.E.resize(edges()); //allocate space for the edge list | 223 | + n.E.resize(edges()); //allocate space for the edge list |
206 | 224 | ||
207 | //copy all fibers, resampling them in the process | 225 | //copy all fibers, resampling them in the process |
208 | - for(unsigned e = 0; e < edges(); e++){ //for each edge in the edge list | ||
209 | - n.E[e] = E[e].resample(spacing); //resample the edge and copy it to the new network | 226 | + for(unsigned e = 0; e < edges(); e++){ //for each edge in the edge list |
227 | + n.E[e] = E[e].resample(spacing); //resample the edge and copy it to the new network | ||
210 | } | 228 | } |
211 | 229 | ||
212 | - return n; //return the resampled network | 230 | + return n; //return the resampled network |
213 | } | 231 | } |
214 | 232 | ||
215 | 233 | ||
@@ -236,14 +254,14 @@ public: | @@ -236,14 +254,14 @@ public: | ||
236 | /// @param m is the magnitude value to use. The default is 0 (usually radius). | 254 | /// @param m is the magnitude value to use. The default is 0 (usually radius). |
237 | T average(unsigned m = 0){ | 255 | T average(unsigned m = 0){ |
238 | 256 | ||
239 | - T M, L; //allocate space for the total magnitude and length | ||
240 | - M = L = 0; //initialize both the initial magnitude and length to zero | ||
241 | - for(unsigned e = 0; e < E.size(); e++){ //for each edge in the network | 257 | + T M, L; //allocate space for the total magnitude and length |
258 | + M = L = 0; //initialize both the initial magnitude and length to zero | ||
259 | + for(unsigned e = 0; e < E.size(); e++){ //for each edge in the network | ||
242 | M += E[e].integrate(m); //get the integrated magnitude | 260 | M += E[e].integrate(m); //get the integrated magnitude |
243 | - L += E[e].length(); //get the edge length | 261 | + L += E[e].length(); //get the edge length |
244 | } | 262 | } |
245 | 263 | ||
246 | - return M / L; //return the average magnitude | 264 | + return M / L; //return the average magnitude |
247 | } | 265 | } |
248 | 266 | ||
249 | /// This function compares two networks and returns the percentage of the current network that is missing from A. | 267 | /// This function compares two networks and returns the percentage of the current network that is missing from A. |
@@ -256,17 +274,17 @@ public: | @@ -256,17 +274,17 @@ public: | ||
256 | R = (*this); //initialize the result with the current network | 274 | R = (*this); //initialize the result with the current network |
257 | 275 | ||
258 | //generate a KD-tree for network A | 276 | //generate a KD-tree for network A |
259 | - float metric = 0.0; // initialize metric to be returned after comparing the networks | ||
260 | - ANNkd_tree* kdt; // initialize a pointer to a kd tree | ||
261 | - double **c; // centerline (array of double pointers) - points on kdtree must be double | ||
262 | - unsigned int n_data = A.total_points(); // set the number of points | ||
263 | - c = (double**) malloc(sizeof(double*) * n_data); // allocate the array pointer | ||
264 | - for(unsigned int i = 0; i < n_data; i++) // allocate space for each point of 3 dimensions | 277 | + float metric = 0.0; // initialize metric to be returned after comparing the networks |
278 | + ANNkd_tree* kdt; // initialize a pointer to a kd tree | ||
279 | + double **c; // centerline (array of double pointers) - points on kdtree must be double | ||
280 | + unsigned int n_data = A.total_points(); // set the number of points | ||
281 | + c = (double**) malloc(sizeof(double*) * n_data); // allocate the array pointer | ||
282 | + for(unsigned int i = 0; i < n_data; i++) // allocate space for each point of 3 dimensions | ||
265 | c[i] = (double*) malloc(sizeof(double) * 3); | 283 | c[i] = (double*) malloc(sizeof(double) * 3); |
266 | 284 | ||
267 | unsigned t = 0; | 285 | unsigned t = 0; |
268 | for(unsigned e = 0; e < A.E.size(); e++){ //for each edge in the network | 286 | for(unsigned e = 0; e < A.E.size(); e++){ //for each edge in the network |
269 | - for(unsigned p = 0; p < A.E[e].size(); p++){ //for each point in the edge | 287 | + for(unsigned p = 0; p < A.E[e].size(); p++){ //for each point in the edge |
270 | for(unsigned d = 0; d < 3; d++){ //for each coordinate | 288 | for(unsigned d = 0; d < 3; d++){ //for each coordinate |
271 | 289 | ||
272 | c[t][d] = A.E[e][p][d]; | 290 | c[t][d] = A.E[e][p][d]; |
@@ -276,27 +294,27 @@ public: | @@ -276,27 +294,27 @@ public: | ||
276 | } | 294 | } |
277 | 295 | ||
278 | //compare each point in the current network to the field produced by A | 296 | //compare each point in the current network to the field produced by A |
279 | - ANNpointArray pts = (ANNpointArray)c; // create an array of data points of type double | ||
280 | - kdt = new ANNkd_tree(pts, n_data, 3); // build a KD tree using the annpointarray | 297 | + ANNpointArray pts = (ANNpointArray)c; // create an array of data points of type double |
298 | + kdt = new ANNkd_tree(pts, n_data, 3); // build a KD tree using the annpointarray | ||
281 | double eps = 0; // error bound | 299 | double eps = 0; // error bound |
282 | - ANNdistArray dists = new ANNdist[1]; // near neighbor distances | ||
283 | - ANNidxArray nnIdx = new ANNidx[1]; // near neighbor indices // allocate near neigh indices | 300 | + ANNdistArray dists = new ANNdist[1]; // near neighbor distances |
301 | + ANNidxArray nnIdx = new ANNidx[1]; // near neighbor indices // allocate near neigh indices | ||
284 | 302 | ||
285 | stim::vec3<T> p0, p1; | 303 | stim::vec3<T> p0, p1; |
286 | float m1; | 304 | float m1; |
287 | - float M = 0; //stores the total metric value | ||
288 | - float L = 0; //stores the total network length | 305 | + float M = 0; //stores the total metric value |
306 | + float L = 0; //stores the total network length | ||
289 | ANNpoint queryPt = annAllocPt(3); | 307 | ANNpoint queryPt = annAllocPt(3); |
290 | for(unsigned e = 0; e < R.E.size(); e++){ //for each edge in A | 308 | for(unsigned e = 0; e < R.E.size(); e++){ //for each edge in A |
291 | - R.E[e].add_mag(0); //add a new magnitude for the metric | 309 | + R.E[e].add_mag(0); //add a new magnitude for the metric |
292 | 310 | ||
293 | - for(unsigned p = 0; p < R.E[e].size(); p++){ //for each point in the edge | 311 | + for(unsigned p = 0; p < R.E[e].size(); p++){ //for each point in the edge |
294 | 312 | ||
295 | - p1 = R.E[e][p]; //get the next point in the edge | 313 | + p1 = R.E[e][p]; //get the next point in the edge |
296 | stim2ann(queryPt, p1); | 314 | stim2ann(queryPt, p1); |
297 | - kdt->annkSearch( queryPt, 1, nnIdx, dists, eps); //find the distance between A and the current network | 315 | + kdt->annkSearch( queryPt, 1, nnIdx, dists, eps); //find the distance between A and the current network |
298 | m1 = 1.0f - gaussianFunction((float)dists[0], sigma); //calculate the metric value based on the distance | 316 | m1 = 1.0f - gaussianFunction((float)dists[0], sigma); //calculate the metric value based on the distance |
299 | - R.E[e].set_mag(m1, p, 1); //set the error for the second point in the segment | 317 | + R.E[e].set_mag(m1, p, 1); //set the error for the second point in the segment |
300 | 318 | ||
301 | } | 319 | } |
302 | } | 320 | } |
stim/math/vec3.h
stim/visualization/gl_aaboundingbox.h
@@ -11,6 +11,9 @@ class gl_aaboundingbox : public aaboundingbox<T>{ | @@ -11,6 +11,9 @@ class gl_aaboundingbox : public aaboundingbox<T>{ | ||
11 | 11 | ||
12 | public: | 12 | public: |
13 | 13 | ||
14 | + using stim::aaboundingbox<T>::A; | ||
15 | + using stim::aaboundingbox<T>::B; | ||
16 | + | ||
14 | //default constructor | 17 | //default constructor |
15 | gl_aaboundingbox() : stim::aaboundingbox<T>(){} | 18 | gl_aaboundingbox() : stim::aaboundingbox<T>(){} |
16 | 19 | ||
@@ -57,4 +60,4 @@ public: | @@ -57,4 +60,4 @@ public: | ||
57 | 60 | ||
58 | }; //end namespace stim | 61 | }; //end namespace stim |
59 | 62 | ||
60 | -#endif | ||
61 | \ No newline at end of file | 63 | \ No newline at end of file |
64 | +#endif |