Commit e376212f1c48b3bd6dabebe11f7f0f76b4fac008

Authored by David Mayerich
1 parent fa737592

added support for exporting stim::network to stim::obj

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&lt;T&gt;
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&lt;T&gt;
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&lt;T&gt;
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&lt;T&gt;
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  
... ...