Commit c01958adbad61ab26da7cafe2bd52749322819fc

Authored by Pavel Govyadinov
1 parent a8ad9192

merged the two stim versions to work for volume-spider, and ONLY volume spider. …

…circle.h, cylinder.h, centerline.h and some other have been changed. Other compilation errors on linux also fixxed in spharmonic.h and gl_spharmonic.h
stim/biomodels/centerline.h
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 3
4 #include <vector> 4 #include <vector>
5 #include <stim/math/vec3.h> 5 #include <stim/math/vec3.h>
  6 +//#include <ANN/ANN.h>
6 7
7 namespace stim{ 8 namespace stim{
8 9
@@ -11,134 +12,195 @@ namespace stim{ @@ -11,134 +12,195 @@ namespace stim{
11 * class to describe an interconnected (often biological) network. 12 * class to describe an interconnected (often biological) network.
12 */ 13 */
13 template<typename T> 14 template<typename T>
14 -class centerline : public std::vector< stim::vec3<T> >{ 15 +class centerline{
15 16
16 protected: 17 protected:
  18 + unsigned int N; //number of points in the fiber
  19 + double **c; //centerline (array of double pointers)
  20 +// ANNkd_tree* kdt; //kd-tree stores all points in the fiber for fast searching
  21 +
  22 + /// Initialize an empty fiber
  23 + void init()
  24 + {
  25 + N=0;
  26 + c=NULL;
  27 +// kdt = NULL;
  28 + }
17 29
18 - std::vector<T> L; //stores the integrated length along the fiber (used for parameterization)  
19 -  
20 - ///Return the normalized direction vector at point i (average of the incoming and outgoing directions)  
21 - vec3<T> d(size_t i) {  
22 - if (size() <= 1) return vec3<T>(0, 0, 0); //if there is insufficient information to calculate the direction, return a null vector  
23 - if (size() == 2) return (at(1) - at(0)).norm(); //if there are only two points, the direction vector at both is the direction of the line segment  
24 - if (i == 0) return (at(1) - at(0)).norm(); //the first direction vector is oriented towards the first line segment  
25 - if (i == size() - 1) return (at(size() - 1) - at(size() - 2)).norm(); //the last direction vector is oriented towards the last line segment  
26 -  
27 - //all other direction vectors are the average direction of the two joined line segments  
28 - vec3<T> a = at(i) - at(i - 1);  
29 - vec3<T> b = at(i + 1) - at(i);  
30 - vec3<T> ab = a.norm() + b.norm();  
31 - return ab.norm();  
32 - }  
33 - //initializes the integrated length vector to make parameterization easier, starting with index idx (all previous indices are assumed to be correct)  
34 - void update_L(size_t start = 0) {  
35 - L.resize(size()); //allocate space for the L array  
36 - if (start == 0) {  
37 - L[0] = 0; //initialize the length value for the first point to zero (0)  
38 - start++;  
39 - } 30 + /// Initialize a fiber with N centerline points (all located at [0, 0, 0] with radius 0)
  31 + void init(unsigned int n)
  32 + {
  33 +
  34 + N = n; //set the number of points
  35 +// kdt = NULL;
  36 + c = (double**) malloc(sizeof(double*) * N); //allocate the array pointer
  37 +
  38 + for(unsigned int i = 0; i < N; i++) //allocate space for each point
  39 + c[i] = (double*) malloc(sizeof(double) * 3);
  40 + }
  41 +
  42 + /// Copies an existing fiber to the current fiber
  43 +
  44 + /// @param cpy stores the new copy of the fiber
  45 + void copy( const stim::centerline<T>& cpy, bool kd = 0){
  46 +
  47 + ///allocate space for the new fiber
  48 + init(cpy.N);
40 49
41 - stim::vec3<T> d;  
42 - for (size_t i = start; i < size(); i++) { //for each line segment in the centerline  
43 - d = at(i) - at(i - 1);  
44 - L[i] = L[i - 1] + d.len(); //calculate the running length total 50 + ///copy the points
  51 + for(unsigned int i = 0; i < N; i++){
  52 + for(unsigned int d = 0; d < 3; d++) //for each dimension
  53 + c[i][d] = cpy.c[i][d]; //copy the coordinate
45 } 54 }
  55 +// if(kd)
  56 +// gen_kdtree(); //generate the kd tree for the new fiber
46 } 57 }
47 58
48 - void init() {  
49 - if (size() == 0) return; //return if there aren't any points  
50 - update_L(); 59 + /// generate a KD tree for points on fiber
  60 +// void gen_kdtree()
  61 +// {
  62 +// int n_data = N; //create an array of data points
  63 +// ANNpointArray pts = (ANNpointArray)c; //cast the centerline list to an ANNpointArray
  64 +// kdt = new ANNkd_tree(pts, n_data, 3); //build a KD tree
  65 +// }
  66 +
  67 + /// find distance between two points
  68 + double dist(double* p0, double* p1){
  69 +
  70 + double sum = 0; // initialize variables
  71 + float v;
  72 + for(unsigned int d = 0; d < 3; d++)
  73 + {
  74 + v = p1[d] - p0[d];
  75 + sum +=v * v;
  76 + }
  77 + return sqrt(sum);
51 } 78 }
52 79
  80 + /// This function retreives the index for the fiber point closest to q
  81 +
  82 + /// @param q is a reference point used to find the closest point on the fiber center line
  83 +// unsigned int ann( stim::vec<double> q ){
  84 +// ANNidxArray idx = new ANNidx[1]; //variable used to hold the nearest point
  85 +// ANNdistArray sq_dist = new ANNdist[1]; //variable used to hold the squared distance to the nearest point
  86 +// kdt->annkSearch(q.data(), 1, idx, sq_dist); //search the KD tree for the nearest neighbor
  87 +// return *idx;
  88 +// }
  89 +
53 /// Returns a stim::vec representing the point at index i 90 /// Returns a stim::vec representing the point at index i
54 91
55 /// @param i is an index of the desired centerline point 92 /// @param i is an index of the desired centerline point
56 stim::vec<T> get_vec(unsigned i){ 93 stim::vec<T> get_vec(unsigned i){
57 - return std::vector< stim::vec3<T> >::at(i);  
58 - }  
59 -  
60 - ///finds the index of the point closest to the length l on the lower bound.  
61 - ///binary search.  
62 - size_t findIdx(T l) {  
63 - for (size_t i = 1; i < L.size(); i++) { //for each point in the centerline  
64 - if (L[i] > l) return i - 1; //if we have passed the desired length value, return i-1  
65 - }  
66 - return L.size() - 1;  
67 - /*size_t i = L.size() / 2;  
68 - size_t max = L.size() - 1;  
69 - size_t min = 0;  
70 - while (i < L.size() - 1){  
71 - if (l < L[i]) {  
72 - max = i;  
73 - i = min + (max - min) / 2;  
74 - }  
75 - else if (L[i] <= l && L[i + 1] >= l) {  
76 - break;  
77 - }  
78 - else {  
79 - min = i;  
80 - i = min + (max - min) / 2;  
81 - }  
82 - }  
83 - return i;*/  
84 - } 94 + stim::vec3<T> r;
  95 + r.resize(3);
  96 + r[0] = c[i][0];
  97 + r[1] = c[i][1];
  98 + r[2] = c[i][2];
85 99
86 - ///Returns a position vector at the given length into the fiber (based on the pvalue).  
87 - ///Interpolates the radius along the line.  
88 - ///@param l: the location of the in the cylinder.  
89 - ///@param idx: integer location of the point closest to l but prior to it.  
90 - stim::vec3<T> p(T l, int idx) {  
91 - T rat = (l - L[idx]) / (L[idx + 1] - L[idx]);  
92 - stim::vec3<T> v1 = at(idx);  
93 - stim::vec3<T> v2 = at(idx + 1);  
94 - return(v1 + (v2 - v1)*rat); 100 + return r;
95 } 101 }
96 102
97 103
98 public: 104 public:
99 105
100 - using std::vector< stim::vec3<T> >::at;  
101 - using std::vector< stim::vec3<T> >::size;  
102 -  
103 - centerline() : std::vector< stim::vec3<T> >() { 106 + centerline(){
104 init(); 107 init();
105 } 108 }
106 - centerline(size_t n) : std::vector< stim::vec3<T> >(n){  
107 - init(); 109 +
  110 + /// Copy constructor
  111 + centerline(const stim::centerline<T> &obj){
  112 + copy(obj);
108 } 113 }
109 114
110 - //overload the push_back function to update the length vector  
111 - void push_back(stim::vec3<T> p) {  
112 - std::vector< stim::vec3<T> >::push_back(p);  
113 - update_L(size() - 1); 115 + //temp constructor for graph visualization
  116 + centerline(int n)
  117 + {
  118 + init(n);
114 } 119 }
115 120
116 - ///Returns a position vector at the given p-value (p value ranges from 0 to 1).  
117 - ///interpolates the position along the line.  
118 - ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1).  
119 - stim::vec3<T> p(T pvalue) {  
120 - if (pvalue <= 0.0) return at(0); //return the first element  
121 - if (pvalue >= 1.0) return back(); //return the last element 121 + /// Constructor takes a list of stim::vec points, the radius at each point is set to zero
  122 + centerline(std::vector< stim::vec<T> > p, bool kd = 0){
  123 + init(p.size()); //initialize the fiber
  124 +
  125 + //for each point, set the centerline position and radius
  126 + for(unsigned int i = 0; i < N; i++){
122 127
123 - T l = pvalue*L[L.size() - 1];  
124 - int idx = findIdx(l);  
125 - return p(l, idx); 128 + //set the centerline position
  129 + for(unsigned int d = 0; d < 3; d++)
  130 + c[i][d] = (double) p[i][d];
  131 +
  132 + //set the radius
  133 + }
  134 + //generate a kd tree
  135 +// if(kd)
  136 +// gen_kdtree();
126 } 137 }
127 138
128 - ///Update centerline internal parameters (currently the L vector)  
129 - void update() {  
130 - init(); 139 + /// constructor takes a list of points
  140 + centerline(std::vector< stim::vec3< T > > pos, bool kd = 0){
  141 + init(pos.size()); //initialize the fiber
  142 +
  143 + //for each point, set the centerline position and radius
  144 + for(unsigned int i = 0; i < N; i++){
  145 + //set the centerline position
  146 + for(unsigned int d = 0; d < 3; d++)
  147 + c[i][d] = (double) pos[i][d];
  148 + //set the radius
  149 + }
  150 +
  151 + //generate a kd tree
  152 + //if(kd)
  153 + // gen_kdtree();
  154 + }
  155 +
  156 + /// Assignment operation
  157 + centerline& operator=(const centerline &rhs){
  158 + if(this == &rhs) return *this; //test for and handle self-assignment
  159 + copy(rhs);
  160 + return *this;
131 } 161 }
132 - ///Return the length of the entire centerline  
133 - T length() {  
134 - return L.back(); 162 +
  163 +
  164 + /// Return the point on the fiber closest to q
  165 + /// @param q is the query point used to locate the nearest point on the fiber centerline
  166 +// stim::vec<T> nearest(stim::vec<T> q){
  167 +//
  168 +// stim::vec<double> temp( (double) q[0], (double) q[1], (double) q[2]);
  169 +//
  170 +// unsigned int idx = ann(temp); //determine the index of the nearest neighbor
  171 +//
  172 +// return stim::vec<T>((T) c[idx][0], (T) c[idx][1], (T) c[idx][2]); //return the nearest centerline point
  173 +// }
  174 +
  175 + /// Return the point index on the fiber closest to q
  176 + /// @param q is the query point used to locate the nearest point on the fiber centerline
  177 +// unsigned int nearest_idx(stim::vec<T> q){
  178 +//
  179 +// stim::vec<double> temp((double) q[0], (double) q[1], (double) q[2]);
  180 +//
  181 +// unsigned int idx = ann(temp); //determine the index of the nearest neighbor
  182 +//
  183 +// return idx; //return the nearest centerline point index
  184 +// }
  185 +
  186 + /// Returns the fiber centerline as an array of stim::vec points
  187 + std::vector< stim::vec<T> > get_centerline(){
  188 +
  189 + //create an array of stim vectors
  190 + std::vector< stim::vec3<T> > pts(N);
  191 +
  192 + //cast each point to a stim::vec, keeping only the position information
  193 + for(unsigned int i = 0; i < N; i++)
  194 + pts[i] = stim::vec3<T>((T) c[i][0], (T) c[i][1], (T) c[i][2]);
  195 +
  196 + //return the centerline array
  197 + return pts;
135 } 198 }
136 199
137 /// Split the fiber at the specified index. If the index is an end point, only one fiber is returned 200 /// Split the fiber at the specified index. If the index is an end point, only one fiber is returned
138 std::vector< stim::centerline<T> > split(unsigned int idx){ 201 std::vector< stim::centerline<T> > split(unsigned int idx){
139 202
140 - std::vector< stim::centerline<T> > fl; //create an array to store up to two fibers  
141 - size_t N = size(); 203 + std::vector< stim::centerline<T> > fl; //create an array to store up to two fibers
142 204
143 //if the index is an end point, only the existing fiber is returned 205 //if the index is an end point, only the existing fiber is returned
144 if(idx == 0 || idx == N-1){ 206 if(idx == 0 || idx == N-1){
@@ -154,84 +216,123 @@ public: @@ -154,84 +216,123 @@ public:
154 216
155 fl.resize(2); //set the array size to 2 217 fl.resize(2); //set the array size to 2
156 218
157 - fl[0] = stim::centerline<T>(N1); //set the size of each fiber  
158 - fl[1] = stim::centerline<T>(N2); 219 + fl[0].init(N1); //set the size of each fiber
  220 + fl[1].init(N2);
159 221
160 //copy both halves of the fiber 222 //copy both halves of the fiber
161 - unsigned int i; 223 + unsigned int i, d;
162 224
163 //first half 225 //first half
164 - for(i = 0; i < N1; i++) //for each centerline point  
165 - fl[0][i] = std::vector< stim::vec3<T> >::at(i);  
166 - fl[0].init(); //initialize the length vector 226 + for(i = 0; i < N1; i++){ //for each centerline point
  227 + for(d = 0; d < 3; d++)
  228 + fl[0].c[i][d] = c[i][d]; //copy each coordinate
  229 + }
167 230
168 //second half 231 //second half
169 - for(i = 0; i < N2; i++)  
170 - fl[1][i] = std::vector< stim::vec3<T> >::at(idx+i);  
171 - fl[1].init(); //initialize the length vector 232 + for(i = 0; i < N2; i++){
  233 + for(d = 0; d < 3; d++)
  234 + fl[1].c[i][d] = c[idx + i][d];
  235 +
  236 + }
172 } 237 }
173 238
174 return fl; //return the array 239 return fl; //return the array
175 240
176 } 241 }
177 242
  243 + /// Calculates the set of fibers resulting from a connection between the current fiber and a fiber f
  244 +
  245 + /// @param f is the fiber that will be connected to the current fiber
  246 +/* std::vector< stim::centerline<T> > connect( stim::centerline<T> &f, double dist){
  247 +
  248 + double min_dist;
  249 + unsigned int idx0, idx1;
  250 +
  251 + //go through each point in the query fiber, looking for the indices for the closest points
  252 + for(unsigned int i = 0; i < f.n_pts(); i++){
  253 + //Run through all points and find the index with the closest point, then partition the fiber and return two fibers.
  254 +
  255 + }
  256 +
  257 +
  258 +
  259 + }
  260 +*/
178 /// Outputs the fiber as a string 261 /// Outputs the fiber as a string
179 std::string str(){ 262 std::string str(){
180 std::stringstream ss; 263 std::stringstream ss;
181 - size_t N = std::vector< stim::vec3<T> >::size();  
182 - ss << "---------[" << N << "]---------" << std::endl;  
183 - for (size_t i = 0; i < N; i++)  
184 - ss << std::vector< stim::vec3<T> >::at(i) << std::endl;  
185 - ss << "--------------------" << std::endl; 264 +
  265 + //create an iterator for the point list
  266 + //typename std::list< point<T> >::iterator i;
  267 + for(unsigned int i = 0; i < N; i++){
  268 + ss<<" [ ";
  269 + for(unsigned int d = 0; d < 3; d++){
  270 + ss<<c[i][d]<<" ";
  271 + }
  272 + }
186 273
187 return ss.str(); 274 return ss.str();
188 } 275 }
189 -  
190 - /// Back method returns the last point in the fiber  
191 - stim::vec3<T> back(){  
192 - return std::vector< stim::vec3<T> >::back(); 276 + /// Returns the number of centerline points in the fiber
  277 + unsigned int size(){
  278 + return N;
193 } 279 }
194 280
195 - ////resample a fiber in the network  
196 - stim::centerline<T> resample(T spacing)  
197 - {  
198 - //std::cout<<"fiber::resample()"<<std::endl;  
199 281
200 - stim::vec3<T> v; //v-direction vector of the segment  
201 - stim::vec3<T> p; //- intermediate point to be added  
202 - stim::vec3<T> p1; // p1 - starting point of an segment on the fiber,  
203 - stim::vec3<T> p2; // p2 - ending point,  
204 - //double sum=0; //distance summation 282 + /// Bracket operator returns the element at index i
205 283
206 - size_t N = size(); 284 + /// @param i is the index of the element to be returned as a stim::vec
  285 + stim::vec<T> operator[](unsigned i){
  286 + return get_vec(i);
  287 + }
207 288
208 - centerline<T> new_c; // initialize list of new resampled points on the fiber 289 + /// Back method returns the last point in the fiber
  290 + stim::vec<T> back(){
  291 + return get_vec(N-1);
  292 + }
  293 + ////resample a fiber in the network
  294 + stim::centerline<T> resample(T spacing)
  295 + {
  296 + std::cout<<"fiber::resample()"<<std::endl;
  297 +
  298 + std::vector<T> v(3); //v-direction vector of the segment
  299 + stim::vec<T> p(3); //- intermediate point to be added
  300 + stim::vec<T> p1(3); // p1 - starting point of an segment on the fiber,
  301 + stim::vec<T> p2(3); // p2 - ending point,
  302 + double sum=0; //distance summation
  303 + std::vector<stim::vec<T> > fiberPositions = centerline();
  304 + std::vector<stim::vec<T> > newPointList; // initialize list of new resampled points on the fiber
209 // for each point on the centerline (skip if it is the last point on centerline) 305 // for each point on the centerline (skip if it is the last point on centerline)
  306 + //unsigned int N = fiberPositions.size(); // number of points on the fiber
210 for(unsigned int f=0; f< N-1; f++) 307 for(unsigned int f=0; f< N-1; f++)
211 - {  
212 - p1 = at(f);  
213 - p2 = at(f+1);  
214 - v = p2 - p1; 308 + {
215 309
216 - T lengthSegment = v.len(); //find Length of the segment as distance between the starting and ending points of the segment  
217 -  
218 - if(lengthSegment >= spacing){ // if length of the segment is greater than standard deviation resample  
219 -  
220 - // repeat resampling until accumulated stepsize is equsl to length of the segment  
221 - for(T step=0.0; step<lengthSegment; step+=spacing){  
222 - // calculate the resampled point by travelling step size in the direction of normalized gradient vector  
223 - p = p1 + v * (step / lengthSegment);  
224 -  
225 - // add this resampled points to the new fiber list  
226 - new_c.push_back(p); 310 + p1 = fiberPositions[f]; p2 = fiberPositions[f + 1]; v = p2 - p1;
  311 + for(unsigned int d = 0; d < 3; d++){
  312 + sum +=v[d] * v[d];} //length of segment-distance between starting and ending point
  313 +
  314 + T lengthSegment = sqrt(sum); //find Length of the segment as distance between the starting and ending points of the segment
  315 +
  316 + if(lengthSegment >= spacing) // if length of the segment is greater than standard deviation resample
  317 + {
  318 + // repeat resampling until accumulated stepsize is equsl to length of the segment
  319 + for(T step=0.0; step<lengthSegment; step+=spacing)
  320 + {
  321 + // calculate the resampled point by travelling step size in the direction of normalized gradient vector
  322 + for(unsigned int i=0; i<3;i++)
  323 + {
  324 + p[i] = p1[i] + v[i]*(step/lengthSegment);
  325 + } //for each dimension
  326 + // add this resampled points to the new fiber list
  327 + newPointList.push_back(p);
  328 + }
227 } 329 }
228 - }  
229 else // length of the segment is now less than standard deviation, push the ending point of the segment and proceed to the next point in the fiber 330 else // length of the segment is now less than standard deviation, push the ending point of the segment and proceed to the next point in the fiber
230 - new_c.push_back(at(f));  
231 - }  
232 - new_c.push_back(at(N-1)); //add the last point on the fiber to the new fiber list  
233 - //centerline newFiber(newPointList);  
234 - return new_c; 331 + newPointList.push_back(fiberPositions[f+1]);
  332 + }
  333 + newPointList.push_back(fiberPositions[N-1]); //add the last point on the fiber to the new fiber list
  334 + centerline newFiber(newPointList);
  335 + return newFiber;
235 } 336 }
236 337
237 }; 338 };
stim/cuda/filter.cuh
@@ -180,6 +180,7 @@ namespace stim @@ -180,6 +180,7 @@ namespace stim
180 #endif 180 #endif
181 181
182 182
  183 +// stim::cuda::gpu_local_max<float>(centers, res, conn, DIM_X, DIM_Y);
183 stim::cuda::gpu_local_max<float>(centers, res, threshold, conn, DIM_X, DIM_Y); 184 stim::cuda::gpu_local_max<float>(centers, res, threshold, conn, DIM_X, DIM_Y);
184 185
185 cudaDeviceSynchronize(); 186 cudaDeviceSynchronize();
stim/cuda/ivote/local_max.cuh
@@ -10,24 +10,24 @@ namespace stim{ @@ -10,24 +10,24 @@ namespace stim{
10 10
11 // this kernel calculates the local maximum for finding the cell centers 11 // this kernel calculates the local maximum for finding the cell centers
12 template<typename T> 12 template<typename T>
13 - __global__ void cuda_local_max(T* gpuCenters, T* gpuVote, int conn, size_t x, size_t y){ 13 + __global__ void cuda_local_max(T* gpuCenters, T* gpuVote, T final_t, int conn, int x, int y){
14 14
15 // calculate the 2D coordinates for this current thread. 15 // calculate the 2D coordinates for this current thread.
16 - size_t xi = blockIdx.x * blockDim.x + threadIdx.x;  
17 - size_t yi = blockIdx.y * blockDim.y + threadIdx.y; 16 + int xi = blockIdx.x * blockDim.x + threadIdx.x;
  17 + int yi = blockIdx.y * blockDim.y + threadIdx.y;
18 18
19 if(xi >= x || yi >= y) 19 if(xi >= x || yi >= y)
20 return; 20 return;
21 21
22 // convert 2D coordinates to 1D 22 // convert 2D coordinates to 1D
23 - size_t i = yi * x + xi; 23 + int i = yi * x + xi;
24 24
25 gpuCenters[i] = 0; //initialize the value at this location to zero 25 gpuCenters[i] = 0; //initialize the value at this location to zero
26 26
27 T val = gpuVote[i]; 27 T val = gpuVote[i];
28 28
29 //compare to the threshold 29 //compare to the threshold
30 - //if(val < final_t) return; 30 + if(val < final_t) return;
31 31
32 //define an array to store indices with same vote value 32 //define an array to store indices with same vote value
33 /*int * IdxEq; 33 /*int * IdxEq;
@@ -56,25 +56,24 @@ namespace stim{ @@ -56,25 +56,24 @@ namespace stim{
56 return; 56 return;
57 } 57 }
58 } */ 58 } */
59 - //gpuCenters[i] = 1;  
60 - gpuCenters[i] = gpuVote[i]; 59 + gpuCenters[i] = 1;
61 } 60 }
62 61
63 template<typename T> 62 template<typename T>
64 - void gpu_local_max(T* gpuCenters, T* gpuVote, unsigned int conn, size_t x, size_t y){ 63 + void gpu_local_max(T* gpuCenters, T* gpuVote, T final_t, unsigned int conn, unsigned int x, unsigned int y){
65 64
66 unsigned int max_threads = stim::maxThreadsPerBlock(); 65 unsigned int max_threads = stim::maxThreadsPerBlock();
67 /*dim3 threads(max_threads, 1); 66 /*dim3 threads(max_threads, 1);
68 dim3 blocks(x/threads.x + (x %threads.x == 0 ? 0:1) , y);*/ 67 dim3 blocks(x/threads.x + (x %threads.x == 0 ? 0:1) , y);*/
69 - dim3 threads((unsigned int)sqrt(max_threads), (unsigned int)sqrt(max_threads) );  
70 - dim3 blocks((unsigned int)x/threads.x + 1, (unsigned int)y/threads.y + 1); 68 + dim3 threads( sqrt(max_threads), sqrt(max_threads) );
  69 + dim3 blocks(x/threads.x + 1, y/threads.y + 1);
71 70
72 //call the kernel to find the local maximum. 71 //call the kernel to find the local maximum.
73 - cuda_local_max <<< blocks, threads >>>(gpuCenters, gpuVote, conn, x, y); 72 + cuda_local_max <<< blocks, threads >>>(gpuCenters, gpuVote, final_t, conn, x, y);
74 } 73 }
75 74
76 template<typename T> 75 template<typename T>
77 - void cpu_local_max(T* cpuCenters, T* cpuVote, unsigned int conn, unsigned int x, unsigned int y){ 76 + void cpu_local_max(T* cpuCenters, T* cpuVote, T final_t, unsigned int conn, unsigned int x, unsigned int y){
78 77
79 //calculate the number of bytes in the array 78 //calculate the number of bytes in the array
80 unsigned int bytes = x * y * sizeof(T); 79 unsigned int bytes = x * y * sizeof(T);
@@ -91,7 +90,7 @@ namespace stim{ @@ -91,7 +90,7 @@ namespace stim{
91 HANDLE_ERROR(cudaMemcpy(gpuVote, cpuVote, bytes, cudaMemcpyHostToDevice)); 90 HANDLE_ERROR(cudaMemcpy(gpuVote, cpuVote, bytes, cudaMemcpyHostToDevice));
92 91
93 //call the GPU version of the local max function 92 //call the GPU version of the local max function
94 - gpu_local_max<T>(gpuCenters, gpuVote, conn, x, y); 93 + gpu_local_max<T>(gpuCenters, gpuVote, final_t, conn, x, y);
95 94
96 //copy the cell centers data to the CPU 95 //copy the cell centers data to the CPU
97 cudaMemcpy(cpuCenters, gpuCenters, bytes, cudaMemcpyDeviceToHost) ; 96 cudaMemcpy(cpuCenters, gpuCenters, bytes, cudaMemcpyDeviceToHost) ;
stim/gl/gl_spider.h
@@ -2,33 +2,47 @@ @@ -2,33 +2,47 @@
2 #define STIM_GL_SPIDER_H 2 #define STIM_GL_SPIDER_H
3 3
4 //#include <GL/glew.h> 4 //#include <GL/glew.h>
  5 +///basic GL and Cuda libs
5 #include <GL/glut.h> 6 #include <GL/glut.h>
6 #include <cuda.h> 7 #include <cuda.h>
7 #include <cuda_gl_interop.h> 8 #include <cuda_gl_interop.h>
8 #include <cudaGL.h> 9 #include <cudaGL.h>
9 -#include <math.h> 10 +
  11 +///stim .*h for gl tracking and visualization
10 #include <stim/gl/gl_texture.h> 12 #include <stim/gl/gl_texture.h>
11 -#include <stim/visualization/camera.h>  
12 #include <stim/gl/error.h> 13 #include <stim/gl/error.h>
  14 +#include <stim/visualization/camera.h>
  15 +#include <stim/math/matrix_sq.h>
  16 +#include <stim/cuda/spider_cost.cuh>
  17 +#include <stim/visualization/glObj.h>
  18 +#include <stim/cuda/cudatools/glbind.h>
  19 +
  20 +///stim *.h for CUDA
  21 +#include <stim/cuda/cuda_texture.cuh>
  22 +#include <stim/cuda/cudatools.h>
  23 +
  24 +///stim *.h for branch detection
  25 +#include <stim/visualization/cylinder.h>
  26 +#include <stim/cuda/branch_detection.cuh>
  27 +#include "../../../volume-spider/glnetwork.h"
  28 +
  29 +/// *.h for math
  30 +#include <math.h>
13 #include <stim/math/vector.h> 31 #include <stim/math/vector.h>
14 #include <stim/math/vec3.h> 32 #include <stim/math/vec3.h>
15 #include <stim/math/rect.h> 33 #include <stim/math/rect.h>
16 -#include <stim/math/matrix.h>  
17 #include <stim/math/constants.h> 34 #include <stim/math/constants.h>
18 -#include <stim/cuda/spider_cost.cuh>  
19 -#include <stim/cuda/cudatools/glbind.h>  
20 #include <stim/cuda/arraymath.cuh> 35 #include <stim/cuda/arraymath.cuh>
21 -#include <stim/cuda/cuda_texture.cuh>  
22 -#include <stim/cuda/cudatools.h>  
23 -#include <stim/cuda/ivote.cuh>  
24 -#include <stim/visualization/glObj.h> 36 +#include <stim/math/random.h>
  37 +
  38 +
  39 +///c++ libs for everything
25 #include <vector> 40 #include <vector>
26 #include <stack> 41 #include <stack>
27 -#include <stim/cuda/branch_detection.cuh>  
28 -#include "../../../volume-spider/glnetwork.h"  
29 -#include <stim/visualization/cylinder.h>  
30 #include <iostream> 42 #include <iostream>
31 #include <fstream> 43 #include <fstream>
  44 +
  45 +///Timing and debugging
32 #ifdef TIMING 46 #ifdef TIMING
33 #include <ctime> 47 #include <ctime>
34 #include <cstdio> 48 #include <cstdio>
@@ -39,6 +53,7 @@ @@ -39,6 +53,7 @@
39 #include <ctime> 53 #include <ctime>
40 #endif 54 #endif
41 55
  56 +// #include <stim/cuda/testKernel.cuh>
42 #ifdef DEBUG 57 #ifdef DEBUG
43 #include <stim/cuda/testKernel.cuh> 58 #include <stim/cuda/testKernel.cuh>
44 #endif 59 #endif
@@ -61,6 +76,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -61,6 +76,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
61 double cost_time;// = 0; 76 double cost_time;// = 0;
62 double network_time;// = 0; 77 double network_time;// = 0;
63 double hit_time;// = 0; 78 double hit_time;// = 0;
  79 + int iter_t;
64 #endif 80 #endif
65 81
66 stim::vec3<float> p; //vector designating the position of the spider. 82 stim::vec3<float> p; //vector designating the position of the spider.
@@ -72,7 +88,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -72,7 +88,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
72 std::vector<float> mV; //A list of all the size vectors. 88 std::vector<float> mV; //A list of all the size vectors.
73 std::vector<float> lV; //A list of all the size vectors. 89 std::vector<float> lV; //A list of all the size vectors.
74 90
75 - stim::matrix<float, 4> cT; //current Transformation matrix (tissue)->(texture) 91 + stim::matrix_sq<float, 4> cT; //current Transformation matrix (tissue)->(texture)
76 GLuint texID; //OpenGL ID for the texture to be traced 92 GLuint texID; //OpenGL ID for the texture to be traced
77 stim::vec3<float> S; //Size of a voxel in the volume. 93 stim::vec3<float> S; //Size of a voxel in the volume.
78 stim::vec3<float> R; //Dimensions of the volume. 94 stim::vec3<float> R; //Dimensions of the volume.
@@ -339,31 +355,6 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -339,31 +355,6 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
339 #endif 355 #endif
340 } 356 }
341 357
342 -  
343 - float uniformRandom()  
344 - {  
345 - return ( (float)(rand()))/( (float)(RAND_MAX)); ///generates a random number between 0 and 1 using the uniform distribution.  
346 - }  
347 -  
348 - float normalRandom()  
349 - {  
350 - float u1 = uniformRandom();  
351 - float u2 = uniformRandom();  
352 - return cos(2.0*atan(1.0)*u2)*sqrt(-1.0*log(u1)); ///generate a random number using the normal distribution between 0 and 1.  
353 - }  
354 -  
355 - stim::vec3<float> uniformRandVector()  
356 - {  
357 - stim::vec3<float> r(uniformRandom(), uniformRandom(), 1.0); ///generate a random vector using the uniform distribution between 0 and 1.  
358 - return r;  
359 - }  
360 -  
361 - stim::vec3<float> normalRandVector()  
362 - {  
363 - stim::vec3<float> r(normalRandom(), normalRandom(), 1.0); ///generate a random vector using the normal distribution between 0 and 1.  
364 - return r;  
365 - }  
366 -  
367 358
368 //--------------------------------------------------------------------------// 359 //--------------------------------------------------------------------------//
369 //---------------------TEMPLATE CREATION METHODS----------------------------// 360 //---------------------TEMPLATE CREATION METHODS----------------------------//
@@ -400,8 +391,8 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -400,8 +391,8 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
400 glNewList(dList, GL_COMPILE); ///create a display list of all the direction templates. 391 glNewList(dList, GL_COMPILE); ///create a display list of all the direction templates.
401 for(int i = 0; i < numSamples; i++) ///for each sample 392 for(int i = 0; i < numSamples; i++) ///for each sample
402 { 393 {
403 - z = uniformRandom()*range + Z[1]; ///generate a z coordinate  
404 - theta = uniformRandom()*stim::TAU; ///generate a theta coordinate 394 + z = stim::Random<float>::uniformRandom()*range + Z[1]; ///generate a z coordinate
  395 + theta = stim::Random<float>::uniformRandom()*stim::TAU; ///generate a theta coordinate
405 phi = acos(z); ///generate a phi from the z. 396 phi = acos(z); ///generate a phi from the z.
406 stim::vec3<float> sph(1, theta, phi); ///combine into a vector in spherical coordinates. 397 stim::vec3<float> sph(1, theta, phi); ///combine into a vector in spherical coordinates.
407 stim::vec3<float> cart = sph.sph2cart();///convert to cartesian. 398 stim::vec3<float> cart = sph.sph2cart();///convert to cartesian.
@@ -460,7 +451,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -460,7 +451,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
460 UpdateBuffer(0.0, 0.0+0*n_pixels); 451 UpdateBuffer(0.0, 0.0+0*n_pixels);
461 for(int i = 1; i < numSamplesPos; i++) ///for the number of position samples 452 for(int i = 1; i < numSamplesPos; i++) ///for the number of position samples
462 { 453 {
463 - stim::vec3<float> temp = uniformRandVector(); ///generate a random point on a plane. 454 + stim::vec3<float> temp = stim::Random<float>::uniformRandVector(); ///generate a random point on a plane.
464 temp[0] = temp[0]*delta; 455 temp[0] = temp[0]*delta;
465 temp[1] = temp[1]*2*stim::PI; 456 temp[1] = temp[1]*2*stim::PI;
466 457
@@ -953,6 +944,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -953,6 +944,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
953 cost_time = 0; 944 cost_time = 0;
954 network_time = 0; 945 network_time = 0;
955 hit_time = 0; 946 hit_time = 0;
  947 + iter_t = 0;
956 #endif 948 #endif
957 #ifdef DEBUG 949 #ifdef DEBUG
958 iter = 0; 950 iter = 0;
@@ -960,7 +952,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -960,7 +952,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
960 iter_dir = 0; 952 iter_dir = 0;
961 iter_siz = 0; 953 iter_siz = 0;
962 #endif 954 #endif
963 - stepsize = 6.0; 955 + stepsize = 3.0;
964 n_pixels = 16.0; 956 n_pixels = 16.0;
965 957
966 srand(100); 958 srand(100);
@@ -1274,12 +1266,19 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -1274,12 +1266,19 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1274 { 1266 {
1275 std::vector <double> ret; 1267 std::vector <double> ret;
1276 ret.resize(7); 1268 ret.resize(7);
  1269 + // ret[0] = branch_time/(float)iter;
1277 ret[0] = branch_time; 1270 ret[0] = branch_time;
  1271 + // ret[1] = direction_time/(float)iter;
1278 ret[1] = direction_time; 1272 ret[1] = direction_time;
  1273 + // ret[2] = position_time/(float)iter;
1279 ret[2] = position_time; 1274 ret[2] = position_time;
  1275 + // ret[3] = size_time/(float)iter;
1280 ret[3] = size_time; 1276 ret[3] = size_time;
  1277 + // ret[4] = cost_time/(float)iter;
1281 ret[4] = cost_time; 1278 ret[4] = cost_time;
  1279 + // ret[5] = network_time/(float)iter;
1282 ret[5] = network_time; 1280 ret[5] = network_time;
  1281 + // ret[6] = hit_time/(float)iter;
1283 ret[6] = hit_time; 1282 ret[6] = hit_time;
1284 1283
1285 return ret; 1284 return ret;
@@ -1311,6 +1310,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -1311,6 +1310,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1311 setSeed(x, y, z); 1310 setSeed(x, y, z);
1312 setSeedVec(u, v, w); 1311 setSeedVec(u, v, w);
1313 setSeedMag(m); 1312 setSeedMag(m);
  1313 + std::cout << getLastSeed() << getLastSeedVec() << std::cout;
1314 } 1314 }
1315 myfile.close(); 1315 myfile.close();
1316 } else { 1316 } else {
@@ -1320,7 +1320,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -1320,7 +1320,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1320 1320
1321 ///Saves the network to a file. 1321 ///Saves the network to a file.
1322 void 1322 void
1323 - saveNetwork(std::string name) 1323 + saveNetwork(std::string name, int xoffset = 0, int yoffset = 0, int zoffset = 0)
1324 { 1324 {
1325 stim::glObj<float> sk1; 1325 stim::glObj<float> sk1;
1326 for(int i = 0; i < nt.sizeE(); i++) 1326 for(int i = 0; i < nt.sizeE(); i++)
@@ -1331,7 +1331,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -1331,7 +1331,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1331 for(int j = 0; j < ce.size(); j++) 1331 for(int j = 0; j < ce.size(); j++)
1332 { 1332 {
1333 sk1.TexCoord(cm[j]); 1333 sk1.TexCoord(cm[j]);
1334 - sk1.Vertex(ce[j][0], ce[j][1], ce[j][2]); 1334 + sk1.Vertex(ce[j][0]+xoffset, ce[j][1]+yoffset, ce[j][2]+zoffset);
1335 } 1335 }
1336 sk1.End(); 1336 sk1.End();
1337 } 1337 }
@@ -1408,6 +1408,11 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -1408,6 +1408,11 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1408 #ifdef DEBUG 1408 #ifdef DEBUG
1409 std::cerr << std::endl; 1409 std::cerr << std::endl;
1410 #endif 1410 #endif
  1411 +
  1412 + #ifdef TIMING
  1413 + iter_t++;
  1414 + #endif
  1415 +
1411 return current_cost; 1416 return current_cost;
1412 } 1417 }
1413 1418
@@ -1422,36 +1427,6 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -1422,36 +1427,6 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1422 //--------------------------------------------------------------------------// 1427 //--------------------------------------------------------------------------//
1423 //-----------------------------EXPERIMENTAL METHODS-------------------------// 1428 //-----------------------------EXPERIMENTAL METHODS-------------------------//
1424 //--------------------------------------------------------------------------// 1429 //--------------------------------------------------------------------------//
1425 -  
1426 - void  
1427 - MonteCarloDirectionVectors(int nSamples, float solidAngle = stim::TAU)  
1428 - {  
1429 -// float PHI[2];//, Z[2];//, range;  
1430 -// PHI[0] = asin(solidAngle/2);  
1431 -// PHI[1] = asin(0);  
1432 -  
1433 -// Z[0] = cos(PHI[0]);  
1434 -// Z[1] = cos(PHI[1]);  
1435 -  
1436 -// range = Z[0] - Z[1];  
1437 -  
1438 - std::vector<stim::vec3<float> > vecsUni;  
1439 - for(int i = 0; i < numSamplesPos; i++)  
1440 - {  
1441 - stim::vec3<float> a(uniformRandom()*0.8, uniformRandom()*0.8, 0.0);  
1442 - a[0] = a[0]-0.4;  
1443 - a[1] = a[1]-0.4;  
1444 - vecsUni.push_back(a);  
1445 - }  
1446 -  
1447 - stringstream name;  
1448 - for(int i = 0; i < numSamplesPos; i++)  
1449 - name << vecsUni[i].str() << std::endl;  
1450 -  
1451 - std::ofstream outFile;  
1452 - outFile.open("New_Pos_Vectors.txt");  
1453 - outFile << name.str().c_str();  
1454 - }  
1455 /* 1430 /*
1456 void 1431 void
1457 DrawCylinder() 1432 DrawCylinder()
@@ -1570,9 +1545,6 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -1570,9 +1545,6 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1570 { 1545 {
1571 //Define the varibles and turn on Selection Mode 1546 //Define the varibles and turn on Selection Mode
1572 1547
1573 - #ifdef TIMING  
1574 - gpuStartTimer();  
1575 - #endif  
1576 1548
1577 GLuint selectBuf[2048]; ///size of the selection buffer in bytes. 1549 GLuint selectBuf[2048]; ///size of the selection buffer in bytes.
1578 GLint hits; ///hit fibers 1550 GLint hits; ///hit fibers
@@ -1602,6 +1574,9 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -1602,6 +1574,9 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1602 glPushMatrix(); 1574 glPushMatrix();
1603 glLoadIdentity(); 1575 glLoadIdentity();
1604 1576
  1577 + #ifdef TIMING
  1578 + gpuStartTimer();
  1579 + #endif
1605 CHECK_OPENGL_ERROR 1580 CHECK_OPENGL_ERROR
1606 gluLookAt(ps[0], ps[1], ps[2], 1581 gluLookAt(ps[0], ps[1], ps[2],
1607 ds[0], ds[1], ds[2], 1582 ds[0], ds[1], ds[2],
@@ -1849,6 +1824,65 @@ class gl_spider // : public virtual gl_texture&lt;T&gt; @@ -1849,6 +1824,65 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1849 std::cout << "I broke out!" << std::endl; 1824 std::cout << "I broke out!" << std::endl;
1850 #endif 1825 #endif
1851 } 1826 }
  1827 +//--------------------------------------------------------------------------//
  1828 +//--------------------------------DEPRECIATED-------------------------------//
  1829 +//--------------------------------------------------------------------------//
  1830 +/*
  1831 + float uniformRandom()
  1832 + {
  1833 + return ( (float)(rand()))/( (float)(RAND_MAX)); ///generates a random number between 0 and 1 using the uniform distribution.
  1834 + }
  1835 +
  1836 + float normalRandom()
  1837 + {
  1838 + float u1 = uniformRandom();
  1839 + float u2 = uniformRandom();
  1840 + return cos(2.0*atan(1.0)*u2)*sqrt(-1.0*log(u1)); ///generate a random number using the normal distribution between 0 and 1.
  1841 + }
  1842 +
  1843 + stim::vec3<float> uniformRandVector()
  1844 + {
  1845 + stim::vec3<float> r(uniformRandom(), uniformRandom(), 1.0); ///generate a random vector using the uniform distribution between 0 and 1.
  1846 + return r;
  1847 + }
  1848 +
  1849 + stim::vec3<float> normalRandVector()
  1850 + {
  1851 + stim::vec3<float> r(normalRandom(), normalRandom(), 1.0); ///generate a random vector using the normal distribution between 0 and 1.
  1852 + return r;
  1853 + }
  1854 +
  1855 + void
  1856 + MonteCarloDirectionVectors(int nSamples, float solidAngle = stim::TAU)
  1857 + {
  1858 +// float PHI[2];//, Z[2];//, range;
  1859 +// PHI[0] = asin(solidAngle/2);
  1860 +// PHI[1] = asin(0);
  1861 +
  1862 +// Z[0] = cos(PHI[0]);
  1863 +// Z[1] = cos(PHI[1]);
  1864 +
  1865 +// range = Z[0] - Z[1];
  1866 +
  1867 + std::vector<stim::vec3<float> > vecsUni;
  1868 + for(int i = 0; i < numSamplesPos; i++)
  1869 + {
  1870 + stim::vec3<float> a(uniformRandom()*0.8, uniformRandom()*0.8, 0.0);
  1871 + a[0] = a[0]-0.4;
  1872 + a[1] = a[1]-0.4;
  1873 + vecsUni.push_back(a);
  1874 + }
  1875 +
  1876 + stringstream name;
  1877 + for(int i = 0; i < numSamplesPos; i++)
  1878 + name << vecsUni[i].str() << std::endl;
  1879 +
  1880 + std::ofstream outFile;
  1881 + outFile.open("New_Pos_Vectors.txt");
  1882 + outFile << name.str().c_str();
  1883 + }
  1884 +
  1885 +*/
1852 }; 1886 };
1853 } 1887 }
1854 #endif 1888 #endif
@@ -187,7 +187,7 @@ namespace stim { @@ -187,7 +187,7 @@ namespace stim {
187 } 187 }
188 188
189 bool open(std::string filename) { //open the bitmap file and read the header data 189 bool open(std::string filename) { //open the bitmap file and read the header data
190 - file.open(filename, std::ifstream::binary); 190 + file.open(filename.c_str(), std::ifstream::binary);
191 if (!file) { 191 if (!file) {
192 std::cout << "stim::bmp ERROR: error opening file: " << filename.c_str() << std::endl; 192 std::cout << "stim::bmp ERROR: error opening file: " << filename.c_str() << std::endl;
193 return false; 193 return false;
@@ -246,7 +246,7 @@ namespace stim { @@ -246,7 +246,7 @@ namespace stim {
246 info_header.bcSize = sizeof(tagBITMAPCOREHEADER); 246 info_header.bcSize = sizeof(tagBITMAPCOREHEADER);
247 info_header.bcPlanes = 1; 247 info_header.bcPlanes = 1;
248 248
249 - std::ofstream outfile(filename, std::ios::binary); //open the output file for binary writing 249 + std::ofstream outfile(filename.c_str(), std::ios::binary); //open the output file for binary writing
250 outfile.write((char*)&file_header, sizeof(tagBITMAPFILEHEADER)); //write the file header 250 outfile.write((char*)&file_header, sizeof(tagBITMAPFILEHEADER)); //write the file header
251 outfile.write((char*)&info_header, sizeof(tagBITMAPCOREHEADER)); //write the information header 251 outfile.write((char*)&info_header, sizeof(tagBITMAPCOREHEADER)); //write the information header
252 252
@@ -259,4 +259,4 @@ namespace stim { @@ -259,4 +259,4 @@ namespace stim {
259 free(pad); 259 free(pad);
260 return true; 260 return true;
261 } 261 }
262 -}  
263 \ No newline at end of file 262 \ No newline at end of file
  263 +}
stim/image/image.h
@@ -606,7 +606,7 @@ public: @@ -606,7 +606,7 @@ public:
606 606
607 //crop regions given by an array of 1D index values 607 //crop regions given by an array of 1D index values
608 std::vector< image<T> > crop_idx(size_t w, size_t h, std::vector<size_t> idx) { 608 std::vector< image<T> > crop_idx(size_t w, size_t h, std::vector<size_t> idx) {
609 - std::vector<image<T>> result(idx.size()); //create an array of image files to return 609 + std::vector<image<T> > result(idx.size()); //create an array of image files to return
610 for (size_t i = 0; i < idx.size(); i++) { //for each specified index point 610 for (size_t i = 0; i < idx.size(); i++) { //for each specified index point
611 size_t y = idx[i] / X(); //calculate the y coordinate from the 1D index (center of ROI) 611 size_t y = idx[i] / X(); //calculate the y coordinate from the 1D index (center of ROI)
612 size_t x = idx[i] - y * X(); //calculate the x coordinate (center of ROI) 612 size_t x = idx[i] - y * X(); //calculate the x coordinate (center of ROI)
stim/math/circle.h
@@ -18,14 +18,13 @@ class circle : plane&lt;T&gt; @@ -18,14 +18,13 @@ class circle : plane&lt;T&gt;
18 18
19 private: 19 private:
20 20
21 - //stim::vec3<T> Y;  
22 - T R; //radius of the circle 21 + stim::vec3<T> Y;
23 22
24 - /*CUDA_CALLABLE void 23 + CUDA_CALLABLE void
25 init() 24 init()
26 { 25 {
27 Y = U.cross(N).norm(); 26 Y = U.cross(N).norm();
28 - }*/ 27 + }
29 28
30 public: 29 public:
31 using stim::plane<T>::n; 30 using stim::plane<T>::n;
@@ -35,8 +34,6 @@ public: @@ -35,8 +34,6 @@ public:
35 using stim::plane<T>::rotate; 34 using stim::plane<T>::rotate;
36 using stim::plane<T>::setU; 35 using stim::plane<T>::setU;
37 36
38 - using stim::plane<T>::init;  
39 -  
40 ///base constructor 37 ///base constructor
41 ///@param th value of the angle of the starting point from 0 to 360. 38 ///@param th value of the angle of the starting point from 0 to 360.
42 CUDA_CALLABLE 39 CUDA_CALLABLE
@@ -45,28 +42,26 @@ public: @@ -45,28 +42,26 @@ public:
45 init(); 42 init();
46 } 43 }
47 44
48 - ///create a circle given a size and position in Z space. 45 + ///create a rectangle given a size and position in Z space.
49 ///@param size: size of the rectangle in ND space. 46 ///@param size: size of the rectangle in ND space.
50 ///@param z_pos z coordinate of the rectangle. 47 ///@param z_pos z coordinate of the rectangle.
51 CUDA_CALLABLE 48 CUDA_CALLABLE
52 - circle(T radius, T z_pos = (T)0) : plane<T>(z_pos) 49 + circle(T size, T z_pos = (T)0) : plane<T>()
53 { 50 {
54 - //center(stim::vec3<T>(0, 0, z_pos));  
55 - //scale(size);  
56 - //init();  
57 - R = radius; 51 + center(stim::vec3<T>(0,0,z_pos));
  52 + scale(size);
  53 + init();
58 } 54 }
59 55
60 ///create a rectangle from a center point, normal 56 ///create a rectangle from a center point, normal
61 ///@param c: x,y,z location of the center. 57 ///@param c: x,y,z location of the center.
62 ///@param n: x,y,z direction of the normal. 58 ///@param n: x,y,z direction of the normal.
63 CUDA_CALLABLE 59 CUDA_CALLABLE
64 - circle(vec3<T> c, vec3<T> n = vec3<T>(0,0,1)) : plane<T>(n, c) 60 + circle(vec3<T> c, vec3<T> n = vec3<T>(0,0,1)) : plane<T>()
65 { 61 {
66 - //center(c);  
67 - //normal(n);  
68 - //init();  
69 - R = (T)1; 62 + center(c);
  63 + normal(n);
  64 + init();
70 } 65 }
71 66
72 /*///create a rectangle from a center point, normal, and size 67 /*///create a rectangle from a center point, normal, and size
@@ -89,18 +84,14 @@ public: @@ -89,18 +84,14 @@ public:
89 ///@param n: x,y,z direction of the normal. 84 ///@param n: x,y,z direction of the normal.
90 ///@param u: x,y,z direction for the zero vector (from where the rotation starts) 85 ///@param u: x,y,z direction for the zero vector (from where the rotation starts)
91 CUDA_CALLABLE 86 CUDA_CALLABLE
92 - circle(vec3<T> c, T r, vec3<T> n = vec3<T>(0,0,1), vec3<T> u = vec3<T>(1, 0, 0)) : plane<T>() 87 + circle(vec3<T> c, T s, vec3<T> n = vec3<T>(0,0,1), vec3<T> u = vec3<T>(1, 0, 0)) : plane<T>()
93 { 88 {
94 - P = c;  
95 - N = n; 89 + init();
96 setU(u); 90 setU(u);
97 - R = r;  
98 - //init();  
99 - //setU(u);  
100 // U = u; 91 // U = u;
101 - //center(c);  
102 - //normal(n);  
103 - //scale(s); 92 + center(c);
  93 + normal(n);
  94 + scale(s);
104 } 95 }
105 96
106 ///scales the circle by a certain factor 97 ///scales the circle by a certain factor
@@ -108,111 +99,86 @@ public: @@ -108,111 +99,86 @@ public:
108 CUDA_CALLABLE 99 CUDA_CALLABLE
109 void scale(T factor) 100 void scale(T factor)
110 { 101 {
111 - //U *= factor;  
112 - //Y *= factor;  
113 - R *= factor;  
114 - }  
115 -  
116 - ///set the radius of circle to a certain value  
117 - ///@param value: the new radius of the circle  
118 - CUDA_CALLABLE  
119 - void set_R(T value)  
120 - {  
121 - R = value; 102 + U *= factor;
  103 + Y *= factor;
122 } 104 }
123 105
124 ///sets the normal for the cirlce 106 ///sets the normal for the cirlce
125 ///@param n: x,y,z direction of the normal. 107 ///@param n: x,y,z direction of the normal.
126 CUDA_CALLABLE void 108 CUDA_CALLABLE void
127 - normal(vec3<T> n){  
128 - rotate(n); 109 + normal(vec3<T> n)
  110 + {
  111 + rotate(n, Y);
129 } 112 }
130 113
131 ///sets the center of the circle. 114 ///sets the center of the circle.
132 ///@param n: x,y,z location of the center. 115 ///@param n: x,y,z location of the center.
133 CUDA_CALLABLE void 116 CUDA_CALLABLE void
134 center(vec3<T> p){ 117 center(vec3<T> p){
135 - P = p; 118 + this->P = p;
136 } 119 }
137 120
138 ///boolean comparison 121 ///boolean comparison
139 bool 122 bool
140 operator==(const circle<T> & rhs) 123 operator==(const circle<T> & rhs)
141 { 124 {
142 - if(P == rhs.P && U == rhs.U) 125 + if(P == rhs.P && U == rhs.U && Y == rhs.Y)
143 return true; 126 return true;
144 else 127 else
145 return false; 128 return false;
146 } 129 }
147 130
148 - //returns the point in world space corresponding to the polar coordinate (r, theta)  
149 - CUDA_CALLABLE stim::vec3<T>  
150 - p(T r, T theta) {  
151 - T u = r * cos(theta); //calculate the coordinates in the planar space defined by the circle  
152 - T v = r * sin(theta);  
153 -  
154 - vec3<T> V = U.cross(N); //calculate the orthogonal vector V  
155 - return P + U * u + V * v; //calculate the cartesian coordinate of the specified point  
156 - }  
157 -  
158 - //returns the point in world space corresponding to the value theta at radius R  
159 - CUDA_CALLABLE stim::vec3<T>  
160 - p(T theta) {  
161 - return p(R, theta);  
162 - }  
163 -  
164 - //get the world space value given the polar coordinates (r, theta)  
165 -  
166 ///get the world space value given the planar coordinates a, b in [0, 1] 131 ///get the world space value given the planar coordinates a, b in [0, 1]
167 - /*CUDA_CALLABLE stim::vec3<T> p(T a, T b) 132 + CUDA_CALLABLE stim::vec3<T> p(T a, T b)
168 { 133 {
169 stim::vec3<T> result; 134 stim::vec3<T> result;
170 135
171 vec3<T> A = this->P - this->U * (T)0.5 - Y * (T)0.5; 136 vec3<T> A = this->P - this->U * (T)0.5 - Y * (T)0.5;
172 result = A + this->U * a + Y * b; 137 result = A + this->U * a + Y * b;
173 return result; 138 return result;
174 - }*/ 139 + }
175 140
176 ///parenthesis operator returns the world space given rectangular coordinates a and b in [0 1] 141 ///parenthesis operator returns the world space given rectangular coordinates a and b in [0 1]
177 - CUDA_CALLABLE stim::vec3<T> operator()(T r, T theta) 142 + CUDA_CALLABLE stim::vec3<T> operator()(T a, T b)
178 { 143 {
179 - return p(r, theta);  
180 - }  
181 -  
182 - //parenthesis operator returns the world space coordinate at the edge of the circle given theta  
183 - CUDA_CALLABLE stim::vec3<T> operator()(T theta) {  
184 - return p(theta); 144 + return p(a,b);
185 } 145 }
186 146
187 ///returns a vector with the points on the initialized circle. 147 ///returns a vector with the points on the initialized circle.
188 ///connecting the points results in a circle. 148 ///connecting the points results in a circle.
189 ///@param n: integer for the number of points representing the circle. 149 ///@param n: integer for the number of points representing the circle.
190 - std::vector< stim::vec3<T> > points(unsigned n) {  
191 - std::vector< stim::vec3<T> > result(n); //initialize a vector of n points  
192 -  
193 - float dt = stim::TAU / n;  
194 - for (unsigned i = 0; i < n; i++)  
195 - result[i] = p(i * dt); //calculate a point on the edge of the circle 150 + std::vector<stim::vec3<T> >
  151 + getPoints(int n)
  152 + {
  153 + std::vector<stim::vec3<T> > result;
  154 + stim::vec3<T> point;
  155 + T x,y;
  156 + float step = 360.0/(float) n;
  157 + for(float j = 0; j <= 360.0; j += step)
  158 + {
  159 + y = 0.5*cos(j*stim::TAU/360.0)+0.5;
  160 + x = 0.5*sin(j*stim::TAU/360.0)+0.5;
  161 + result.push_back(p(x,y));
  162 + }
196 return result; 163 return result;
197 } 164 }
198 -  
199 - ///returns a vector with the points on the initialized circle  
200 - ///connecting the points results in a circle  
201 - ///@param n: integer for the number of points representing the circle  
202 - ///the only difference between points and glpoints is that the first point appears twice in the returning lists  
203 - std::vector< stim::vec3<T> > glpoints(unsigned n) {  
204 - std::vector< stim::vec3<T> > result(n + 1);  
205 - float dt = stim::TAU / n;  
206 - for (unsigned i = 0; i < n; i++)  
207 - result[i] = p(i * dt);  
208 - result[n] = p(0); //close the circle!  
209 - return result;  
210 - }  
211 165
  166 + ///returns a vector with the points on the initialized circle.
  167 + ///connecting the points results in a circle.
  168 + ///@param n: integer for the number of points representing the circle.
  169 + CUDA_CALLABLE stim::vec3<T>
  170 + p(T theta)
  171 + {
  172 + T x,y;
  173 + y = 0.5*cos(theta*STIM_TAU/360.0)+0.5;
  174 + x = 0.5*sin(theta*STIM_TAU/360.0)+0.5;
  175 + return p(x,y);
  176 + }
  177 +
212 std::string str() const 178 std::string str() const
213 { 179 {
214 std::stringstream ss; 180 std::stringstream ss;
215 - ss << "r = "<<R<<" (P=" << P.str() << ", N=" << N.str() << ", U=" << U.str() << ")"; 181 + ss << "(P=" << P.str() << ", N=" << N.str() << ", U=" << U.str() << ", Y=" << Y.str();
216 return ss.str(); 182 return ss.str();
217 } 183 }
218 184
stim/math/random.h
@@ -17,7 +17,7 @@ protected: @@ -17,7 +17,7 @@ protected:
17 if(seed <= 0) 17 if(seed <= 0)
18 srand(time(NULL)); 18 srand(time(NULL));
19 else if(seed > 0) 19 else if(seed > 0)
20 - srand(time(seed)); 20 + srand(seed);
21 else 21 else
22 std::cout << "Error: Unknown value: in STIM::RANDOM" << std::endl; 22 std::cout << "Error: Unknown value: in STIM::RANDOM" << std::endl;
23 } 23 }
stim/math/spharmonics.h
@@ -181,7 +181,7 @@ namespace stim { @@ -181,7 +181,7 @@ namespace stim {
181 /// @param n is the number of points of the surface of the sphere used to create the PDF. DEFAULT 1000 181 /// @param n is the number of points of the surface of the sphere used to create the PDF. DEFAULT 1000
182 /// @param norm, a boolean that sets where the output vectors will be normalized between 0 and 1. 182 /// @param norm, a boolean that sets where the output vectors will be normalized between 0 and 1.
183 /// @param 183 /// @param
184 - /*void pdf(std::vector<stim::vec3<T> > sph_pts, unsigned int l, int m, stim::vec3<T> c = stim::vec3<T>(0, 0, 0), unsigned int n = 1000, bool norm = true, std::vector<T> w = std::vector<T>()) 184 + void pdf(std::vector<stim::vec3<T> > sph_pts, unsigned int l, int m, stim::vec3<T> c = stim::vec3<T>(0, 0, 0), unsigned int n = 1000, bool norm = true, std::vector<T> w = std::vector<T>())
185 { 185 {
186 std::vector<double> weights; ///the weight at each point on the surface of the sphere. 186 std::vector<double> weights; ///the weight at each point on the surface of the sphere.
187 // weights.resize(n); 187 // weights.resize(n);
@@ -223,7 +223,7 @@ namespace stim { @@ -223,7 +223,7 @@ namespace stim {
223 } 223 }
224 } 224 }
225 mcEnd(); 225 mcEnd();
226 - }*/ 226 + }
227 227
228 std::string str() { 228 std::string str() {
229 229
@@ -313,6 +313,52 @@ namespace stim { @@ -313,6 +313,52 @@ namespace stim {
313 T operator()(T theta, T phi) { 313 T operator()(T theta, T phi) {
314 return p(theta, phi); 314 return p(theta, phi);
315 } 315 }
  316 +
  317 + //overload arithmetic operations
  318 +
  319 + spharmonics<T> operator*(T rhs) const {
  320 +
  321 + spharmonics<T> result(C.size()); //create a new spherical harmonics object
  322 +
  323 + for (size_t c = 0; c < C.size(); c++) //for each coefficient
  324 +
  325 + result.C[c] = C[c] * rhs; //calculate the factor and store the result in the new spharmonics object
  326 +
  327 + return result;
  328 +
  329 + }
  330 +
  331 +
  332 +
  333 + spharmonics<T> operator+(spharmonics<T> rhs) {
  334 +
  335 + size_t low = std::min(C.size(), rhs.C.size()); //store the number of coefficients in the lowest object
  336 + size_t high = std::max(C.size(), rhs.C.size()); //store the number of coefficients in the result
  337 + bool rhs_lowest = false; //true if rhs has the lowest number of coefficients
  338 + if (rhs.C.size() < C.size()) rhs_lowest = true; //if rhs has a lower number of coefficients, set the flag
  339 +
  340 +
  341 +
  342 + spharmonics<T> result(high); //create a new object
  343 +
  344 + size_t c;
  345 + for (c = 0; c < low; c++) //perform the first batch of additions
  346 + result.C[c] = C[c] + rhs.C[c]; //perform the addition
  347 +
  348 + for (c = low; c < high; c++) {
  349 + if (rhs_lowest)
  350 + result.C[c] = C[c];
  351 + else
  352 + result.C[c] = rhs.C[c];
  353 + }
  354 + return result;
  355 + }
  356 +
  357 +
  358 +
  359 + spharmonics<T> operator-(spharmonics<T> rhs) {
  360 + return (*this) + (rhs * (T)(-1));
  361 + }
316 /// Fill an NxN grid with the spherical function for theta = [0 2pi] and phi = [0 pi] 362 /// Fill an NxN grid with the spherical function for theta = [0 2pi] and phi = [0 pi]
317 void get_func(T* data, size_t X, size_t Y) { 363 void get_func(T* data, size_t X, size_t Y) {
318 T dt = stim::TAU / (T)X; //calculate the step size in each direction 364 T dt = stim::TAU / (T)X; //calculate the step size in each direction
@@ -351,4 +397,4 @@ namespace stim { @@ -351,4 +397,4 @@ namespace stim {
351 } 397 }
352 398
353 399
354 -#endif  
355 \ No newline at end of file 400 \ No newline at end of file
  401 +#endif
stim/visualization/cylinder.h
@@ -3,268 +3,56 @@ @@ -3,268 +3,56 @@
3 #include <iostream> 3 #include <iostream>
4 #include <stim/math/circle.h> 4 #include <stim/math/circle.h>
5 #include <stim/biomodels/centerline.h> 5 #include <stim/biomodels/centerline.h>
6 -#include <stim/visualization/obj.h>  
7 6
  7 +/*
  8 +
  9 +*/
8 10
9 namespace stim 11 namespace stim
10 { 12 {
11 template<typename T> 13 template<typename T>
12 -class cylinder : public centerline<T> {  
13 -protected:  
14 -  
15 - using stim::centerline<T>::d; 14 +class cylinder
  15 + : public centerline<T>
  16 +{
  17 + private:
  18 + stim::circle<T> s; //an arbitrary circle
  19 + std::vector<stim::circle<T> > e; //an array of circles that store the centerline
16 20
17 - std::vector< stim::vec3<T> > U; //stores the array of U vectors defining the Frenet frame  
18 - std::vector< T > R; //stores a list of magnitudes for each point in the centerline (assuming mags[0] is the radius) 21 + std::vector<stim::vec3<T> > norms;
  22 + std::vector<stim::vec<T> > Us;
  23 + std::vector<stim::vec<T> > mags; //stores a list of magnitudes for each point in the centerline (assuming mags[0] is the radius)
  24 + std::vector< T > L; //length of the cylinder at each position (pre-integration)
19 25
20 - using stim::centerline<T>::findIdx;  
21 -  
22 - //calculates the U values for each point to initialize the frenet frame  
23 - // this function assumes that the centerline has already been set  
24 - void init() {  
25 - U.resize(size()); //allocate space for the frenet frame vectors  
26 - R.resize(size());  
27 -  
28 - stim::circle<T> c; //create a circle  
29 - stim::vec3<T> d0, d1;  
30 - for (size_t i = 0; i < size() - 1; i++) { //for each line segment in the centerline  
31 - c.rotate(d(i)); //rotate the circle to match that normal  
32 - U[i] = c.U; //save the U vector from the circle  
33 - }  
34 - U[size() - 1] = c.U; //for the last point, duplicate the final frenet frame vector  
35 - }  
36 -  
37 -public:  
38 -  
39 - using stim::centerline<T>::size;  
40 - using stim::centerline<T>::at;  
41 - using stim::centerline<T>::L;  
42 - using stim::centerline<T>::length;  
43 -  
44 - cylinder() : centerline<T>(){}  
45 -  
46 - cylinder(centerline<T>c) : centerline<T>(c) {  
47 - init();  
48 - }  
49 -  
50 - //cylinder(centerline<T>c, T r) : centerline(c) {  
51 - // init();  
52 - // //add_mag(r);  
53 - //}  
54 -  
55 - //initialize a cylinder with a list of points and magnitude values  
56 - //cylinder(centerline<T>c, std::vector<T> r) : centerline(c){  
57 - // init();  
58 - // //add_mag(r);  
59 - //}  
60 -  
61 - //copy the original radius  
62 - void copy_r(std::vector<T> radius) {  
63 - for (unsigned i = 0; i < radius.size(); i++)  
64 - R[i] = radius[i];  
65 - }  
66 -  
67 - ///Returns magnitude i at the given length into the fiber (based on the pvalue).  
68 - ///Interpolates the position along the line.  
69 - ///@param l: the location of the in the cylinder.  
70 - ///@param idx: integer location of the point closest to l but prior to it.  
71 - T r(T l, int idx) {  
72 - T a = (l - L[idx]) / (L[idx + 1] - L[idx]);  
73 - T v2 = (R[idx] + (R[idx + 1] - R[idx])*a);  
74 -  
75 - return v2;  
76 - }  
77 -  
78 - ///Returns the ith magnitude at the given p-value (p value ranges from 0 to 1).  
79 - ///interpolates the radius along the line.  
80 - ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1).  
81 - T rl(T pvalue) {  
82 - if (pvalue <= 0.0) return R[0];  
83 - if (pvalue >= 1.0) return R[size() - 1];  
84 -  
85 - T l = pvalue*L[L.size() - 1];  
86 - int idx = findIdx(l);  
87 - return r(l, idx);  
88 - }  
89 -  
90 - /// Returns the magnitude at the given index  
91 - /// @param i is the index of the desired point  
92 - /// @param r is the index of the magnitude value  
93 - T r(unsigned i) {  
94 - return R[i];  
95 - }  
96 -  
97 - ///adds a magnitude to each point in the cylinder  
98 - /*void add_mag(V val = 0) {  
99 - if (M.size() == 0) M.resize(size()); //if the magnitude vector isn't initialized, resize it to match the centerline  
100 - for (size_t i = 0; i < size(); i++) //for each point  
101 - R[i].push_back(val); //add this value to the magnitude vector at each point  
102 - }*/  
103 -  
104 - //adds a magnitude based on a list of magnitudes for each point  
105 - /*void add_mag(std::vector<T> val) {  
106 - if (M.size() == 0) M.resize(size()); //if the magnitude vector isn't initialized, resize it to match the centerline  
107 - for (size_t i = 0; i < size(); i++) //for each point  
108 - R[i].push_back(val[i]); //add this value to the magnitude vector at each point  
109 - }*/  
110 -  
111 - //sets the value of magnitude m at point i  
112 - void set_r(size_t i, T r) {  
113 - R[i] = r;  
114 - }  
115 -  
116 - /*size_t nmags() {  
117 - if (M.size() == 0) return 0;  
118 - else return R[0].size();  
119 - }*/  
120 -  
121 - ///Returns a circle representing the cylinder cross section at point i  
122 - stim::circle<T> circ(size_t i) {  
123 - return stim::circle<T>(at(i), R[i], d(i), U[i]);  
124 - }  
125 -  
126 - ///Returns an OBJ object representing the cylinder with a radial tesselation value of N using magnitude m  
127 - stim::obj<T> OBJ(size_t N) {  
128 - stim::obj<T> out; //create an OBJ object  
129 - stim::circle<T> c0, c1;  
130 - std::vector< stim::vec3<T> > p0, p1; //allocate space for the point sets representing the circles bounding each cylinder segment  
131 - T u0, u1, v0, v1; //allocate variables to store running texture coordinates  
132 - for (size_t i = 1; i < size(); i++) { //for each line segment in the cylinder  
133 - c0 = circ(i - 1); //get the two circles bounding the line segment  
134 - c1 = circ(i);  
135 -  
136 - p0 = c0.points(N); //get t points for each of the end caps  
137 - p1 = c1.points(N);  
138 -  
139 - u0 = L[i - 1] / length(); //calculate the texture coordinate (u, v) where u runs along the cylinder length  
140 - u1 = L[i] / length();  
141 -  
142 - for (size_t n = 1; n < N; n++) { //for each point in the circle  
143 - v0 = (double)(n-1) / (double)(N - 1); //v texture coordinate runs around the cylinder  
144 - v1 = (double)(n) / (double)(N - 1);  
145 - out.Begin(OBJ_FACE); //start a face (quad)  
146 - out.TexCoord(u0, v0);  
147 - out.Vertex(p0[n - 1][0], p0[n - 1][1], p0[n - 1][2]); //output the points composing a strip of quads wrapping the cylinder segment  
148 - out.TexCoord(u1, v0);  
149 - out.Vertex(p1[n - 1][0], p1[n - 1][1], p1[n - 1][2]);  
150 -  
151 - out.TexCoord(u0, v1);  
152 - out.Vertex(p1[n][0], p1[n][1], p1[n][2]);  
153 - out.TexCoord(u1, v1);  
154 - out.Vertex(p0[n][0], p0[n][1], p0[n][2]);  
155 - out.End();  
156 - }  
157 - v0 = (double)(N - 2) / (double)(N - 1); //v texture coordinate runs around the cylinder  
158 - v1 = 1.0;  
159 - out.Begin(OBJ_FACE);  
160 - out.TexCoord(u0, v0);  
161 - out.Vertex(p0[N - 1][0], p0[N - 1][1], p0[N - 1][2]); //output the points composing a strip of quads wrapping the cylinder segment  
162 - out.TexCoord(u1, v0);  
163 - out.Vertex(p1[N - 1][0], p1[N - 1][1], p1[N - 1][2]);  
164 -  
165 - out.TexCoord(u0, v1);  
166 - out.Vertex(p1[0][0], p1[0][1], p1[0][2]);  
167 - out.TexCoord(u1, v1);  
168 - out.Vertex(p0[0][0], p0[0][1], p0[0][2]);  
169 - out.End();  
170 - }  
171 - return out;  
172 - }  
173 -  
174 - std::string str() {  
175 - std::stringstream ss;  
176 - size_t N = std::vector< stim::vec3<T> >::size();  
177 - ss << "---------[" << N << "]---------" << std::endl;  
178 - for (size_t i = 0; i < N; i++)  
179 - ss << std::vector< stim::vec3<T> >::at(i) << " r = " << R[i] << " u = " << U[i] << std::endl;  
180 - ss << "--------------------" << std::endl;  
181 -  
182 - return ss.str();  
183 - }  
184 -  
185 - /// Integrates a magnitude value along the cylinder.  
186 - /// @param m is the magnitude value to be integrated (this is usually the radius)  
187 - T integrate() {  
188 - T sum = 0; //initialize the integral to zero  
189 - if (L.size() == 1)  
190 - return sum;  
191 - else {  
192 - T m0, m1; //allocate space for both magnitudes in a single segment  
193 - m0 = R[0]; //initialize the first point and magnitude to the first point in the cylinder  
194 - T len = L[1]; //allocate space for the segment length  
195 26
  27 + using stim::centerline<T>::c;
  28 + using stim::centerline<T>::N;
  29 +
  30 + ///default init
  31 + void
  32 + init()
  33 + {
196 34
197 - for (unsigned p = 1; p < size(); p++) { //for every consecutive point in the cylinder  
198 - m1 = R[p];  
199 - if (p > 1) len = (L[p] - L[p - 1]); //calculate the segment length using the L array  
200 - sum += (m0 + m1) / (T)2.0 * len; //add the average magnitude, weighted by the segment length  
201 - m0 = m1; //move to the next segment by shifting points  
202 - }  
203 - return sum; //return the integral  
204 - }  
205 - }  
206 -  
207 - /// Resamples the cylinder to provide a maximum distance of "spacing" between centerline points. All current  
208 - /// centerline points are guaranteed to exist in the new cylinder  
209 - /// @param spacing is the maximum spacing allowed between sample points  
210 - cylinder<T> resample(T spacing) {  
211 - cylinder<T> c = stim::centerline<T>::resample(spacing); //resample the centerline and use it to create a new cylinder  
212 -  
213 - //size_t nm = nmags(); //get the number of magnitude values in the current cylinder  
214 - //if (nm > 0) { //if there are magnitude values  
215 - // std::vector<T> magvec(nm, 0); //create a magnitude vector for a single point  
216 - // c.M.resize(c.size(), magvec); //allocate space for a magnitude vector at each point of the new cylinder  
217 - //}  
218 -  
219 - T l, t;  
220 - for (size_t i = 0; i < c.size(); i++) { //for each point in the new cylinder  
221 - l = c.L[i]; //get the length along the new cylinder  
222 - t = l / length(); //calculate the parameter value along the new cylinder  
223 - //for (size_t mag = 0; mag < nm; mag++) { //for each magnitude value  
224 - c.R[i] = r(t); //retrieve the interpolated magnitude from the current cylinder and store it in the new one  
225 - //}  
226 - }  
227 - return c;  
228 - }  
229 -  
230 - std::vector< stim::cylinder<T> > split(unsigned int idx) {  
231 -  
232 - unsigned N = size();  
233 - std::vector< stim::centerline<T> > LL;  
234 - LL.resize(2);  
235 - LL = (*this).centerline<T>::split(idx);  
236 - std::vector< stim::cylinder<T> > C(LL.size());  
237 - unsigned i = 0;  
238 - C[0] = LL[0];  
239 - //C[0].R.resize(idx);  
240 - for (; i < idx + 1; i++) {  
241 - //for(unsigned d = 0; d < 3; d++)  
242 - //C[0][i][d] = LL[0].c[i][d];  
243 - C[0].R[i] = R[i];  
244 - //C[0].R[i].resize(1);  
245 - }  
246 - if (C.size() == 2) {  
247 - C[1] = LL[1];  
248 - i--;  
249 - //C[1].M.resize(N - idx);  
250 - for (; i < N; i++) {  
251 - //for(unsigned d = 0; d < 3; d++)  
252 - //C[1][i - idx][d] = LL[1].c[i - idx][d];  
253 - C[1].R[i - idx] = R[i];  
254 - //C[1].M[i - idx].resize(1);  
255 - }  
256 } 35 }
257 36
258 - return C;  
259 - }  
260 - 37 + ///Calculate the physical length of the fiber at each point in the fiber.
  38 + void
  39 + calculateL()
  40 + {
  41 +/* L.resize(inP.size());
  42 + T temp = (T)0;
  43 + L[0] = 0;
  44 + for(size_t i = 1; i < L.size(); i++)
  45 + {
  46 + temp += (inP[i-1] - inP[i]).len();
  47 + L[i] = temp;
  48 + }
  49 +*/ }
261 50
262 - /*  
263 - ///inits the cylinder from a list of points (std::vector of stim::vec3 --inP) and magnitudes (inM) 51 + ///inits the cylinder from a list of points (std::vector of stim::vec3 --inP) and radii (inM)
264 void 52 void
265 - init(centerline inP, std::vector< std::vector<T> > inM) {  
266 - M = inM; //the magnitude vector can be copied directly  
267 - (*this) = inP; //the centerline can be copied to this class directly 53 + init(std::vector<stim::vec3<T> > inP, std::vector<stim::vec<T> > inM)
  54 + {
  55 + mags = inM;
268 stim::vec3<float> v1; 56 stim::vec3<float> v1;
269 stim::vec3<float> v2; 57 stim::vec3<float> v2;
270 e.resize(inP.size()); 58 e.resize(inP.size());
@@ -286,7 +74,7 @@ public: @@ -286,7 +74,7 @@ public:
286 } 74 }
287 75
288 stim::vec3<T> dr = (inP[1] - inP[0]).norm(); 76 stim::vec3<T> dr = (inP[1] - inP[0]).norm();
289 - s = stim::circle<T>(inP[0], inR[0][0], dr, stim::vec3<T>(1,0,0)); 77 + s = stim::circle<T>(inP[0], inM[0][0], dr, stim::vec3<T>(1,0,0));
290 norms[0] = s.N; 78 norms[0] = s.N;
291 e[0] = s; 79 e[0] = s;
292 Us[0] = e[0].U; 80 Us[0] = e[0].U;
@@ -300,7 +88,7 @@ public: @@ -300,7 +88,7 @@ public:
300 88
301 norms[i] = s.N; 89 norms[i] = s.N;
302 90
303 - s.scale(inR[i][0]/inR[i-1][0]); 91 + s.scale(inM[i][0]/inM[i-1][0]);
304 e[i] = s; 92 e[i] = s;
305 Us[i] = e[i].U; 93 Us[i] = e[i].U;
306 } 94 }
@@ -312,7 +100,7 @@ public: @@ -312,7 +100,7 @@ public:
312 100
313 norms[j] = s.N; 101 norms[j] = s.N;
314 102
315 - s.scale(inR[j][0]/inR[j-1][0]); 103 + s.scale(inM[j][0]/inM[j-1][0]);
316 e[j] = s; 104 e[j] = s;
317 Us[j] = e[j].U; 105 Us[j] = e[j].U;
318 } 106 }
@@ -439,7 +227,7 @@ public: @@ -439,7 +227,7 @@ public:
439 stim::vec<T> zero(0.0,0.0); 227 stim::vec<T> zero(0.0,0.0);
440 temp.resize(inM.size(), zero); 228 temp.resize(inM.size(), zero);
441 for(int i = 0; i < inM.size(); i++) 229 for(int i = 0; i < inM.size(); i++)
442 - temp[i][0] = inR[i]; 230 + temp[i][0] = inM[i];
443 init(inP, temp); 231 init(inP, temp);
444 } 232 }
445 233
@@ -458,18 +246,13 @@ public: @@ -458,18 +246,13 @@ public:
458 init(inP, inM); 246 init(inP, inM);
459 } 247 }
460 248
461 - //assignment operator creates a cylinder from a centerline (default radius is zero)  
462 - cylinder& operator=(stim::centerline<T> c) {  
463 - init(c);  
464 - }  
465 -  
466 ///Returns the number of points on the cylinder centerline 249 ///Returns the number of points on the cylinder centerline
467 250
468 unsigned int size(){ 251 unsigned int size(){
469 return N; 252 return N;
470 } 253 }
471 254
472 - 255 +
473 ///Returns a position vector at the given p-value (p value ranges from 0 to 1). 256 ///Returns a position vector at the given p-value (p value ranges from 0 to 1).
474 ///interpolates the position along the line. 257 ///interpolates the position along the line.
475 ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1). 258 ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1).
@@ -483,7 +266,22 @@ public: @@ -483,7 +266,22 @@ public:
483 T l = pvalue*L[L.size()-1]; 266 T l = pvalue*L[L.size()-1];
484 int idx = findIdx(l); 267 int idx = findIdx(l);
485 return (p(l,idx)); 268 return (p(l,idx));
486 - } 269 +/* T rat = (l-L[idx])/(L[idx+1]-L[idx]);
  270 + stim::vec3<T> v1(
  271 + c[idx][0],
  272 + c[idx][1],
  273 + c[idx][2]
  274 + );
  275 +
  276 + stim::vec3<T> v2(
  277 + c[idx+1][0],
  278 + c[idx+1][1],
  279 + c[idx+1][2]
  280 + );
  281 +
  282 +// return( e[idx].P + (e[idx+1].P-e[idx].P)*rat);
  283 + return( v1 + (v2 - v1)*rat);
  284 +*/ }
487 285
488 ///Returns a position vector at the given length into the fiber (based on the pvalue). 286 ///Returns a position vector at the given length into the fiber (based on the pvalue).
489 ///Interpolates the radius along the line. 287 ///Interpolates the radius along the line.
@@ -523,7 +321,10 @@ public: @@ -523,7 +321,10 @@ public:
523 T l = pvalue*L[L.size()-1]; 321 T l = pvalue*L[L.size()-1];
524 int idx = findIdx(l); 322 int idx = findIdx(l);
525 return (r(l,idx)); 323 return (r(l,idx));
526 - } 324 +/* T rat = (l-L[idx])/(L[idx+1]-L[idx]);
  325 +// return (mags[idx][0] + (mags[idx+1][0]-mags[idx][0])*rat);
  326 + return (e[idx].U.len() + (e[idx+1].U.len() - e[idx].U.len())*rat);
  327 +*/ }
527 328
528 ///Returns a radius at the given length into the fiber (based on the pvalue). 329 ///Returns a radius at the given length into the fiber (based on the pvalue).
529 ///Interpolates the position along the line. 330 ///Interpolates the position along the line.
@@ -705,10 +506,10 @@ public: @@ -705,10 +506,10 @@ public:
705 506
706 return cylinder<T>(result); 507 return cylinder<T>(result);
707 508
708 - }*/ 509 + }
709 510
710 511
711 }; 512 };
712 513
713 } 514 }
714 -#endif  
715 \ No newline at end of file 515 \ No newline at end of file
  516 +#endif
stim/visualization/gl_spharmonics.h
@@ -51,6 +51,13 @@ namespace stim { @@ -51,6 +51,13 @@ namespace stim {
51 magnitude = true; 51 magnitude = true;
52 } 52 }
53 53
  54 + gl_spharmonics(stim::spharmonics<T> disp, stim::spharmonics<T> color, size_t slices) :
  55 + gl_spharmonics<T>(slices)
  56 + {
  57 + Sc = color;
  58 + Sd = disp;
  59 + }
  60 +
54 ~gl_spharmonics() { 61 ~gl_spharmonics() {
55 if (dlist) glDeleteLists(dlist, 1); //delete the display list when the object is destroyed 62 if (dlist) glDeleteLists(dlist, 1); //delete the display list when the object is destroyed
56 } 63 }
@@ -166,13 +173,13 @@ namespace stim { @@ -166,13 +173,13 @@ namespace stim {
166 } 173 }
167 174
168 /// Project a set of samples onto the basis 175 /// Project a set of samples onto the basis
169 - void project(std::vector<vec3<float>>& vlist, size_t nc) { 176 + void project(std::vector<vec3<float> >& vlist, size_t nc) {
170 Sd.project(vlist, nc); 177 Sd.project(vlist, nc);
171 Sc = Sd; 178 Sc = Sd;
172 } 179 }
173 180
174 /// Calculate a density function from a list of points in spherical coordinates 181 /// Calculate a density function from a list of points in spherical coordinates
175 - void pdf(std::vector<stim::vec3<T>>& vlist, size_t nc) { 182 + void pdf(std::vector<stim::vec3<T> >& vlist, size_t nc) {
176 Sd.pdf(vlist, nc); 183 Sd.pdf(vlist, nc);
177 Sc = Sd; 184 Sc = Sd;
178 } 185 }
@@ -196,4 +203,4 @@ namespace stim { @@ -196,4 +203,4 @@ namespace stim {
196 203
197 204
198 205
199 -#endif  
200 \ No newline at end of file 206 \ No newline at end of file
  207 +#endif