From cbce396ed49ae78cd4170a7242ff9601a3f3fd08 Mon Sep 17 00:00:00 2001 From: David Date: Tue, 4 Aug 2015 23:07:29 -0500 Subject: [PATCH] added support for threading and progress bars to ENVI streaming classes --- stim/biomodels/network.h | 32 +++++++++++++++++--------------- stim/envi/bil.h | 20 +++++++++++++++++++- stim/envi/binary.h | 12 +++++++++++- stim/envi/bip.h | 14 ++++++++++++++ stim/envi/bsq.h | 38 ++++++++++++++++++++++++++------------ stim/envi/envi.h | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- stim/ui/progressbar.h | 16 +++++++++------- stim/visualization/obj.h | 154 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 8 files changed, 315 insertions(+), 46 deletions(-) diff --git a/stim/biomodels/network.h b/stim/biomodels/network.h index 2411188..1e33e98 100644 --- a/stim/biomodels/network.h +++ b/stim/biomodels/network.h @@ -42,10 +42,15 @@ class network{ /// Stores information about a single capillary (a length of vessel between two branch or end points) //template - class fiber{ + class fiber : public std::list< point >{ + + using std::list< point >::begin; + using std::list< point >::end; + using std::list< point >::size; + public: - std::list< point > P; //geometric point positions + //std::list< point > P; //geometric point positions typename std::list< t_node >::iterator n[2]; //indices to terminal nodes unsigned int id; @@ -60,9 +65,9 @@ class network{ //for each point typename std::list< point >::iterator i; //create a point iterator - for(i = P.begin(); i != P.end(); i++){ //for each point in the fiber + for(i = begin(); i != end(); i++){ //for each point in the fiber - if(i == P.begin()) //if this is the first point, just store it + if(i == begin()) //if this is the first point, just store it p1 = *i; else{ //if this is any other point p0 = p1; //shift p1->p0 @@ -84,9 +89,9 @@ class network{ //for each point typename std::list< point >::iterator i; //create a point iterator - for(i = P.begin(); i != P.end(); i++){ //for each point in the fiber + for(i = begin(); i != end(); i++){ //for each point in the fiber - if(i == P.begin()){ //if this is the first point, just store it + if(i == begin()){ //if this is the first point, just store it p1 = *i; r1 = i->r; } @@ -116,13 +121,13 @@ class network{ std::vector< stim::vec > geometry(){ std::vector< stim::vec > result; //create an array to store the fiber geometry - result.resize( P.size() ); //pre-allocate the array + result.resize( size() ); //pre-allocate the array typename std::list< point >::iterator p; //create a list iterator unsigned int pi = 0; //create an index into the result array //for each geometric point on the fiber centerline - for(p = P.begin(); p != P.end(); p++){ + for(p = begin(); p != end(); p++){ result[pi] = *p; pi++; } @@ -136,7 +141,7 @@ class network{ //create an iterator for the point list typename std::list::iterator i; - for(i = P.begin(); i != P.end(); i++){ + for(i = begin(); i != end(); i++){ ss<str()<<" r = "<r<P.push_back(p); //push the point onto the current fiber + f->push_back(p); //push the point onto the current fiber } } @@ -338,9 +343,9 @@ public: //if the number of outgoing nodes is nonzero if(ni->out.size() != 0) - result[vi] = ni->out.front()->P.front(); + result[vi] = ni->out.front()->front(); else if(ni->in.size() != 0) - result[vi] = ni->in.front()->P.back(); + result[vi] = ni->in.front()->back(); vi++; //increment the array index } @@ -406,9 +411,6 @@ public: } return object; - - - } /// This function returns the information necessary for a simple graph-based physical (ex. fluid) simulation. diff --git a/stim/envi/bil.h b/stim/envi/bil.h index 465b187..52a4637 100644 --- a/stim/envi/bil.h +++ b/stim/envi/bil.h @@ -35,6 +35,8 @@ protected: return R[1]; } + using binary::thread_data; + public: using binary::open; @@ -318,12 +320,17 @@ public: }//loop for YZ line end target.write(reinterpret_cast(c), L); //write the corrected data into destination + + thread_data = (double)k / Y() * 100; }//loop for Y slice end free(a); free(b); free(c); target.close(); + + thread_data = 100; + return true; } @@ -366,11 +373,14 @@ public: } } target.write(reinterpret_cast(c), L); //write normalized data into destination + + thread_data = (double)j / Y() * 100; } free(b); free(c); target.close(); + thread_data = 100; return true; } @@ -390,9 +400,13 @@ public: for ( unsigned i = 0; i < Z(); i++) { band_index(p, i); - target.write(reinterpret_cast(p), S); //write a band data into target file + target.write(reinterpret_cast(p), S); //write a band data into target file + + thread_data = (double)i / Z() * 100; //store the progress for the current operation } + thread_data = 100; //set the current progress to 100% + free(p); target.close(); return true; @@ -421,11 +435,15 @@ public: unsigned ks = k * X(); for ( unsigned j = 0; j < X(); j++) q[k + j * Z()] = p[ks + j]; + + thread_data = (double)(i * Z() + k) / (Z() * Y()) * 100; //store the progress for the current operation } target.write(reinterpret_cast(q), S); //write a band data into target file } + thread_data = 100; + free(p); free(q); diff --git a/stim/envi/binary.h b/stim/envi/binary.h index 16ff0b9..7c431a0 100644 --- a/stim/envi/binary.h +++ b/stim/envi/binary.h @@ -28,7 +28,7 @@ protected: unsigned int header; //header size (in bytes) unsigned char* mask; //pointer to a character array: 0 = background, 1 = foreground (or valid data) - + unsigned int thread_data; //unsigned integer used to pass data to threads during processing /// Private initialization function used to set default parameters in the data structure. @@ -36,6 +36,8 @@ protected: memset(R, 0, sizeof(unsigned int) * D); //initialize the resolution to zero header = 0; //initialize the header size to zero mask = NULL; + + thread_data = 0; } /// Private helper function that returns the size of the file on disk using system functions. @@ -95,6 +97,14 @@ protected: public: + unsigned int get_thread_data(){ + return thread_data; + } + + void reset_thread_data(){ + thread_data = 0; + } + /// Open a binary file for streaming. /// @param filename is the name of the binary file diff --git a/stim/envi/bip.h b/stim/envi/bip.h index 96e6305..6273e4d 100644 --- a/stim/envi/bip.h +++ b/stim/envi/bip.h @@ -37,6 +37,8 @@ protected: return R[0]; } + using binary::thread_data; + public: using binary::open; @@ -327,6 +329,8 @@ public: }//loop for YZ line end target.write(reinterpret_cast(c), L); //write the corrected data into destination + + thread_data = (double)k / Y() * 100; }//loop for Y slice end @@ -335,6 +339,8 @@ public: free(b); free(c); target.close(); + + thread_data = 100; return true; } @@ -379,12 +385,15 @@ public: } } target.write(reinterpret_cast(c), L); //write normalized data into destination + + thread_data = (double) j / Y() * 100; } free(b); free(c); target.close(); + thread_data = 100; return true; } @@ -434,10 +443,13 @@ public: unsigned ks = k * X(); for ( unsigned j = 0; j < X(); j++) q[ks + j] = p[k + j * Z()]; + + thread_data = (double)(i * Z() + k) / (Y() * Z()) * 100; } target.write(reinterpret_cast(q), S); //write a band data into target file } + thread_data = 100; free(p); free(q); @@ -882,6 +894,8 @@ public: //close the output file target.close(); free(spectrum); + + return true; } bool unsift(std::string outfile, unsigned char* mask, unsigned int samples, unsigned int lines){ diff --git a/stim/envi/bsq.h b/stim/envi/bsq.h index 0f3977c..d3f1f9c 100644 --- a/stim/envi/bsq.h +++ b/stim/envi/bsq.h @@ -42,6 +42,8 @@ protected: return R[2]; } + using binary::thread_data; + public: using binary::open; @@ -259,6 +261,8 @@ public: } target.write(reinterpret_cast(c), S); //write the corrected data into destination + + thread_data = (double)cii / B * 100; } @@ -268,6 +272,8 @@ public: free(b); free(c); target.close(); + + thread_data = 100; return true; } @@ -304,13 +310,18 @@ public: c[i] = c[i] / b[i]; } target.write(reinterpret_cast(c), S); //write normalized data into destination + + thread_data = (double)j / B * 100; } + + //header.save(headername); //save the new header file free(b); free(c); target.close(); + thread_data = 100; //make sure that the progress bar is full return true; } @@ -349,23 +360,26 @@ public: std::ofstream target(outname.c_str(), std::ios::binary); std::string headername = outname + ".hdr"; - T * p; //pointer to the current spectrum - p = (T*)malloc(L); - - for ( unsigned i = 0; i < Y(); i++) + unsigned int xz_bytes = X() * Z() * sizeof(T); + T * xz_slice; //pointer to the current spectrum + xz_slice = (T*)malloc(xz_bytes); + + for ( unsigned y = 0; y < Y(); y++) //for each y position { - file.seekg(X() * i * sizeof(T), std::ios::beg); - for ( unsigned j = 0; j < Z(); j++ ) + file.seekg(y * X() * sizeof(T), std::ios::beg); //seek to the beginning of the xz slice + for ( unsigned z = 0; z < Z(); z++ ) //for each band { - file.read((char *)(p + j * X()), sizeof(T) * X()); - file.seekg(jump, std::ios::cur); //go to the next band + file.read((char *)(xz_slice + z * X()), sizeof(T) * X()); //read a line + file.seekg(jump, std::ios::cur); //seek to the next band + + thread_data = (double)(y * Z() + z) / (Z() * Y()) * 100; //update the progress counter } - target.write(reinterpret_cast(p), L); //write XZ slice data into target file + target.write(reinterpret_cast(xz_slice), xz_bytes); //write the generated XZ slice to the target file } - //header.interleave = rts::envi_header::BIL; //change the type of file in header file - //header.save(headername); - free(p); + thread_data = 100; + + free(xz_slice); target.close(); return true; } diff --git a/stim/envi/envi.h b/stim/envi/envi.h index 591605d..5c7bcef 100644 --- a/stim/envi/envi.h +++ b/stim/envi/envi.h @@ -23,6 +23,78 @@ public: envi_header header; + /// Returns the progress of the current processing operation as a percentage + void reset_progress(){ + + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file + if(header.data_type ==envi_header::float32) + ((bsq*)file)->reset_thread_data(); + else if(header.data_type == envi_header::float64) + ((bsq*)file)->reset_thread_data(); + else + std::cout<<"ERROR: unidentified data type"<*)file)->reset_thread_data(); + else if(header.data_type == envi_header::float64) + ((bil*)file)->reset_thread_data(); + else + std::cout<<"ERROR: unidentified data type"<*)file)->reset_thread_data(); + else if(header.data_type == envi_header::float64) + ((bip*)file)->reset_thread_data(); + else + std::cout<<"ERROR: unidentified data type"<*)file)->get_thread_data(); + else if(header.data_type == envi_header::float64) + return ((bsq*)file)->get_thread_data(); + else + std::cout<<"ERROR: unidentified data type"<*)file)->get_thread_data(); + else if(header.data_type == envi_header::float64) + return ((bil*)file)->get_thread_data(); + else + std::cout<<"ERROR: unidentified data type"<*)file)->get_thread_data(); + else if(header.data_type == envi_header::float64) + return ((bip*)file)->get_thread_data(); + else + std::cout<<"ERROR: unidentified data type"< #include using namespace std; -static void rtsProgressBar(int percent) +static void rtsProgressBar(unsigned int percent) { + //std::cout<& v){ + v.resize(size()); //resize the vector to match the number of vertices + for(unsigned int i = 0; i& vt){ + vt.resize(size()); //resize the vector to match the number of vertices + for(unsigned int i = 0; i& vn){ + vn.resize(size()); //resize the vector to match the number of vertices + for(unsigned int i = 0; i get_l_v(unsigned l){ + + + + } + public: /// Constructor loads a Wavefront OBJ file obj(std::string filename){ @@ -511,12 +537,70 @@ public: } /// Retrieve the vertex stored in index i + /// @param vi is the desired vertex index + stim::vec getV(unsigned int vi){ + stim::vec v = V[vi]; + return v; + } - /// @param i is the desired vertex index - stim::vec getV(unsigned int i){ + /// Retrieve the vertex texture coordinate at index i + /// @param vti is the desired index + stim::vec getVT(unsigned int vti){ + stim::vec vt = VT[vti]; + return vt; + } - stim::vec v = V[i]; - return v; + /// Retrieve the vertex normal at index i + /// @param vni is the desired index + stim::vec getVN(unsigned int vni){ + stim::vec vn = VN[vni]; + return vn; + } + + + /// Retrieve a vertex stored at a list of given indices + /// @param vi is an array containing a series of indices + std::vector< stim::vec > getV( std::vector vi ){ + + std::vector< stim::vec > v; + v.resize(vi.size()); //pre-allocate an array of vertices + + std::cout<<"stim::obj::getV: "< > getVT( std::vector vti ){ + + std::vector< stim::vec > vt; + vt.resize(vti.size()); //pre-allocate an array of vertices + + std::cout<<"stim::obj::getV: "< > getVN( std::vector vni ){ + + std::vector< stim::vec > vn; + vn.resize(vni.size()); //pre-allocate an array of vertices + + std::cout<<"stim::obj::getV: "< centroid(){ @@ -585,7 +669,7 @@ public: /// Returns the vertex indices for the specified line /// @param i is the index of the line - std::vector< unsigned int > getL_Vi(unsigned int i){ + /*std::vector< unsigned int > getL_Vi(unsigned int i){ unsigned int nP = L[i].size(); @@ -602,12 +686,12 @@ public: } return l; - } + }*/ /// Returns a vector containing the list of texture coordinates associated with each point of a line. /// @param i is the index of the desired line - std::vector< stim::vec > getL_VT(unsigned int i){ + /*std::vector< stim::vec > getL_VT(unsigned int i){ //get the number of points in the specified line unsigned int nP = L[i].size(); @@ -633,7 +717,7 @@ public: } return l; - } + }*/ /// Add an array of vertices to the vertex list unsigned int addV(std::vector< stim::vec > vertices){ @@ -674,9 +758,63 @@ public: //push the new geometry to the line list L.push_back(new_line); + } + + /// Fills three std::vector structures with the indices representing a line + /// @param l is the line index + /// @param vi is a vertex index array that will be filled + void getLinei(unsigned l, std::vector& vi){ + L[l-1].get_v(vi); + } + /// Fills three std::vector structures with the indices representing a line + /// @param l is the line index + /// @param vi is a vertex index array that will be filled + /// @param vti is a vertex texture coordinate index array that will be filled + void getLinei(unsigned l, std::vector& vi, std::vector& vti){ + getLinei(l, vi); + L[l-1].get_vt(vti); } + /// Fills three std::vector structures with the indices representing a line + /// @param l is the line index + /// @param vi is a vertex index array that will be filled + /// @param vti is a vertex texture coordinate index array that will be filled + /// @param vni is a vertex normal index array that will be filled + void getLinei(unsigned l, std::vector& vi, std::vector& vti, std::vector& vni){ + getLinei(l, vi, vti); + L[l-1].get_vn(vni); + } + + /// Returns a list of points corresponding to the vertices of a line + void getLine(unsigned l, std::vector< stim::vec > v){ + + std::vector vi; //create a vector to store indices to vertices + getLinei(l, vi); //get the indices for the line vertices + v = getV(vi); //get the vertices corresponding to the indices + } + + void getLine(unsigned l, std::vector< stim::vec > v, std::vector< stim::vec > vt){ + + std::vector vi, vti; + getLinei(l, vi, vti); //get the indices for the line vertices + v = getV(vi); //get the vertices corresponding to the indices + vt = getVT(vti); + } + + void getLine(unsigned l, std::vector< stim::vec > v, + std::vector< stim::vec > vt, + std::vector< stim::vec > vn){ + + std::vector vi, vti, vni; + getLinei(l, vi, vti, vni); //get the indices for the line vertices + v = getV(vi); //get the vertices corresponding to the indices + vt = getVT(vti); + vn = getVN(vni); + + } + + }; -- libgit2 0.21.4