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 3  
4 4 #include <vector>
5 5 #include <stim/math/vec3.h>
  6 +//#include <ANN/ANN.h>
6 7  
7 8 namespace stim{
8 9  
... ... @@ -11,134 +12,195 @@ namespace stim{
11 12 * class to describe an interconnected (often biological) network.
12 13 */
13 14 template<typename T>
14   -class centerline : public std::vector< stim::vec3<T> >{
  15 +class centerline{
15 16  
16 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 90 /// Returns a stim::vec representing the point at index i
54 91  
55 92 /// @param i is an index of the desired centerline point
56 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 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 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 200 /// Split the fiber at the specified index. If the index is an end point, only one fiber is returned
138 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 205 //if the index is an end point, only the existing fiber is returned
144 206 if(idx == 0 || idx == N-1){
... ... @@ -154,84 +216,123 @@ public:
154 216  
155 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 222 //copy both halves of the fiber
161   - unsigned int i;
  223 + unsigned int i, d;
162 224  
163 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 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 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 261 /// Outputs the fiber as a string
179 262 std::string str(){
180 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 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 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 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 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 180 #endif
181 181  
182 182  
  183 +// stim::cuda::gpu_local_max<float>(centers, res, conn, DIM_X, DIM_Y);
183 184 stim::cuda::gpu_local_max<float>(centers, res, threshold, conn, DIM_X, DIM_Y);
184 185  
185 186 cudaDeviceSynchronize();
... ...
stim/cuda/ivote/local_max.cuh
... ... @@ -10,24 +10,24 @@ namespace stim{
10 10  
11 11 // this kernel calculates the local maximum for finding the cell centers
12 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 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 19 if(xi >= x || yi >= y)
20 20 return;
21 21  
22 22 // convert 2D coordinates to 1D
23   - size_t i = yi * x + xi;
  23 + int i = yi * x + xi;
24 24  
25 25 gpuCenters[i] = 0; //initialize the value at this location to zero
26 26  
27 27 T val = gpuVote[i];
28 28  
29 29 //compare to the threshold
30   - //if(val < final_t) return;
  30 + if(val < final_t) return;
31 31  
32 32 //define an array to store indices with same vote value
33 33 /*int * IdxEq;
... ... @@ -56,25 +56,24 @@ namespace stim{
56 56 return;
57 57 }
58 58 } */
59   - //gpuCenters[i] = 1;
60   - gpuCenters[i] = gpuVote[i];
  59 + gpuCenters[i] = 1;
61 60 }
62 61  
63 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 65 unsigned int max_threads = stim::maxThreadsPerBlock();
67 66 /*dim3 threads(max_threads, 1);
68 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 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 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 78 //calculate the number of bytes in the array
80 79 unsigned int bytes = x * y * sizeof(T);
... ... @@ -91,7 +90,7 @@ namespace stim{
91 90 HANDLE_ERROR(cudaMemcpy(gpuVote, cpuVote, bytes, cudaMemcpyHostToDevice));
92 91  
93 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 95 //copy the cell centers data to the CPU
97 96 cudaMemcpy(cpuCenters, gpuCenters, bytes, cudaMemcpyDeviceToHost) ;
... ...
stim/gl/gl_spider.h
... ... @@ -2,33 +2,47 @@
2 2 #define STIM_GL_SPIDER_H
3 3  
4 4 //#include <GL/glew.h>
  5 +///basic GL and Cuda libs
5 6 #include <GL/glut.h>
6 7 #include <cuda.h>
7 8 #include <cuda_gl_interop.h>
8 9 #include <cudaGL.h>
9   -#include <math.h>
  10 +
  11 +///stim .*h for gl tracking and visualization
10 12 #include <stim/gl/gl_texture.h>
11   -#include <stim/visualization/camera.h>
12 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 31 #include <stim/math/vector.h>
14 32 #include <stim/math/vec3.h>
15 33 #include <stim/math/rect.h>
16   -#include <stim/math/matrix.h>
17 34 #include <stim/math/constants.h>
18   -#include <stim/cuda/spider_cost.cuh>
19   -#include <stim/cuda/cudatools/glbind.h>
20 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 40 #include <vector>
26 41 #include <stack>
27   -#include <stim/cuda/branch_detection.cuh>
28   -#include "../../../volume-spider/glnetwork.h"
29   -#include <stim/visualization/cylinder.h>
30 42 #include <iostream>
31 43 #include <fstream>
  44 +
  45 +///Timing and debugging
32 46 #ifdef TIMING
33 47 #include <ctime>
34 48 #include <cstdio>
... ... @@ -39,6 +53,7 @@
39 53 #include <ctime>
40 54 #endif
41 55  
  56 +// #include <stim/cuda/testKernel.cuh>
42 57 #ifdef DEBUG
43 58 #include <stim/cuda/testKernel.cuh>
44 59 #endif
... ... @@ -61,6 +76,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
61 76 double cost_time;// = 0;
62 77 double network_time;// = 0;
63 78 double hit_time;// = 0;
  79 + int iter_t;
64 80 #endif
65 81  
66 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 88 std::vector<float> mV; //A list of all the size vectors.
73 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 92 GLuint texID; //OpenGL ID for the texture to be traced
77 93 stim::vec3<float> S; //Size of a voxel in the volume.
78 94 stim::vec3<float> R; //Dimensions of the volume.
... ... @@ -339,31 +355,6 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
339 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 360 //---------------------TEMPLATE CREATION METHODS----------------------------//
... ... @@ -400,8 +391,8 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
400 391 glNewList(dList, GL_COMPILE); ///create a display list of all the direction templates.
401 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 396 phi = acos(z); ///generate a phi from the z.
406 397 stim::vec3<float> sph(1, theta, phi); ///combine into a vector in spherical coordinates.
407 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 451 UpdateBuffer(0.0, 0.0+0*n_pixels);
461 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 455 temp[0] = temp[0]*delta;
465 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 944 cost_time = 0;
954 945 network_time = 0;
955 946 hit_time = 0;
  947 + iter_t = 0;
956 948 #endif
957 949 #ifdef DEBUG
958 950 iter = 0;
... ... @@ -960,7 +952,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
960 952 iter_dir = 0;
961 953 iter_siz = 0;
962 954 #endif
963   - stepsize = 6.0;
  955 + stepsize = 3.0;
964 956 n_pixels = 16.0;
965 957  
966 958 srand(100);
... ... @@ -1274,12 +1266,19 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1274 1266 {
1275 1267 std::vector <double> ret;
1276 1268 ret.resize(7);
  1269 + // ret[0] = branch_time/(float)iter;
1277 1270 ret[0] = branch_time;
  1271 + // ret[1] = direction_time/(float)iter;
1278 1272 ret[1] = direction_time;
  1273 + // ret[2] = position_time/(float)iter;
1279 1274 ret[2] = position_time;
  1275 + // ret[3] = size_time/(float)iter;
1280 1276 ret[3] = size_time;
  1277 + // ret[4] = cost_time/(float)iter;
1281 1278 ret[4] = cost_time;
  1279 + // ret[5] = network_time/(float)iter;
1282 1280 ret[5] = network_time;
  1281 + // ret[6] = hit_time/(float)iter;
1283 1282 ret[6] = hit_time;
1284 1283  
1285 1284 return ret;
... ... @@ -1311,6 +1310,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1311 1310 setSeed(x, y, z);
1312 1311 setSeedVec(u, v, w);
1313 1312 setSeedMag(m);
  1313 + std::cout << getLastSeed() << getLastSeedVec() << std::cout;
1314 1314 }
1315 1315 myfile.close();
1316 1316 } else {
... ... @@ -1320,7 +1320,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1320 1320  
1321 1321 ///Saves the network to a file.
1322 1322 void
1323   - saveNetwork(std::string name)
  1323 + saveNetwork(std::string name, int xoffset = 0, int yoffset = 0, int zoffset = 0)
1324 1324 {
1325 1325 stim::glObj<float> sk1;
1326 1326 for(int i = 0; i < nt.sizeE(); i++)
... ... @@ -1331,7 +1331,7 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1331 1331 for(int j = 0; j < ce.size(); j++)
1332 1332 {
1333 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 1336 sk1.End();
1337 1337 }
... ... @@ -1408,6 +1408,11 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1408 1408 #ifdef DEBUG
1409 1409 std::cerr << std::endl;
1410 1410 #endif
  1411 +
  1412 + #ifdef TIMING
  1413 + iter_t++;
  1414 + #endif
  1415 +
1411 1416 return current_cost;
1412 1417 }
1413 1418  
... ... @@ -1422,36 +1427,6 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1422 1427 //--------------------------------------------------------------------------//
1423 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 1431 void
1457 1432 DrawCylinder()
... ... @@ -1570,9 +1545,6 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1570 1545 {
1571 1546 //Define the varibles and turn on Selection Mode
1572 1547  
1573   - #ifdef TIMING
1574   - gpuStartTimer();
1575   - #endif
1576 1548  
1577 1549 GLuint selectBuf[2048]; ///size of the selection buffer in bytes.
1578 1550 GLint hits; ///hit fibers
... ... @@ -1602,6 +1574,9 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1602 1574 glPushMatrix();
1603 1575 glLoadIdentity();
1604 1576  
  1577 + #ifdef TIMING
  1578 + gpuStartTimer();
  1579 + #endif
1605 1580 CHECK_OPENGL_ERROR
1606 1581 gluLookAt(ps[0], ps[1], ps[2],
1607 1582 ds[0], ds[1], ds[2],
... ... @@ -1849,6 +1824,65 @@ class gl_spider // : public virtual gl_texture&lt;T&gt;
1849 1824 std::cout << "I broke out!" << std::endl;
1850 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 1888 #endif
... ...
stim/image/bmp.h
... ... @@ -187,7 +187,7 @@ namespace stim {
187 187 }
188 188  
189 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 191 if (!file) {
192 192 std::cout << "stim::bmp ERROR: error opening file: " << filename.c_str() << std::endl;
193 193 return false;
... ... @@ -246,7 +246,7 @@ namespace stim {
246 246 info_header.bcSize = sizeof(tagBITMAPCOREHEADER);
247 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 250 outfile.write((char*)&file_header, sizeof(tagBITMAPFILEHEADER)); //write the file header
251 251 outfile.write((char*)&info_header, sizeof(tagBITMAPCOREHEADER)); //write the information header
252 252  
... ... @@ -259,4 +259,4 @@ namespace stim {
259 259 free(pad);
260 260 return true;
261 261 }
262   -}
263 262 \ No newline at end of file
  263 +}
... ...
stim/image/image.h
... ... @@ -606,7 +606,7 @@ public:
606 606  
607 607 //crop regions given by an array of 1D index values
608 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 610 for (size_t i = 0; i < idx.size(); i++) { //for each specified index point
611 611 size_t y = idx[i] / X(); //calculate the y coordinate from the 1D index (center of ROI)
612 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 18  
19 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 24 init()
26 25 {
27 26 Y = U.cross(N).norm();
28   - }*/
  27 + }
29 28  
30 29 public:
31 30 using stim::plane<T>::n;
... ... @@ -35,8 +34,6 @@ public:
35 34 using stim::plane<T>::rotate;
36 35 using stim::plane<T>::setU;
37 36  
38   - using stim::plane<T>::init;
39   -
40 37 ///base constructor
41 38 ///@param th value of the angle of the starting point from 0 to 360.
42 39 CUDA_CALLABLE
... ... @@ -45,28 +42,26 @@ public:
45 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 46 ///@param size: size of the rectangle in ND space.
50 47 ///@param z_pos z coordinate of the rectangle.
51 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 56 ///create a rectangle from a center point, normal
61 57 ///@param c: x,y,z location of the center.
62 58 ///@param n: x,y,z direction of the normal.
63 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 67 /*///create a rectangle from a center point, normal, and size
... ... @@ -89,18 +84,14 @@ public:
89 84 ///@param n: x,y,z direction of the normal.
90 85 ///@param u: x,y,z direction for the zero vector (from where the rotation starts)
91 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 90 setU(u);
97   - R = r;
98   - //init();
99   - //setU(u);
100 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 97 ///scales the circle by a certain factor
... ... @@ -108,111 +99,86 @@ public:
108 99 CUDA_CALLABLE
109 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 106 ///sets the normal for the cirlce
125 107 ///@param n: x,y,z direction of the normal.
126 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 114 ///sets the center of the circle.
132 115 ///@param n: x,y,z location of the center.
133 116 CUDA_CALLABLE void
134 117 center(vec3<T> p){
135   - P = p;
  118 + this->P = p;
136 119 }
137 120  
138 121 ///boolean comparison
139 122 bool
140 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 126 return true;
144 127 else
145 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 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 134 stim::vec3<T> result;
170 135  
171 136 vec3<T> A = this->P - this->U * (T)0.5 - Y * (T)0.5;
172 137 result = A + this->U * a + Y * b;
173 138 return result;
174   - }*/
  139 + }
175 140  
176 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 147 ///returns a vector with the points on the initialized circle.
188 148 ///connecting the points results in a circle.
189 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 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 178 std::string str() const
213 179 {
214 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 182 return ss.str();
217 183 }
218 184  
... ...
stim/math/random.h
... ... @@ -17,7 +17,7 @@ protected:
17 17 if(seed <= 0)
18 18 srand(time(NULL));
19 19 else if(seed > 0)
20   - srand(time(seed));
  20 + srand(seed);
21 21 else
22 22 std::cout << "Error: Unknown value: in STIM::RANDOM" << std::endl;
23 23 }
... ...
stim/math/spharmonics.h
... ... @@ -181,7 +181,7 @@ namespace stim {
181 181 /// @param n is the number of points of the surface of the sphere used to create the PDF. DEFAULT 1000
182 182 /// @param norm, a boolean that sets where the output vectors will be normalized between 0 and 1.
183 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 186 std::vector<double> weights; ///the weight at each point on the surface of the sphere.
187 187 // weights.resize(n);
... ... @@ -223,7 +223,7 @@ namespace stim {
223 223 }
224 224 }
225 225 mcEnd();
226   - }*/
  226 + }
227 227  
228 228 std::string str() {
229 229  
... ... @@ -313,6 +313,52 @@ namespace stim {
313 313 T operator()(T theta, T phi) {
314 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 362 /// Fill an NxN grid with the spherical function for theta = [0 2pi] and phi = [0 pi]
317 363 void get_func(T* data, size_t X, size_t Y) {
318 364 T dt = stim::TAU / (T)X; //calculate the step size in each direction
... ... @@ -351,4 +397,4 @@ namespace stim {
351 397 }
352 398  
353 399  
354   -#endif
355 400 \ No newline at end of file
  401 +#endif
... ...
stim/visualization/cylinder.h
... ... @@ -3,268 +3,56 @@
3 3 #include <iostream>
4 4 #include <stim/math/circle.h>
5 5 #include <stim/biomodels/centerline.h>
6   -#include <stim/visualization/obj.h>
7 6  
  7 +/*
  8 +
  9 +*/
8 10  
9 11 namespace stim
10 12 {
11 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 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 56 stim::vec3<float> v1;
269 57 stim::vec3<float> v2;
270 58 e.resize(inP.size());
... ... @@ -286,7 +74,7 @@ public:
286 74 }
287 75  
288 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 78 norms[0] = s.N;
291 79 e[0] = s;
292 80 Us[0] = e[0].U;
... ... @@ -300,7 +88,7 @@ public:
300 88  
301 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 92 e[i] = s;
305 93 Us[i] = e[i].U;
306 94 }
... ... @@ -312,7 +100,7 @@ public:
312 100  
313 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 104 e[j] = s;
317 105 Us[j] = e[j].U;
318 106 }
... ... @@ -439,7 +227,7 @@ public:
439 227 stim::vec<T> zero(0.0,0.0);
440 228 temp.resize(inM.size(), zero);
441 229 for(int i = 0; i < inM.size(); i++)
442   - temp[i][0] = inR[i];
  230 + temp[i][0] = inM[i];
443 231 init(inP, temp);
444 232 }
445 233  
... ... @@ -458,18 +246,13 @@ public:
458 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 249 ///Returns the number of points on the cylinder centerline
467 250  
468 251 unsigned int size(){
469 252 return N;
470 253 }
471 254  
472   -
  255 +
473 256 ///Returns a position vector at the given p-value (p value ranges from 0 to 1).
474 257 ///interpolates the position along the line.
475 258 ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1).
... ... @@ -483,7 +266,22 @@ public:
483 266 T l = pvalue*L[L.size()-1];
484 267 int idx = findIdx(l);
485 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 286 ///Returns a position vector at the given length into the fiber (based on the pvalue).
489 287 ///Interpolates the radius along the line.
... ... @@ -523,7 +321,10 @@ public:
523 321 T l = pvalue*L[L.size()-1];
524 322 int idx = findIdx(l);
525 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 329 ///Returns a radius at the given length into the fiber (based on the pvalue).
529 330 ///Interpolates the position along the line.
... ... @@ -705,10 +506,10 @@ public:
705 506  
706 507 return cylinder<T>(result);
707 508  
708   - }*/
  509 + }
709 510  
710 511  
711 512 };
712 513  
713 514 }
714   -#endif
715 515 \ No newline at end of file
  516 +#endif
... ...
stim/visualization/gl_spharmonics.h
... ... @@ -51,6 +51,13 @@ namespace stim {
51 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 61 ~gl_spharmonics() {
55 62 if (dlist) glDeleteLists(dlist, 1); //delete the display list when the object is destroyed
56 63 }
... ... @@ -166,13 +173,13 @@ namespace stim {
166 173 }
167 174  
168 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 177 Sd.project(vlist, nc);
171 178 Sc = Sd;
172 179 }
173 180  
174 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 183 Sd.pdf(vlist, nc);
177 184 Sc = Sd;
178 185 }
... ... @@ -196,4 +203,4 @@ namespace stim {
196 203  
197 204  
198 205  
199   -#endif
200 206 \ No newline at end of file
  207 +#endif
... ...