From 3800c27f696781bd2349f1121cfa39d57bc56aff Mon Sep 17 00:00:00 2001 From: David Date: Thu, 28 Jan 2016 17:47:15 -0600 Subject: [PATCH] added code to subdivide networks --- stim/biomodels/fiber.h | 30 +++++++++++++++--------------- stim/biomodels/network.h | 66 +++++++++++++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 60 insertions(+), 36 deletions(-) diff --git a/stim/biomodels/fiber.h b/stim/biomodels/fiber.h index 0989803..731467b 100644 --- a/stim/biomodels/fiber.h +++ b/stim/biomodels/fiber.h @@ -5,7 +5,7 @@ #include namespace stim{ - + /** This class stores information about a single fiber represented as a set of geometric points * between two branch or end points. This class is used as a fundamental component of the stim::network * class to describe an interconnected (often biological) network. @@ -39,7 +39,7 @@ protected: for(unsigned int i = 0; i < N; i++) //allocate space for each point c[i] = (double*) malloc(sizeof(double) * 3); - + r = (T*) malloc(sizeof(T) * N); //allocate space for the radii } @@ -62,7 +62,7 @@ protected: gen_kdtree(); //generate the kd tree for the new fiber } - /// generate a KD tree for points on fiber + /// generate a KD tree for points on fiber void gen_kdtree() { int n_data = N; //create an array of data points @@ -123,7 +123,7 @@ public: copy(obj); } - + //temp constructor for graph visualization fiber(int n) { @@ -218,7 +218,7 @@ public: return l; //return the length } - + /// Calculates the length and average radius of the fiber /// @param length is filled with the fiber length @@ -267,7 +267,7 @@ public: T r_sum = 0.; for(unsigned int i = 0; i < N; i++) { - r_sum = r_sum + r[i]; + r_sum = r_sum + r[i]; } return r_sum/((T) N); } @@ -282,16 +282,16 @@ public: T radius(int idx){ return r[idx]; } - /// get index of a node on a fiber + /// get index of a node on a fiber // by matching the node on fiber to already set vertices (both strings) // used in obj file conversion - int - getIndexes(std::string* input, std::string searched, int sizeV) + int + getIndexes(std::string* input, std::string searched, int sizeV) { int result = 0; for (int i = 0; i < sizeV; i++) { - if (input[i] == searched) + if (input[i] == searched) { result = i + 1; } @@ -453,7 +453,7 @@ public: /// @param i is the index of the element to be returned as a stim::vec stim::vec operator[](unsigned i){ - return get_vec(i); + return get_vec(i); } /// Back method returns the last point in the fiber @@ -461,14 +461,14 @@ public: return get_vec(N-1); } ////resample a fiber in the network - stim::fiber Resample(T spacing=25.0) + stim::fiber resample(T spacing=25.0) { std::vector v(3); //v-direction vector of the segment stim::vec p(3); //- intermediate point to be added - std::vector p1(3); // p1 - starting point of an segment on the fiber, - std::vector p2(3); // p2 - ending point, + std::vector p1(3); // p1 - starting point of an segment on the fiber, + std::vector p2(3); // p2 - ending point, double sum=0; //distance summation std::vector > fiberPositions = centerline(); std::vector > newPointList; // initialize list of new resampled points on the fiber @@ -483,7 +483,7 @@ public: v[d] = p2[d] - p1[d]; //direction vector sum +=v[d] * v[d]; //length of segment-distance between starting and ending point } - newPointList.push_back(fiberPositions[f]); //always push the starting point + //newPointList.push_back(fiberPositions[f]); //always push the starting point T lengthSegment = sqrt(sum); //find Length of the segment as distance between the starting and ending points of the segment diff --git a/stim/biomodels/network.h b/stim/biomodels/network.h index ae3a8a7..ec68567 100644 --- a/stim/biomodels/network.h +++ b/stim/biomodels/network.h @@ -37,8 +37,20 @@ class network{ /// Constructor - creates an edge from a list of points by calling the stim::fiber constructor - ///@param p is a position in space + ///@param p is an array of positions in space edge(std::vector< stim::vec > p) : fiber(p){} + + /// Copy constructor creates an edge from a fiber + edge(stim::fiber f) : fiber(f) {} + + /// Resamples an edge by calling the fiber resampling function + edge resample(T spacing){ + edge e(fiber::resample()); //call the fiber->edge constructor + e.v[0] = v[0]; //copy the vertex data + e.v[1] = v[1]; + + return e; //return the new edge + } /// Output the edge information as a string std::string str(){ @@ -98,15 +110,16 @@ class network{ return V.size(); } + stim::fiber get_fiber(unsigned f){ + return E[f]; //return the specified edge (casting it to a fiber) + } + //load a network from an OBJ file void load_obj(std::string filename){ stim::obj O; //create an OBJ object O.load(filename); //load the OBJ file as an object - //prints each line in the obj file - vertex positions and fibers - std::cout< id2vert; //this list stores the OBJ vertex ID associated with each network vertex unsigned i[2]; //temporary, IDs associated with the first and last points in an OBJ line @@ -117,7 +130,7 @@ class network{ std::vector< stim::vec > c; //allocate an array of points for the vessel centerline O.getLine(l, c); //get the fiber centerline - edge e = c; //create an edge from the given centerline + edge new_edge = c; //create an edge from the given centerline //get the first and last vertex IDs for the line std::vector< unsigned > id; //create an array to store the centerline point IDs @@ -132,36 +145,32 @@ class network{ it = find(id2vert.begin(), id2vert.end(), i[0]); //look for the first node it_idx = std::distance(id2vert.begin(), it); if(it == id2vert.end()){ //if i[0] hasn't already been used - vertex v = e[0]; //create a new vertex, assign it a position - v.e[0].push_back(E.size()); //add the current edge as outgoing - e.v[0] = V.size(); //add the new vertex to the edge - V.push_back(v); //add the new vertex to the vertex list + vertex new_vertex = new_edge[0]; //create a new vertex, assign it a position + new_vertex.e[0].push_back(E.size()); //add the current edge as outgoing + new_edge.v[0] = V.size(); //add the new vertex to the edge + V.push_back(new_vertex); //add the new vertex to the vertex list id2vert.push_back(i[0]); //add the ID to the ID->vertex conversion list } else{ //if the vertex already exists V[it_idx].e[0].push_back(E.size()); //add the current edge as outgoing - e.v[0] = it_idx; + new_edge.v[0] = it_idx; } it = find(id2vert.begin(), id2vert.end(), i[1]); //look for the second ID it_idx = std::distance(id2vert.begin(), it); if(it == id2vert.end()){ //if i[1] hasn't already been used - vertex v = e.back(); //create a new vertex, assign it a position - v.e[1].push_back(E.size()); //add the current edge as incoming - e.v[1] = V.size(); - V.push_back(v); //add the new vertex to the vertex list + vertex new_vertex = new_edge.back(); //create a new vertex, assign it a position + new_vertex.e[1].push_back(E.size()); //add the current edge as incoming + new_edge.v[1] = V.size(); + V.push_back(new_vertex); //add the new vertex to the vertex list id2vert.push_back(i[1]); //add the ID to the ID->vertex conversion list } else{ //if the vertex already exists V[it_idx].e[1].push_back(E.size()); //add the current edge as incoming - e.v[1] = it_idx; + new_edge.v[1] = it_idx; } - stim::fiber f = e.Resample(25.0); - std::cout<<"resampled fiber length"< resample(T spacing){ + stim::network n; //create a new network that will be an exact copy, with resampled fibers + n.V = V; //copy all vertices + + n.E.resize(E.size()); //allocate space for the edge list + + //copy all fibers, resampling them in the process + for(unsigned e = 0; e < E.size(); e++){ //for each edge in the edge list + n.E[e] = E[e].resample(spacing); //resample the edge and copy it to the new network + } + + return n; //return the resampled network + } }; //end stim::network class }; //end stim namespace #endif -- libgit2 0.21.4