Commit e376212f1c48b3bd6dabebe11f7f0f76b4fac008
1 parent
fa737592
added support for exporting stim::network to stim::obj
Showing
3 changed files
with
158 additions
and
6 deletions
Show diff stats
stim/biomodels/network.h
... | ... | @@ -18,7 +18,7 @@ namespace stim{ |
18 | 18 | template<typename T> |
19 | 19 | class network{ |
20 | 20 | |
21 | - //helper classes | |
21 | + //-------------------HELPER CLASSES----------------------- | |
22 | 22 | /// Stores information about a geometric point on the network centerline (including point position and radius) |
23 | 23 | //template<typename T> |
24 | 24 | class point : public stim::vec<T>{ |
... | ... | @@ -113,6 +113,24 @@ class network{ |
113 | 113 | return radius_sum / length; //return the average radius of the fiber |
114 | 114 | } |
115 | 115 | |
116 | + std::vector< stim::vec<T> > geometry(){ | |
117 | + | |
118 | + std::vector< stim::vec<T> > result; //create an array to store the fiber geometry | |
119 | + result.resize( P.size() ); //pre-allocate the array | |
120 | + | |
121 | + typename std::list< point >::iterator p; //create a list iterator | |
122 | + unsigned int pi = 0; //create an index into the result array | |
123 | + | |
124 | + //for each geometric point on the fiber centerline | |
125 | + for(p = P.begin(); p != P.end(); p++){ | |
126 | + result[pi] = *p; | |
127 | + pi++; | |
128 | + } | |
129 | + | |
130 | + return result; //return the geometry array | |
131 | + | |
132 | + } | |
133 | + | |
116 | 134 | std::string str(){ |
117 | 135 | std::stringstream ss; |
118 | 136 | |
... | ... | @@ -177,7 +195,7 @@ class network{ |
177 | 195 | }; |
178 | 196 | |
179 | 197 | |
180 | - | |
198 | +//---------------NETWORK CLASS----------------------------- | |
181 | 199 | |
182 | 200 | protected: |
183 | 201 | |
... | ... | @@ -236,6 +254,8 @@ public: |
236 | 254 | } |
237 | 255 | |
238 | 256 | /// Load a network from an OBJ object |
257 | + | |
258 | + /// @param object is the object file to be used as the basis for the network | |
239 | 259 | void load( stim::obj<T> object){ |
240 | 260 | |
241 | 261 | //get the number of vertices in the object |
... | ... | @@ -302,6 +322,95 @@ public: |
302 | 322 | |
303 | 323 | } //end load() |
304 | 324 | |
325 | + /// Returns an array of node positions | |
326 | + std::vector< stim::vec<T> > get_node_positions(){ | |
327 | + | |
328 | + std::vector< stim::vec<T> > result; //create an array to store the result | |
329 | + result.resize(N.size()); //set the array size | |
330 | + | |
331 | + t_node_i ni; //create a terminal node iterator | |
332 | + unsigned int vi = 0; //vertex index into the result array | |
333 | + | |
334 | + //for every terminal node | |
335 | + for(ni = N.begin(); ni != N.end(); ni++){ | |
336 | + | |
337 | + //create a vector based on the node position | |
338 | + | |
339 | + //if the number of outgoing nodes is nonzero | |
340 | + if(ni->out.size() != 0) | |
341 | + result[vi] = ni->out.front()->P.front(); | |
342 | + else if(ni->in.size() != 0) | |
343 | + result[vi] = ni->in.front()->P.back(); | |
344 | + | |
345 | + vi++; //increment the array index | |
346 | + } | |
347 | + | |
348 | + //return the resulting array | |
349 | + return result; | |
350 | + } | |
351 | + | |
352 | + std::vector< stim::vec<T> > get_fiber_geometry( fiber_i f ){ | |
353 | + return f->geometry(); | |
354 | + } | |
355 | + | |
356 | + /// Generate an OBJ file from the network | |
357 | + | |
358 | + stim::obj<T> obj(){ | |
359 | + | |
360 | + //create an OBJ object | |
361 | + stim::obj<T> object; | |
362 | + | |
363 | + //name the nodes | |
364 | + set_names(); | |
365 | + | |
366 | + //retrieve a list of terminal node positions | |
367 | + std::vector< stim::vec<T> > node_pos = get_node_positions(); | |
368 | + | |
369 | + //add the nodes to the obj file | |
370 | + object.addV(node_pos); | |
371 | + | |
372 | + //counter for vertex indices in the object class | |
373 | + unsigned int nP; | |
374 | + | |
375 | + //for each fiber | |
376 | + fiber_i fi; //create a fiber iterator | |
377 | + for(fi = F.begin(); fi != F.end(); fi++){ | |
378 | + | |
379 | + //get an array of fiber points | |
380 | + std::vector< stim::vec<T> > fiber_p = get_fiber_geometry(fi); | |
381 | + | |
382 | + //create a subset of this array | |
383 | + typename std::vector< stim::vec<T> >::iterator start = fiber_p.begin() + 1; | |
384 | + typename std::vector< stim::vec<T> >::iterator end = fiber_p.end() - 1; | |
385 | + typename std::vector< stim::vec<T> > fiber_subset(start, end); | |
386 | + | |
387 | + //add this subset to the geometry object | |
388 | + nP = object.addV(fiber_subset); | |
389 | + | |
390 | + //create an array to hold vertex indices for a line | |
391 | + std::vector<unsigned int> line; | |
392 | + line.resize(fiber_p.size()); | |
393 | + | |
394 | + //add the terminal nodes to the line list (make sure to add 1 to make them compatible with the OBJ) | |
395 | + line[0] = fi->n[0]->id + 1; | |
396 | + line[line.size() - 1] = fi->n[1]->id + 1; | |
397 | + | |
398 | + //add the intermediate vertex indices to the line array | |
399 | + for(unsigned int i = 0; i < fiber_subset.size(); i++){ | |
400 | + line[1 + i] = nP + i; | |
401 | + } | |
402 | + | |
403 | + //add the line list to the object class | |
404 | + object.addLine(line); | |
405 | + | |
406 | + } | |
407 | + | |
408 | + return object; | |
409 | + | |
410 | + | |
411 | + | |
412 | + } | |
413 | + | |
305 | 414 | /// This function returns the information necessary for a simple graph-based physical (ex. fluid) simulation. |
306 | 415 | |
307 | 416 | /// @param n0 is a array which will contain the list of source nodes | ... | ... |
stim/math/vector.h
... | ... | @@ -59,7 +59,7 @@ struct vec : public std::vector<T> |
59 | 59 | //copy constructor |
60 | 60 | vec( const vec<T>& other){ |
61 | 61 | unsigned int N = other.size(); |
62 | - for(int i=0; i<N; i++) | |
62 | + for(unsigned int i=0; i<N; i++) | |
63 | 63 | push_back(other[i]); |
64 | 64 | } |
65 | 65 | |
... | ... | @@ -112,7 +112,7 @@ struct vec : public std::vector<T> |
112 | 112 | |
113 | 113 | //compute and return the vector length |
114 | 114 | T sum_sq = (T)0; |
115 | - for(int i=0; i<N; i++) | |
115 | + for(unsigned int i=0; i<N; i++) | |
116 | 116 | { |
117 | 117 | sum_sq += pow( at(i), 2 ); |
118 | 118 | } |
... | ... | @@ -231,7 +231,7 @@ struct vec : public std::vector<T> |
231 | 231 | |
232 | 232 | vec<T> result(N); |
233 | 233 | |
234 | - for(int i=0; i<N; i++) | |
234 | + for(unsigned int i=0; i<N; i++) | |
235 | 235 | result[i] = at(i) - rhs[i]; |
236 | 236 | |
237 | 237 | return result; |
... | ... | @@ -340,7 +340,7 @@ struct vec : public std::vector<T> |
340 | 340 | unsigned int N = size(); |
341 | 341 | |
342 | 342 | ss<<"["; |
343 | - for(int i=0; i<N; i++) | |
343 | + for(unsigned int i=0; i<N; i++) | |
344 | 344 | { |
345 | 345 | ss<<at(i); |
346 | 346 | if(i != N-1) | ... | ... |
stim/visualization/obj.h
... | ... | @@ -52,6 +52,8 @@ protected: |
52 | 52 | vertex(T x, T y, T z) : stim::vec<T>(x, y, z){} |
53 | 53 | vertex(T x, T y, T z, T w) : stim::vec<T>(x, y, z, w){} |
54 | 54 | |
55 | + vertex(stim::vec<T> rhs) : stim::vec<T>(rhs){} | |
56 | + | |
55 | 57 | //constructor creates a vertex from a line string |
56 | 58 | vertex(std::string line){ |
57 | 59 | |
... | ... | @@ -631,6 +633,47 @@ public: |
631 | 633 | } |
632 | 634 | |
633 | 635 | return l; |
636 | + } | |
637 | + | |
638 | + /// Add an array of vertices to the vertex list | |
639 | + unsigned int addV(std::vector< stim::vec<T> > vertices){ | |
640 | + | |
641 | + unsigned int NV = vertices.size(); //get the total number of new vertices | |
642 | + | |
643 | + unsigned int currentV = V.size() + 1; //store the index to the first submitted point | |
644 | + | |
645 | + //for each vertex | |
646 | + for(unsigned int vi = 0; vi < NV; vi++){ | |
647 | + vertex v(vertices[vi]); | |
648 | + V.push_back(v); | |
649 | + } | |
650 | + | |
651 | + //return the index to the first point | |
652 | + return currentV; | |
653 | + | |
654 | + } | |
655 | + | |
656 | + /// Add a line to the object | |
657 | + void addLine(std::vector<unsigned> v, std::vector<unsigned> vt = std::vector<unsigned>(), std::vector<unsigned> vn = std::vector<unsigned>()){ | |
658 | + | |
659 | + //create a new line geometry | |
660 | + geometry new_line; | |
661 | + | |
662 | + unsigned int v_i, vt_i, vn_i; | |
663 | + for(unsigned int i = 0; i < v.size(); i++){ | |
664 | + v_i = vt_i = vn_i = 0; | |
665 | + | |
666 | + v_i = v[i]; | |
667 | + if(vt.size() != 0) | |
668 | + vt_i = vt[i]; | |
669 | + if(vn.size() != 0) | |
670 | + vn_i = vn[i]; | |
671 | + | |
672 | + new_line.push_back(triplet(v_i, vt_i, vn_i)); | |
673 | + } | |
674 | + | |
675 | + //push the new geometry to the line list | |
676 | + L.push_back(new_line); | |
634 | 677 | |
635 | 678 | } |
636 | 679 | ... | ... |