Commit 3800c27f696781bd2349f1121cfa39d57bc56aff
1 parent
7c43b7f9
added code to subdivide networks
Showing
2 changed files
with
60 additions
and
36 deletions
Show diff stats
stim/biomodels/fiber.h
@@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
5 | #include <ANN/ANN.h> | 5 | #include <ANN/ANN.h> |
6 | 6 | ||
7 | namespace stim{ | 7 | namespace stim{ |
8 | - | 8 | + |
9 | /** This class stores information about a single fiber represented as a set of geometric points | 9 | /** This class stores information about a single fiber represented as a set of geometric points |
10 | * between two branch or end points. This class is used as a fundamental component of the stim::network | 10 | * between two branch or end points. This class is used as a fundamental component of the stim::network |
11 | * class to describe an interconnected (often biological) network. | 11 | * class to describe an interconnected (often biological) network. |
@@ -39,7 +39,7 @@ protected: | @@ -39,7 +39,7 @@ protected: | ||
39 | 39 | ||
40 | for(unsigned int i = 0; i < N; i++) //allocate space for each point | 40 | for(unsigned int i = 0; i < N; i++) //allocate space for each point |
41 | c[i] = (double*) malloc(sizeof(double) * 3); | 41 | c[i] = (double*) malloc(sizeof(double) * 3); |
42 | - | 42 | + |
43 | r = (T*) malloc(sizeof(T) * N); //allocate space for the radii | 43 | r = (T*) malloc(sizeof(T) * N); //allocate space for the radii |
44 | } | 44 | } |
45 | 45 | ||
@@ -62,7 +62,7 @@ protected: | @@ -62,7 +62,7 @@ protected: | ||
62 | gen_kdtree(); //generate the kd tree for the new fiber | 62 | gen_kdtree(); //generate the kd tree for the new fiber |
63 | } | 63 | } |
64 | 64 | ||
65 | - /// generate a KD tree for points on fiber | 65 | + /// generate a KD tree for points on fiber |
66 | void gen_kdtree() | 66 | void gen_kdtree() |
67 | { | 67 | { |
68 | int n_data = N; //create an array of data points | 68 | int n_data = N; //create an array of data points |
@@ -123,7 +123,7 @@ public: | @@ -123,7 +123,7 @@ public: | ||
123 | copy(obj); | 123 | copy(obj); |
124 | 124 | ||
125 | } | 125 | } |
126 | - | 126 | + |
127 | //temp constructor for graph visualization | 127 | //temp constructor for graph visualization |
128 | fiber(int n) | 128 | fiber(int n) |
129 | { | 129 | { |
@@ -218,7 +218,7 @@ public: | @@ -218,7 +218,7 @@ public: | ||
218 | 218 | ||
219 | return l; //return the length | 219 | return l; //return the length |
220 | } | 220 | } |
221 | - | 221 | + |
222 | /// Calculates the length and average radius of the fiber | 222 | /// Calculates the length and average radius of the fiber |
223 | 223 | ||
224 | /// @param length is filled with the fiber length | 224 | /// @param length is filled with the fiber length |
@@ -267,7 +267,7 @@ public: | @@ -267,7 +267,7 @@ public: | ||
267 | T r_sum = 0.; | 267 | T r_sum = 0.; |
268 | for(unsigned int i = 0; i < N; i++) | 268 | for(unsigned int i = 0; i < N; i++) |
269 | { | 269 | { |
270 | - r_sum = r_sum + r[i]; | 270 | + r_sum = r_sum + r[i]; |
271 | } | 271 | } |
272 | return r_sum/((T) N); | 272 | return r_sum/((T) N); |
273 | } | 273 | } |
@@ -282,16 +282,16 @@ public: | @@ -282,16 +282,16 @@ public: | ||
282 | T radius(int idx){ | 282 | T radius(int idx){ |
283 | return r[idx]; | 283 | return r[idx]; |
284 | } | 284 | } |
285 | - /// get index of a node on a fiber | 285 | + /// get index of a node on a fiber |
286 | // by matching the node on fiber to already set vertices (both strings) | 286 | // by matching the node on fiber to already set vertices (both strings) |
287 | // used in obj file conversion | 287 | // used in obj file conversion |
288 | - int | ||
289 | - getIndexes(std::string* input, std::string searched, int sizeV) | 288 | + int |
289 | + getIndexes(std::string* input, std::string searched, int sizeV) | ||
290 | { | 290 | { |
291 | int result = 0; | 291 | int result = 0; |
292 | for (int i = 0; i < sizeV; i++) | 292 | for (int i = 0; i < sizeV; i++) |
293 | { | 293 | { |
294 | - if (input[i] == searched) | 294 | + if (input[i] == searched) |
295 | { | 295 | { |
296 | result = i + 1; | 296 | result = i + 1; |
297 | } | 297 | } |
@@ -453,7 +453,7 @@ public: | @@ -453,7 +453,7 @@ public: | ||
453 | 453 | ||
454 | /// @param i is the index of the element to be returned as a stim::vec | 454 | /// @param i is the index of the element to be returned as a stim::vec |
455 | stim::vec<T> operator[](unsigned i){ | 455 | stim::vec<T> operator[](unsigned i){ |
456 | - return get_vec(i); | 456 | + return get_vec(i); |
457 | } | 457 | } |
458 | 458 | ||
459 | /// Back method returns the last point in the fiber | 459 | /// Back method returns the last point in the fiber |
@@ -461,14 +461,14 @@ public: | @@ -461,14 +461,14 @@ public: | ||
461 | return get_vec(N-1); | 461 | return get_vec(N-1); |
462 | } | 462 | } |
463 | ////resample a fiber in the network | 463 | ////resample a fiber in the network |
464 | - stim::fiber<T> Resample(T spacing=25.0) | 464 | + stim::fiber<T> resample(T spacing=25.0) |
465 | { | 465 | { |
466 | 466 | ||
467 | 467 | ||
468 | std::vector<T> v(3); //v-direction vector of the segment | 468 | std::vector<T> v(3); //v-direction vector of the segment |
469 | stim::vec<T> p(3); //- intermediate point to be added | 469 | stim::vec<T> p(3); //- intermediate point to be added |
470 | - std::vector<T> p1(3); // p1 - starting point of an segment on the fiber, | ||
471 | - std::vector<T> p2(3); // p2 - ending point, | 470 | + std::vector<T> p1(3); // p1 - starting point of an segment on the fiber, |
471 | + std::vector<T> p2(3); // p2 - ending point, | ||
472 | double sum=0; //distance summation | 472 | double sum=0; //distance summation |
473 | std::vector<stim::vec<T> > fiberPositions = centerline(); | 473 | std::vector<stim::vec<T> > fiberPositions = centerline(); |
474 | std::vector<stim::vec<T> > newPointList; // initialize list of new resampled points on the fiber | 474 | std::vector<stim::vec<T> > newPointList; // initialize list of new resampled points on the fiber |
@@ -483,7 +483,7 @@ public: | @@ -483,7 +483,7 @@ public: | ||
483 | v[d] = p2[d] - p1[d]; //direction vector | 483 | v[d] = p2[d] - p1[d]; //direction vector |
484 | sum +=v[d] * v[d]; //length of segment-distance between starting and ending point | 484 | sum +=v[d] * v[d]; //length of segment-distance between starting and ending point |
485 | } | 485 | } |
486 | - newPointList.push_back(fiberPositions[f]); //always push the starting point | 486 | + //newPointList.push_back(fiberPositions[f]); //always push the starting point |
487 | 487 | ||
488 | T lengthSegment = sqrt(sum); //find Length of the segment as distance between the starting and ending points of the segment | 488 | T lengthSegment = sqrt(sum); //find Length of the segment as distance between the starting and ending points of the segment |
489 | 489 |
stim/biomodels/network.h
@@ -37,8 +37,20 @@ class network{ | @@ -37,8 +37,20 @@ class network{ | ||
37 | 37 | ||
38 | /// Constructor - creates an edge from a list of points by calling the stim::fiber constructor | 38 | /// Constructor - creates an edge from a list of points by calling the stim::fiber constructor |
39 | 39 | ||
40 | - ///@param p is a position in space | 40 | + ///@param p is an array of positions in space |
41 | edge(std::vector< stim::vec<T> > p) : fiber<T>(p){} | 41 | edge(std::vector< stim::vec<T> > p) : fiber<T>(p){} |
42 | + | ||
43 | + /// Copy constructor creates an edge from a fiber | ||
44 | + edge(stim::fiber<T> f) : fiber<T>(f) {} | ||
45 | + | ||
46 | + /// Resamples an edge by calling the fiber resampling function | ||
47 | + edge resample(T spacing){ | ||
48 | + edge e(fiber<T>::resample()); //call the fiber->edge constructor | ||
49 | + e.v[0] = v[0]; //copy the vertex data | ||
50 | + e.v[1] = v[1]; | ||
51 | + | ||
52 | + return e; //return the new edge | ||
53 | + } | ||
42 | 54 | ||
43 | /// Output the edge information as a string | 55 | /// Output the edge information as a string |
44 | std::string str(){ | 56 | std::string str(){ |
@@ -98,15 +110,16 @@ class network{ | @@ -98,15 +110,16 @@ class network{ | ||
98 | return V.size(); | 110 | return V.size(); |
99 | } | 111 | } |
100 | 112 | ||
113 | + stim::fiber<T> get_fiber(unsigned f){ | ||
114 | + return E[f]; //return the specified edge (casting it to a fiber) | ||
115 | + } | ||
116 | + | ||
101 | //load a network from an OBJ file | 117 | //load a network from an OBJ file |
102 | void load_obj(std::string filename){ | 118 | void load_obj(std::string filename){ |
103 | 119 | ||
104 | stim::obj<T> O; //create an OBJ object | 120 | stim::obj<T> O; //create an OBJ object |
105 | O.load(filename); //load the OBJ file as an object | 121 | O.load(filename); //load the OBJ file as an object |
106 | 122 | ||
107 | - //prints each line in the obj file - vertex positions and fibers | ||
108 | - std::cout<<O.str()<<std::endl; | ||
109 | - | ||
110 | std::vector<unsigned> id2vert; //this list stores the OBJ vertex ID associated with each network vertex | 123 | std::vector<unsigned> id2vert; //this list stores the OBJ vertex ID associated with each network vertex |
111 | 124 | ||
112 | unsigned i[2]; //temporary, IDs associated with the first and last points in an OBJ line | 125 | unsigned i[2]; //temporary, IDs associated with the first and last points in an OBJ line |
@@ -117,7 +130,7 @@ class network{ | @@ -117,7 +130,7 @@ class network{ | ||
117 | std::vector< stim::vec<T> > c; //allocate an array of points for the vessel centerline | 130 | std::vector< stim::vec<T> > c; //allocate an array of points for the vessel centerline |
118 | O.getLine(l, c); //get the fiber centerline | 131 | O.getLine(l, c); //get the fiber centerline |
119 | 132 | ||
120 | - edge e = c; //create an edge from the given centerline | 133 | + edge new_edge = c; //create an edge from the given centerline |
121 | 134 | ||
122 | //get the first and last vertex IDs for the line | 135 | //get the first and last vertex IDs for the line |
123 | std::vector< unsigned > id; //create an array to store the centerline point IDs | 136 | std::vector< unsigned > id; //create an array to store the centerline point IDs |
@@ -132,36 +145,32 @@ class network{ | @@ -132,36 +145,32 @@ class network{ | ||
132 | it = find(id2vert.begin(), id2vert.end(), i[0]); //look for the first node | 145 | it = find(id2vert.begin(), id2vert.end(), i[0]); //look for the first node |
133 | it_idx = std::distance(id2vert.begin(), it); | 146 | it_idx = std::distance(id2vert.begin(), it); |
134 | if(it == id2vert.end()){ //if i[0] hasn't already been used | 147 | if(it == id2vert.end()){ //if i[0] hasn't already been used |
135 | - vertex v = e[0]; //create a new vertex, assign it a position | ||
136 | - v.e[0].push_back(E.size()); //add the current edge as outgoing | ||
137 | - e.v[0] = V.size(); //add the new vertex to the edge | ||
138 | - V.push_back(v); //add the new vertex to the vertex list | 148 | + vertex new_vertex = new_edge[0]; //create a new vertex, assign it a position |
149 | + new_vertex.e[0].push_back(E.size()); //add the current edge as outgoing | ||
150 | + new_edge.v[0] = V.size(); //add the new vertex to the edge | ||
151 | + V.push_back(new_vertex); //add the new vertex to the vertex list | ||
139 | id2vert.push_back(i[0]); //add the ID to the ID->vertex conversion list | 152 | id2vert.push_back(i[0]); //add the ID to the ID->vertex conversion list |
140 | } | 153 | } |
141 | else{ //if the vertex already exists | 154 | else{ //if the vertex already exists |
142 | V[it_idx].e[0].push_back(E.size()); //add the current edge as outgoing | 155 | V[it_idx].e[0].push_back(E.size()); //add the current edge as outgoing |
143 | - e.v[0] = it_idx; | 156 | + new_edge.v[0] = it_idx; |
144 | } | 157 | } |
145 | 158 | ||
146 | it = find(id2vert.begin(), id2vert.end(), i[1]); //look for the second ID | 159 | it = find(id2vert.begin(), id2vert.end(), i[1]); //look for the second ID |
147 | it_idx = std::distance(id2vert.begin(), it); | 160 | it_idx = std::distance(id2vert.begin(), it); |
148 | if(it == id2vert.end()){ //if i[1] hasn't already been used | 161 | if(it == id2vert.end()){ //if i[1] hasn't already been used |
149 | - vertex v = e.back(); //create a new vertex, assign it a position | ||
150 | - v.e[1].push_back(E.size()); //add the current edge as incoming | ||
151 | - e.v[1] = V.size(); | ||
152 | - V.push_back(v); //add the new vertex to the vertex list | 162 | + vertex new_vertex = new_edge.back(); //create a new vertex, assign it a position |
163 | + new_vertex.e[1].push_back(E.size()); //add the current edge as incoming | ||
164 | + new_edge.v[1] = V.size(); | ||
165 | + V.push_back(new_vertex); //add the new vertex to the vertex list | ||
153 | id2vert.push_back(i[1]); //add the ID to the ID->vertex conversion list | 166 | id2vert.push_back(i[1]); //add the ID to the ID->vertex conversion list |
154 | } | 167 | } |
155 | else{ //if the vertex already exists | 168 | else{ //if the vertex already exists |
156 | V[it_idx].e[1].push_back(E.size()); //add the current edge as incoming | 169 | V[it_idx].e[1].push_back(E.size()); //add the current edge as incoming |
157 | - e.v[1] = it_idx; | 170 | + new_edge.v[1] = it_idx; |
158 | } | 171 | } |
159 | - stim::fiber<T> f = e.Resample(25.0); | ||
160 | - std::cout<<"resampled fiber length"<<std::endl; | ||
161 | - std::cout<<f.length()<<std::endl; | ||
162 | - std::cout<<"resampled fiber--"<<std::endl; | ||
163 | - std::cout<<f.str()<<std::endl; | ||
164 | - E.push_back(e); //push the edge to the list | 172 | + |
173 | + E.push_back(new_edge); //push the edge to the list | ||
165 | 174 | ||
166 | } | 175 | } |
167 | } | 176 | } |
@@ -182,6 +191,21 @@ class network{ | @@ -182,6 +191,21 @@ class network{ | ||
182 | 191 | ||
183 | return ss.str(); | 192 | return ss.str(); |
184 | } | 193 | } |
194 | + | ||
195 | + /// This function resamples all fibers in a network given a desired minimum spacing | ||
196 | + stim::network<T> resample(T spacing){ | ||
197 | + stim::network<T> n; //create a new network that will be an exact copy, with resampled fibers | ||
198 | + n.V = V; //copy all vertices | ||
199 | + | ||
200 | + n.E.resize(E.size()); //allocate space for the edge list | ||
201 | + | ||
202 | + //copy all fibers, resampling them in the process | ||
203 | + for(unsigned e = 0; e < E.size(); e++){ //for each edge in the edge list | ||
204 | + n.E[e] = E[e].resample(spacing); //resample the edge and copy it to the new network | ||
205 | + } | ||
206 | + | ||
207 | + return n; //return the resampled network | ||
208 | + } | ||
185 | }; //end stim::network class | 209 | }; //end stim::network class |
186 | }; //end stim namespace | 210 | }; //end stim namespace |
187 | #endif | 211 | #endif |