Commit cbce396ed49ae78cd4170a7242ff9601a3f3fd08

Authored by David Mayerich
1 parent e376212f

added support for threading and progress bars to ENVI streaming classes

stim/biomodels/network.h
... ... @@ -42,10 +42,15 @@ class network{
42 42  
43 43 /// Stores information about a single capillary (a length of vessel between two branch or end points)
44 44 //template<typename T>
45   - class fiber{
  45 + class fiber : public std::list< point >{
  46 +
  47 + using std::list< point >::begin;
  48 + using std::list< point >::end;
  49 + using std::list< point >::size;
  50 +
46 51  
47 52 public:
48   - std::list< point > P; //geometric point positions
  53 + //std::list< point > P; //geometric point positions
49 54  
50 55 typename std::list< t_node >::iterator n[2]; //indices to terminal nodes
51 56 unsigned int id;
... ... @@ -60,9 +65,9 @@ class network{
60 65  
61 66 //for each point
62 67 typename std::list< point >::iterator i; //create a point iterator
63   - for(i = P.begin(); i != P.end(); i++){ //for each point in the fiber
  68 + for(i = begin(); i != end(); i++){ //for each point in the fiber
64 69  
65   - if(i == P.begin()) //if this is the first point, just store it
  70 + if(i == begin()) //if this is the first point, just store it
66 71 p1 = *i;
67 72 else{ //if this is any other point
68 73 p0 = p1; //shift p1->p0
... ... @@ -84,9 +89,9 @@ class network{
84 89  
85 90 //for each point
86 91 typename std::list< point >::iterator i; //create a point iterator
87   - for(i = P.begin(); i != P.end(); i++){ //for each point in the fiber
  92 + for(i = begin(); i != end(); i++){ //for each point in the fiber
88 93  
89   - if(i == P.begin()){ //if this is the first point, just store it
  94 + if(i == begin()){ //if this is the first point, just store it
90 95 p1 = *i;
91 96 r1 = i->r;
92 97 }
... ... @@ -116,13 +121,13 @@ class network{
116 121 std::vector< stim::vec<T> > geometry(){
117 122  
118 123 std::vector< stim::vec<T> > result; //create an array to store the fiber geometry
119   - result.resize( P.size() ); //pre-allocate the array
  124 + result.resize( size() ); //pre-allocate the array
120 125  
121 126 typename std::list< point >::iterator p; //create a list iterator
122 127 unsigned int pi = 0; //create an index into the result array
123 128  
124 129 //for each geometric point on the fiber centerline
125   - for(p = P.begin(); p != P.end(); p++){
  130 + for(p = begin(); p != end(); p++){
126 131 result[pi] = *p;
127 132 pi++;
128 133 }
... ... @@ -136,7 +141,7 @@ class network{
136 141  
137 142 //create an iterator for the point list
138 143 typename std::list<point>::iterator i;
139   - for(i = P.begin(); i != P.end(); i++){
  144 + for(i = begin(); i != end(); i++){
140 145 ss<<i->str()<<" r = "<<i->r<<std::endl;
141 146 }
142 147  
... ... @@ -316,7 +321,7 @@ public:
316 321 for(unsigned int pi = 0; pi < nP; pi++){
317 322 point p = (point)L[pi]; //move the geometric coordinates into a point structure
318 323 p.r = R[pi][0]; //store the radius
319   - f->P.push_back(p); //push the point onto the current fiber
  324 + f->push_back(p); //push the point onto the current fiber
320 325 }
321 326 }
322 327  
... ... @@ -338,9 +343,9 @@ public:
338 343  
339 344 //if the number of outgoing nodes is nonzero
340 345 if(ni->out.size() != 0)
341   - result[vi] = ni->out.front()->P.front();
  346 + result[vi] = ni->out.front()->front();
342 347 else if(ni->in.size() != 0)
343   - result[vi] = ni->in.front()->P.back();
  348 + result[vi] = ni->in.front()->back();
344 349  
345 350 vi++; //increment the array index
346 351 }
... ... @@ -406,9 +411,6 @@ public:
406 411 }
407 412  
408 413 return object;
409   -
410   -
411   -
412 414 }
413 415  
414 416 /// This function returns the information necessary for a simple graph-based physical (ex. fluid) simulation.
... ...
stim/envi/bil.h
... ... @@ -35,6 +35,8 @@ protected:
35 35 return R[1];
36 36 }
37 37  
  38 + using binary<T>::thread_data;
  39 +
38 40 public:
39 41  
40 42 using binary<T>::open;
... ... @@ -318,12 +320,17 @@ public:
318 320  
319 321 }//loop for YZ line end
320 322 target.write(reinterpret_cast<const char*>(c), L); //write the corrected data into destination
  323 +
  324 + thread_data = (double)k / Y() * 100;
321 325 }//loop for Y slice end
322 326  
323 327 free(a);
324 328 free(b);
325 329 free(c);
326 330 target.close();
  331 +
  332 + thread_data = 100;
  333 +
327 334 return true;
328 335  
329 336 }
... ... @@ -366,11 +373,14 @@ public:
366 373 }
367 374 }
368 375 target.write(reinterpret_cast<const char*>(c), L); //write normalized data into destination
  376 +
  377 + thread_data = (double)j / Y() * 100;
369 378 }
370 379  
371 380 free(b);
372 381 free(c);
373 382 target.close();
  383 + thread_data = 100;
374 384 return true;
375 385 }
376 386  
... ... @@ -390,9 +400,13 @@ public:
390 400 for ( unsigned i = 0; i < Z(); i++)
391 401 {
392 402 band_index(p, i);
393   - target.write(reinterpret_cast<const char*>(p), S); //write a band data into target file
  403 + target.write(reinterpret_cast<const char*>(p), S); //write a band data into target file
  404 +
  405 + thread_data = (double)i / Z() * 100; //store the progress for the current operation
394 406 }
395 407  
  408 + thread_data = 100; //set the current progress to 100%
  409 +
396 410 free(p);
397 411 target.close();
398 412 return true;
... ... @@ -421,11 +435,15 @@ public:
421 435 unsigned ks = k * X();
422 436 for ( unsigned j = 0; j < X(); j++)
423 437 q[k + j * Z()] = p[ks + j];
  438 +
  439 + thread_data = (double)(i * Z() + k) / (Z() * Y()) * 100; //store the progress for the current operation
424 440 }
425 441  
426 442 target.write(reinterpret_cast<const char*>(q), S); //write a band data into target file
427 443 }
428 444  
  445 + thread_data = 100;
  446 +
429 447  
430 448 free(p);
431 449 free(q);
... ...
stim/envi/binary.h
... ... @@ -28,7 +28,7 @@ protected:
28 28 unsigned int header; //header size (in bytes)
29 29 unsigned char* mask; //pointer to a character array: 0 = background, 1 = foreground (or valid data)
30 30  
31   -
  31 + unsigned int thread_data; //unsigned integer used to pass data to threads during processing
32 32  
33 33  
34 34 /// Private initialization function used to set default parameters in the data structure.
... ... @@ -36,6 +36,8 @@ protected:
36 36 memset(R, 0, sizeof(unsigned int) * D); //initialize the resolution to zero
37 37 header = 0; //initialize the header size to zero
38 38 mask = NULL;
  39 +
  40 + thread_data = 0;
39 41 }
40 42  
41 43 /// Private helper function that returns the size of the file on disk using system functions.
... ... @@ -95,6 +97,14 @@ protected:
95 97  
96 98 public:
97 99  
  100 + unsigned int get_thread_data(){
  101 + return thread_data;
  102 + }
  103 +
  104 + void reset_thread_data(){
  105 + thread_data = 0;
  106 + }
  107 +
98 108 /// Open a binary file for streaming.
99 109  
100 110 /// @param filename is the name of the binary file
... ...
stim/envi/bip.h
... ... @@ -37,6 +37,8 @@ protected:
37 37 return R[0];
38 38 }
39 39  
  40 + using binary<T>::thread_data;
  41 +
40 42 public:
41 43  
42 44 using binary<T>::open;
... ... @@ -327,6 +329,8 @@ public:
327 329  
328 330 }//loop for YZ line end
329 331 target.write(reinterpret_cast<const char*>(c), L); //write the corrected data into destination
  332 +
  333 + thread_data = (double)k / Y() * 100;
330 334 }//loop for Y slice end
331 335  
332 336  
... ... @@ -335,6 +339,8 @@ public:
335 339 free(b);
336 340 free(c);
337 341 target.close();
  342 +
  343 + thread_data = 100;
338 344 return true;
339 345  
340 346 }
... ... @@ -379,12 +385,15 @@ public:
379 385 }
380 386 }
381 387 target.write(reinterpret_cast<const char*>(c), L); //write normalized data into destination
  388 +
  389 + thread_data = (double) j / Y() * 100;
382 390 }
383 391  
384 392  
385 393 free(b);
386 394 free(c);
387 395 target.close();
  396 + thread_data = 100;
388 397 return true;
389 398 }
390 399  
... ... @@ -434,10 +443,13 @@ public:
434 443 unsigned ks = k * X();
435 444 for ( unsigned j = 0; j < X(); j++)
436 445 q[ks + j] = p[k + j * Z()];
  446 +
  447 + thread_data = (double)(i * Z() + k) / (Y() * Z()) * 100;
437 448 }
438 449 target.write(reinterpret_cast<const char*>(q), S); //write a band data into target file
439 450 }
440 451  
  452 + thread_data = 100;
441 453  
442 454 free(p);
443 455 free(q);
... ... @@ -882,6 +894,8 @@ public:
882 894 //close the output file
883 895 target.close();
884 896 free(spectrum);
  897 +
  898 + return true;
885 899 }
886 900  
887 901 bool unsift(std::string outfile, unsigned char* mask, unsigned int samples, unsigned int lines){
... ...
stim/envi/bsq.h
... ... @@ -42,6 +42,8 @@ protected:
42 42 return R[2];
43 43 }
44 44  
  45 + using binary<T>::thread_data;
  46 +
45 47 public:
46 48  
47 49 using binary<T>::open;
... ... @@ -259,6 +261,8 @@ public:
259 261 }
260 262  
261 263 target.write(reinterpret_cast<const char*>(c), S); //write the corrected data into destination
  264 +
  265 + thread_data = (double)cii / B * 100;
262 266  
263 267 }
264 268  
... ... @@ -268,6 +272,8 @@ public:
268 272 free(b);
269 273 free(c);
270 274 target.close();
  275 +
  276 + thread_data = 100;
271 277 return true;
272 278 }
273 279  
... ... @@ -304,13 +310,18 @@ public:
304 310 c[i] = c[i] / b[i];
305 311 }
306 312 target.write(reinterpret_cast<const char*>(c), S); //write normalized data into destination
  313 +
  314 + thread_data = (double)j / B * 100;
307 315 }
308 316  
  317 +
  318 +
309 319 //header.save(headername); //save the new header file
310 320  
311 321 free(b);
312 322 free(c);
313 323 target.close();
  324 + thread_data = 100; //make sure that the progress bar is full
314 325 return true;
315 326 }
316 327  
... ... @@ -349,23 +360,26 @@ public:
349 360 std::ofstream target(outname.c_str(), std::ios::binary);
350 361 std::string headername = outname + ".hdr";
351 362  
352   - T * p; //pointer to the current spectrum
353   - p = (T*)malloc(L);
354   -
355   - for ( unsigned i = 0; i < Y(); i++)
  363 + unsigned int xz_bytes = X() * Z() * sizeof(T);
  364 + T * xz_slice; //pointer to the current spectrum
  365 + xz_slice = (T*)malloc(xz_bytes);
  366 +
  367 + for ( unsigned y = 0; y < Y(); y++) //for each y position
356 368 {
357   - file.seekg(X() * i * sizeof(T), std::ios::beg);
358   - for ( unsigned j = 0; j < Z(); j++ )
  369 + file.seekg(y * X() * sizeof(T), std::ios::beg); //seek to the beginning of the xz slice
  370 + for ( unsigned z = 0; z < Z(); z++ ) //for each band
359 371 {
360   - file.read((char *)(p + j * X()), sizeof(T) * X());
361   - file.seekg(jump, std::ios::cur); //go to the next band
  372 + file.read((char *)(xz_slice + z * X()), sizeof(T) * X()); //read a line
  373 + file.seekg(jump, std::ios::cur); //seek to the next band
  374 +
  375 + thread_data = (double)(y * Z() + z) / (Z() * Y()) * 100; //update the progress counter
362 376 }
363   - target.write(reinterpret_cast<const char*>(p), L); //write XZ slice data into target file
  377 + target.write(reinterpret_cast<const char*>(xz_slice), xz_bytes); //write the generated XZ slice to the target file
364 378 }
365   - //header.interleave = rts::envi_header::BIL; //change the type of file in header file
366   - //header.save(headername);
367 379  
368   - free(p);
  380 + thread_data = 100;
  381 +
  382 + free(xz_slice);
369 383 target.close();
370 384 return true;
371 385 }
... ...
stim/envi/envi.h
... ... @@ -23,6 +23,78 @@ public:
23 23  
24 24 envi_header header;
25 25  
  26 + /// Returns the progress of the current processing operation as a percentage
  27 + void reset_progress(){
  28 +
  29 + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file
  30 + if(header.data_type ==envi_header::float32)
  31 + ((bsq<float>*)file)->reset_thread_data();
  32 + else if(header.data_type == envi_header::float64)
  33 + ((bsq<double>*)file)->reset_thread_data();
  34 + else
  35 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  36 + }
  37 +
  38 + else if(header.interleave == envi_header::BIL){ //if the infile is bil file
  39 + if(header.data_type ==envi_header::float32)
  40 + ((bil<float>*)file)->reset_thread_data();
  41 + else if(header.data_type == envi_header::float64)
  42 + ((bil<double>*)file)->reset_thread_data();
  43 + else
  44 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  45 + }
  46 +
  47 + else if(header.interleave == envi_header::BIP){ //if the infile is bip file
  48 + if(header.data_type ==envi_header::float32)
  49 + ((bip<float>*)file)->reset_thread_data();
  50 + else if(header.data_type == envi_header::float64)
  51 + ((bip<double>*)file)->reset_thread_data();
  52 + else
  53 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  54 + }
  55 +
  56 + else{
  57 + std::cout<<"ERROR: unidentified file type"<<std::endl;
  58 + exit(1);
  59 + }
  60 + }
  61 +
  62 + /// Returns the progress of the current processing operation as a percentage
  63 + unsigned int progress(){
  64 +
  65 + if(header.interleave == envi_header::BSQ){ //if the infile is bsq file
  66 + if(header.data_type ==envi_header::float32)
  67 + return ((bsq<float>*)file)->get_thread_data();
  68 + else if(header.data_type == envi_header::float64)
  69 + return ((bsq<double>*)file)->get_thread_data();
  70 + else
  71 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  72 + }
  73 +
  74 + else if(header.interleave == envi_header::BIL){ //if the infile is bil file
  75 + if(header.data_type ==envi_header::float32)
  76 + return ((bil<float>*)file)->get_thread_data();
  77 + else if(header.data_type == envi_header::float64)
  78 + return ((bil<double>*)file)->get_thread_data();
  79 + else
  80 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  81 + }
  82 +
  83 + else if(header.interleave == envi_header::BIP){ //if the infile is bip file
  84 + if(header.data_type ==envi_header::float32)
  85 + return ((bip<float>*)file)->get_thread_data();
  86 + else if(header.data_type == envi_header::float64)
  87 + return ((bip<double>*)file)->get_thread_data();
  88 + else
  89 + std::cout<<"ERROR: unidentified data type"<<std::endl;
  90 + }
  91 +
  92 + else{
  93 + std::cout<<"ERROR: unidentified file type"<<std::endl;
  94 + }
  95 + return 0;
  96 + }
  97 +
26 98 /// Allocate memory for a new ENVI file based on the current interleave format (BIP, BIL, BSQ) and data type.
27 99 bool allocate(){
28 100  
... ... @@ -469,9 +541,8 @@ public:
469 541  
470 542 else{
471 543 std::cout << "ERROR: unidentified file type" << std::endl;
472   - exit(1);
473 544 }
474   -
  545 + return 0;
475 546 }
476 547  
477 548 /// Compute the ratio of two baseline-corrected peaks. The result is stored in a pre-allocated array.
... ...
stim/ui/progressbar.h
1   -#ifndef RTS_PROGRESSBAR_H
2   -#define RTS_PROGRESSBAR_H
3   -
  1 +#ifndef RTS_PROGRESSBAR_H
  2 +#define RTS_PROGRESSBAR_H
  3 +
4 4 #include <iostream>
5 5 #include <sstream>
6 6 using namespace std;
7 7  
8   -static void rtsProgressBar(int percent)
  8 +static void rtsProgressBar(unsigned int percent)
9 9 {
  10 + //std::cout<<percent<<std::endl;
10 11 stringstream bar;
11 12 static int x = 0;
12 13 string slash[4];
... ... @@ -25,9 +26,10 @@ static void rtsProgressBar(int percent)
25 26 bar<<"]";
26 27 cout << "\r"; // carriage return back to beginning of line
27 28 cout << bar.str() << " " << slash[x] << " " << percent << " %"; // print the bars and percentage
  29 + cout.flush();
28 30 x++; // increment to make the slash appear to rotate
29 31 if(x == 4)
30 32 x = 0; // reset slash animation
31   -}
32   -
33   -#endif
  33 +}
  34 +
  35 +#endif
... ...
stim/visualization/obj.h
... ... @@ -169,6 +169,25 @@ protected:
169 169  
170 170 }
171 171  
  172 + //returns a vector containing the vertex indices for the geometry
  173 + void get_v(std::vector<unsigned>& v){
  174 + v.resize(size()); //resize the vector to match the number of vertices
  175 + for(unsigned int i = 0; i<size(); i++) //for each vertex
  176 + v[i] = at(i)[0]; //copy the vertex index
  177 + }
  178 +
  179 + void get_vt(std::vector<unsigned>& vt){
  180 + vt.resize(size()); //resize the vector to match the number of vertices
  181 + for(unsigned int i = 0; i<size(); i++) //for each vertex
  182 + vt[i] = at(i)[1]; //copy the vertex index
  183 + }
  184 +
  185 + void get_vn(std::vector<unsigned>& vn){
  186 + vn.resize(size()); //resize the vector to match the number of vertices
  187 + for(unsigned int i = 0; i<size(); i++) //for each vertex
  188 + vn[i] = at(i)[2]; //copy the vertex index
  189 + }
  190 +
172 191 std::string str(){
173 192  
174 193 std::stringstream ss;
... ... @@ -293,6 +312,13 @@ protected:
293 312 return OBJ_INVALID;
294 313 }
295 314  
  315 + //private method returns the vertex indices for a line
  316 + std::vector<unsigned> get_l_v(unsigned l){
  317 +
  318 +
  319 +
  320 + }
  321 +
296 322 public:
297 323 /// Constructor loads a Wavefront OBJ file
298 324 obj(std::string filename){
... ... @@ -511,12 +537,70 @@ public:
511 537 }
512 538  
513 539 /// Retrieve the vertex stored in index i
  540 + /// @param vi is the desired vertex index
  541 + stim::vec<T> getV(unsigned int vi){
  542 + stim::vec<T> v = V[vi];
  543 + return v;
  544 + }
514 545  
515   - /// @param i is the desired vertex index
516   - stim::vec<T> getV(unsigned int i){
  546 + /// Retrieve the vertex texture coordinate at index i
  547 + /// @param vti is the desired index
  548 + stim::vec<T> getVT(unsigned int vti){
  549 + stim::vec<T> vt = VT[vti];
  550 + return vt;
  551 + }
517 552  
518   - stim::vec<T> v = V[i];
519   - return v;
  553 + /// Retrieve the vertex normal at index i
  554 + /// @param vni is the desired index
  555 + stim::vec<T> getVN(unsigned int vni){
  556 + stim::vec<T> vn = VN[vni];
  557 + return vn;
  558 + }
  559 +
  560 +
  561 + /// Retrieve a vertex stored at a list of given indices
  562 + /// @param vi is an array containing a series of indices
  563 + std::vector< stim::vec<T> > getV( std::vector<unsigned> vi ){
  564 +
  565 + std::vector< stim::vec<T> > v;
  566 + v.resize(vi.size()); //pre-allocate an array of vertices
  567 +
  568 + std::cout<<"stim::obj::getV: "<<v.size()<<std::endl;
  569 +
  570 + for(unsigned i = 0; i < vi.size(); i++)
  571 + v[i] = V[vi[i] - 1];
  572 +
  573 + return v; //return the array of vertices
  574 + }
  575 +
  576 + /// Retrieve a vertex stored at a list of given indices
  577 + /// @param vi is an array containing a series of indices
  578 + std::vector< stim::vec<T> > getVT( std::vector<unsigned> vti ){
  579 +
  580 + std::vector< stim::vec<T> > vt;
  581 + vt.resize(vti.size()); //pre-allocate an array of vertices
  582 +
  583 + std::cout<<"stim::obj::getV: "<<vt.size()<<std::endl;
  584 +
  585 + for(unsigned i = 0; i < vti.size(); i++)
  586 + vt[i] = VT[vti[i] - 1];
  587 +
  588 + return vt; //return the array of vertices
  589 + }
  590 +
  591 + /// Retrieve a vertex stored at a list of given indices
  592 + /// @param vi is an array containing a series of indices
  593 + std::vector< stim::vec<T> > getVN( std::vector<unsigned> vni ){
  594 +
  595 + std::vector< stim::vec<T> > vn;
  596 + vn.resize(vni.size()); //pre-allocate an array of vertices
  597 +
  598 + std::cout<<"stim::obj::getV: "<<vn.size()<<std::endl;
  599 +
  600 + for(unsigned i = 0; i < vni.size(); i++)
  601 + vn[i] = VN[vni[i] - 1];
  602 +
  603 + return vn; //return the array of vertices
520 604 }
521 605  
522 606 stim::vec<T> centroid(){
... ... @@ -585,7 +669,7 @@ public:
585 669  
586 670 /// Returns the vertex indices for the specified line
587 671 /// @param i is the index of the line
588   - std::vector< unsigned int > getL_Vi(unsigned int i){
  672 + /*std::vector< unsigned int > getL_Vi(unsigned int i){
589 673  
590 674 unsigned int nP = L[i].size();
591 675  
... ... @@ -602,12 +686,12 @@ public:
602 686 }
603 687  
604 688 return l;
605   - }
  689 + }*/
606 690  
607 691 /// Returns a vector containing the list of texture coordinates associated with each point of a line.
608 692  
609 693 /// @param i is the index of the desired line
610   - std::vector< stim::vec<T> > getL_VT(unsigned int i){
  694 + /*std::vector< stim::vec<T> > getL_VT(unsigned int i){
611 695  
612 696 //get the number of points in the specified line
613 697 unsigned int nP = L[i].size();
... ... @@ -633,7 +717,7 @@ public:
633 717 }
634 718  
635 719 return l;
636   - }
  720 + }*/
637 721  
638 722 /// Add an array of vertices to the vertex list
639 723 unsigned int addV(std::vector< stim::vec<T> > vertices){
... ... @@ -674,9 +758,63 @@ public:
674 758  
675 759 //push the new geometry to the line list
676 760 L.push_back(new_line);
  761 + }
  762 +
  763 + /// Fills three std::vector structures with the indices representing a line
  764 + /// @param l is the line index
  765 + /// @param vi is a vertex index array that will be filled
  766 + void getLinei(unsigned l, std::vector<unsigned>& vi){
  767 + L[l-1].get_v(vi);
  768 + }
677 769  
  770 + /// Fills three std::vector structures with the indices representing a line
  771 + /// @param l is the line index
  772 + /// @param vi is a vertex index array that will be filled
  773 + /// @param vti is a vertex texture coordinate index array that will be filled
  774 + void getLinei(unsigned l, std::vector<unsigned>& vi, std::vector<unsigned>& vti){
  775 + getLinei(l, vi);
  776 + L[l-1].get_vt(vti);
678 777 }
679 778  
  779 + /// Fills three std::vector structures with the indices representing a line
  780 + /// @param l is the line index
  781 + /// @param vi is a vertex index array that will be filled
  782 + /// @param vti is a vertex texture coordinate index array that will be filled
  783 + /// @param vni is a vertex normal index array that will be filled
  784 + void getLinei(unsigned l, std::vector<unsigned>& vi, std::vector<unsigned>& vti, std::vector<unsigned>& vni){
  785 + getLinei(l, vi, vti);
  786 + L[l-1].get_vn(vni);
  787 + }
  788 +
  789 + /// Returns a list of points corresponding to the vertices of a line
  790 + void getLine(unsigned l, std::vector< stim::vec<T> > v){
  791 +
  792 + std::vector<unsigned> vi; //create a vector to store indices to vertices
  793 + getLinei(l, vi); //get the indices for the line vertices
  794 + v = getV(vi); //get the vertices corresponding to the indices
  795 + }
  796 +
  797 + void getLine(unsigned l, std::vector< stim::vec<T> > v, std::vector< stim::vec<T> > vt){
  798 +
  799 + std::vector<unsigned> vi, vti;
  800 + getLinei(l, vi, vti); //get the indices for the line vertices
  801 + v = getV(vi); //get the vertices corresponding to the indices
  802 + vt = getVT(vti);
  803 + }
  804 +
  805 + void getLine(unsigned l, std::vector< stim::vec<T> > v,
  806 + std::vector< stim::vec<T> > vt,
  807 + std::vector< stim::vec<T> > vn){
  808 +
  809 + std::vector<unsigned> vi, vti, vni;
  810 + getLinei(l, vi, vti, vni); //get the indices for the line vertices
  811 + v = getV(vi); //get the vertices corresponding to the indices
  812 + vt = getVT(vti);
  813 + vn = getVN(vni);
  814 +
  815 + }
  816 +
  817 +
680 818  
681 819  
682 820 };
... ...