Commit e344902927a5e39225554dee4bb9d07af6709373

Authored by David Mayerich
2 parents a2bf1d08 d4f06a7e

Merge branch 'master' of git.stim.ee.uh.edu:codebase/stimlib

stim/cuda/branch_detection.cuh
@@ -5,167 +5,48 @@ @@ -5,167 +5,48 @@
5 //#include <math.h> 5 //#include <math.h>
6 #include <stim/visualization/colormap.h> 6 #include <stim/visualization/colormap.h>
7 #include <stim/cuda/cuda_texture.cuh> 7 #include <stim/cuda/cuda_texture.cuh>
8 -#include <stim/cuda/templates/gradient.cuh>  
9 -#include <stim/cuda/templates/gaussian_blur.cuh>  
10 -#include <stim/cuda/arraymath.cuh>  
11 -#include <stim/cuda/ivote.cuh>  
12 -#include <stim/cuda/testKernel.cuh> 8 +#include <stim/cuda/filter.cuh>
13 typedef unsigned int uint; 9 typedef unsigned int uint;
14 typedef unsigned int uchar; 10 typedef unsigned int uchar;
15 11
16 -stim::cuda::cuda_texture t;  
17 -float* gpuTable;  
18 -float* gpuGrad;  
19 -float* gpuVote;  
20 -float* gpuI;  
21 -float* gpuCenters;  
22 -  
23 -void atan_2d(float* cpuTable, unsigned int rmax)  
24 -{  
25 - //initialize the width and height of the window which atan2 are computed in.  
26 - int xsize = 2*rmax +1;  
27 - int ysize = 2*rmax +1;  
28 -  
29 - // assign the center coordinates of the atan2 window to yi and xi  
30 - int yi = rmax;  
31 - int xi = rmax;  
32 -  
33 -  
34 - for (int xt = 0; xt < xsize; xt++){  
35 -  
36 - for(int yt = 0; yt < ysize; yt++){  
37 -  
38 - //convert the current 2D coordinates to 1D  
39 - int id = yt * xsize + xt;  
40 - // calculate the distance between the pixel and the center of the atan2 window  
41 - float xd = xi - xt;  
42 - float yd = yi - yt;  
43 -  
44 - // calculate the angle between the pixel and the center of the atan2 window and store the result.  
45 - float atan_2d_vote = atan2(yd, xd);  
46 - cpuTable[id] = atan_2d_vote;  
47 - }  
48 - }  
49 -  
50 -}  
51 -  
52 -void initCuda(unsigned int bytes_table, unsigned int bytes_ds)  
53 -{  
54 - HANDLE_ERROR(  
55 - cudaMalloc((void**) &gpuTable, bytes_table)  
56 - );  
57 - HANDLE_ERROR(  
58 - cudaMalloc((void**) &gpuI, bytes_ds)  
59 - );  
60 - HANDLE_ERROR(  
61 - cudaMalloc((void**) &gpuGrad, bytes_ds*2)  
62 - );  
63 - HANDLE_ERROR(  
64 - cudaMalloc((void**) &gpuVote, bytes_ds)  
65 - );  
66 - HANDLE_ERROR(  
67 - cudaMalloc((void**) &gpuCenters, bytes_ds)  
68 - );  
69 -}  
70 -  
71 -void cleanCuda()  
72 -{  
73 - HANDLE_ERROR(  
74 - cudaFree(gpuTable)  
75 - );  
76 - HANDLE_ERROR(  
77 - cudaFree(gpuGrad)  
78 - );  
79 - HANDLE_ERROR(  
80 - cudaFree(gpuVote)  
81 - );  
82 - HANDLE_ERROR(  
83 - cudaFree(gpuCenters)  
84 - );  
85 - HANDLE_ERROR(  
86 - cudaFree(gpuI)  
87 - );  
88 -}  
89 12
90 std::vector< stim::vec<float> > 13 std::vector< stim::vec<float> >
91 find_branch(GLint texbufferID, GLenum texType, unsigned int x, unsigned int y) 14 find_branch(GLint texbufferID, GLenum texType, unsigned int x, unsigned int y)
92 { 15 {
93 - float phi = 15.1*M_PI/180;  
94 - int iter = 5;  
95 - float dphi = phi/iter;  
96 - float rmax = 10;  
97 - float sigma = 4;  
98 - unsigned int pixels = x * y;  
99 - unsigned int bytes = sizeof(float) * pixels;  
100 - unsigned int bytes_table = sizeof(float) * (2*rmax + 1) * (2*rmax + 1);  
101 - unsigned int x_ds = (x + (x % 1 == 0 ? 0:1));  
102 - unsigned int y_ds = (y + (x % 1 == 0 ? 0:1));  
103 - unsigned int bytes_ds = sizeof(float) * x_ds * y_ds;  
104 - unsigned int conn = 5;  
105 - float final_t = 200.0;  
106 - float* cpuTable = (float*) malloc(bytes_table);  
107 - float* cpuCenters = (float*) malloc(bytes_ds); 16 + float sigma = 2.0;
  17 + unsigned int conn = 7;
  18 + float threshold = 40.0;
  19 + float* cpuCenters = (float*) malloc(x*y*sizeof(float));
  20 + int sizek = 7;
108 21
109 stringstream name; 22 stringstream name;
110 23
111 24
112 -  
113 -  
114 - std::vector<stim::vec<float> > output;  
115 - initCuda(bytes_table, bytes_ds);  
116 -  
117 - atan_2d(cpuTable, rmax);  
118 - cudaMemcpy(gpuTable, cpuTable, bytes_table, cudaMemcpyHostToDevice);  
119 -  
120 -  
121 - t.MapCudaTexture(texbufferID, texType);  
122 - cudaDeviceSynchronize();  
123 - stim::cuda::tex_gaussian_blur2<float>(  
124 - gpuI, sigma, x, y, t.getTexture(), t.getArray()  
125 - ); 25 + cpuCenters = stim::cuda::get_centers(texbufferID, texType, x, y, sizek, sigma, conn, threshold);
126 cudaDeviceSynchronize(); 26 cudaDeviceSynchronize();
127 27
128 28
129 - stim::cuda::gpu_gradient_2d<float>(  
130 - gpuGrad, gpuI, x, y  
131 - );  
132 - cudaDeviceSynchronize();  
133 -  
134 - stim::cuda::gpu_cart2polar<float>(gpuGrad, x, y);  
135 - cudaDeviceSynchronize();  
136 29
137 - cudaDeviceSynchronize();  
138 - for (int i = 0; i < iter; i++)  
139 - {  
140 - stim::cuda::gpu_vote<float>(gpuVote, gpuGrad, gpuTable, phi, rmax, x, y);  
141 - cudaDeviceSynchronize();  
142 - stim::cuda::gpu_update_dir<float>(gpuVote, gpuGrad, gpuTable, phi, rmax, x, y);  
143 - cudaDeviceSynchronize();  
144 - phi = phi - dphi;  
145 - } 30 + std::vector<stim::vec<float> > output;
146 31
147 cudaDeviceSynchronize(); 32 cudaDeviceSynchronize();
148 - stim::cuda::gpu_local_max<float>(gpuCenters, gpuVote, final_t, conn, x, y);  
149 - cudaMemcpy(cpuCenters, gpuCenters, bytes_ds, cudaMemcpyDeviceToHost);  
150 - for(int i = 0; i < pixels; i++) 33 +
  34 + for(int i = 0; i < x; i++)
151 { 35 {
152 - int ix = (i % x);  
153 - int iy = (i / x);  
154 - if((cpuCenters[i] == 1) && (ix > 4) && (ix < x-4)) 36 + for(int j = 0; j < y; j++)
155 { 37 {
156 -  
157 - float x_v = (float) ix;  
158 - float y_v = (float) iy;  
159 - output.push_back(stim::vec<float>((x_v/(float)x),  
160 - (y_v/(float)y), 0.0));  
161 -  
162 - } 38 + int idx = x*j+i;
  39 + if(cpuCenters[idx] != 0)
  40 + {
  41 + float x_v = (float) i;
  42 + float y_v = (float) j;
  43 + output.push_back(stim::vec<float>((x_v/(float)x*360.0),
  44 + (y_v), y_v/8));
  45 + }
  46 +
  47 + }
163 } 48 }
164 -  
165 -  
166 - t.UnmapCudaTexture();  
167 - cleanCuda();  
168 - free(cpuTable); 49 +
169 free(cpuCenters); 50 free(cpuCenters);
170 return output; 51 return output;
171 } 52 }
stim/cuda/branch_detection2.cuh deleted
1 -#include <stim/cuda/templates/gaussian_blur.cuh>  
2 -#include <stim/cuda/templates/gradient.cuh>  
3 -#include <stim/cuda/arraymath.cuh>  
4 -#include <stim/cuda/ivote.cuh>  
5 -  
6 -  
7 -  
8 -  
9 -  
10 -  
11 -  
12 -  
13 -  
14 -  
15 -void atan_2(float* cpuTable, unsigned int rmax){  
16 -  
17 - //initialize the width and height of the window which atan2 are computed in.  
18 - int xsize = 2*rmax +1;  
19 - int ysize = 2*rmax +1;  
20 -  
21 - // assign the center coordinates of the atan2 window to yi and xi  
22 - int yi = rmax;  
23 - int xi = rmax;  
24 -  
25 -  
26 - for (int xt = 0; xt < xsize; xt++){  
27 -  
28 - for(int yt = 0; yt < ysize; yt++){  
29 -  
30 - //convert the current 2D coordinates to 1D  
31 - int id = yt * xsize + xt;  
32 - // calculate the distance between the pixel and the center of the atan2 window  
33 - float xd = xi - xt;  
34 - float yd = yi - yt;  
35 -  
36 - // calculate the angle between the pixel and the center of the atan2 window and store the result.  
37 - float atan_2d_vote = atan2(yd, xd);  
38 - cpuTable[id] = atan_2d_vote;  
39 - }  
40 - }  
41 -  
42 -}  
43 -std::vector<stim::vec<float> >  
44 -find_branch(GLint texbufferID, GLenum texType, unsigned int x, unsigned int y)  
45 -{  
46 -  
47 - float* cpuTable = (float  
48 -  
49 - unsigned int pixels = x * y;  
50 - unsigned int bytes = sizeof(float) * pixels;  
51 -  
52 - //calculate the number of bytes in the atan2 table  
53 -  
54 - unsigned int bytes_table = (2*rmax+1) * (2*rmax+1) * sizeof(float);  
55 -  
56 -  
57 -  
58 - //allocate space on the GPU for the atan2 table  
59 -  
60 - float* gpuTable;  
61 -  
62 - cudaMalloc(&gpuTable, bytes_table);  
63 -  
64 -  
65 -  
66 - cudaMemcpy(gpuTable, cpuTable, bytes_table, cudaMemcpyHostToDevice);  
67 -  
68 - unsigned int sigma_ds = 1/resize;  
69 - unsigned int x_ds = (x/sigma_ds + (x %sigma_ds == 0 ? 0:1));  
70 - unsigned int y_ds = (y/sigma_ds + (y %sigma_ds == 0 ? 0:1));  
71 - unsigned int bytes_ds = sizeof(float) * x_ds * y_ds;  
72 -  
73 -  
74 - float* gpuI;  
75 - cudaMalloc(&gpuI, bytes_ds);  
76 -  
77 -  
78 - float* gpuGrad;  
79 - cudaMalloc(&gpuGrad, bytes_ds*2);  
80 -  
81 - float* gpuVote;  
82 - cudaMalloc(&gpuVote, bytes_ds);  
83 -  
84 - // allocate space on the GPU for the detected cell centes  
85 -  
86 - float* gpuCenters;  
87 -  
88 - cudaMalloc(&gpuCenters, bytes_ds);  
89 -  
90 -  
91 - stim::cuda::gpu_down_sample<float>(gpuI, gpuI0, resize, x , y);  
92 - cudaMemcpy(cpuResize, gpuI, bytes_ds, cudaMemcpyDeviceToHost);  
93 -  
94 -x = x_ds;  
95 - y = y_ds;  
96 - t = t * resize;  
97 - //sigma = sigma * resize;  
98 -  
99 - cudaDeviceSynchronize();  
100 - stim::cuda::gpu_gaussian_blur2<float>(gpuI,sigma, x, y);  
101 - cudaDeviceSynchronize();  
102 - cudaMemcpy(cpuBlur, gpuI, bytes_ds, cudaMemcpyDeviceToHost);  
103 - cudaDeviceSynchronize();  
104 -  
105 - stim::cuda::gpu_gradient_2d<float>(gpuGrad, gpuI, x, y);  
106 - cudaDeviceSynchronize();  
107 - cudaMemcpy(cpuGradient, gpuGrad, bytes_ds*2, cudaMemcpyDeviceToHost);  
108 -  
109 - stim::cuda::gpu_cart2polar<float>(gpuGrad, x, y);  
110 - cudaDeviceSynchronize();  
111 - cudaMemcpy(cpuCart2Polar, gpuGrad, bytes_ds*2, cudaMemcpyDeviceToHost);  
112 -  
113 -  
114 - //multiply the gradient by a constant and calculate the absolute value (to save an image)  
115 -  
116 - stim::cuda::cpu_multiply<float>(cpuCart2Polar, 40, x * y * 2);  
117 -  
118 - cudaDeviceSynchronize();  
119 -  
120 - stim::cuda::cpu_abs<float>(cpuCart2Polar, x * y * 2);  
121 -  
122 - cudaDeviceSynchronize();  
123 -  
124 -  
125 - for (int i =0; i<iter; i++){  
126 -  
127 - stim::cuda::gpu_vote<float>(gpuVote, gpuGrad, gpuTable, phi, rmax, x, y);  
128 - cudaDeviceSynchronize();  
129 - stim::cuda::gpu_update_dir<float>(gpuVote, gpuGrad, gpuTable, phi, rmax, x, y);  
130 - cudaDeviceSynchronize();  
131 - switch (i){  
132 - case 0 : cudaMemcpy(cpuVote1, gpuVote, bytes_ds, cudaMemcpyDeviceToHost);  
133 - break;  
134 - case 1 : cudaMemcpy(cpuVote2, gpuVote, bytes_ds, cudaMemcpyDeviceToHost);  
135 - break;  
136 - case 2 : cudaMemcpy(cpuVote3, gpuVote, bytes_ds, cudaMemcpyDeviceToHost);  
137 - break;  
138 - case 3 : cudaMemcpy(cpuVote4, gpuVote, bytes_ds, cudaMemcpyDeviceToHost);  
139 - break;  
140 - case 4 : cudaMemcpy(cpuVote5, gpuVote, bytes_ds, cudaMemcpyDeviceToHost);  
141 - break;  
142 - default : cudaMemcpy(cpuVote5, gpuVote, bytes_ds, cudaMemcpyDeviceToHost);  
143 - break;  
144 - }  
145 - phi = phi - dphi;  
146 - }  
147 -  
148 - stim::cuda::gpu_local_max<float>(gpuCenters, gpuVote, t, conn, x, y);  
149 - cudaMemcpy(cpuCenters, gpuCenters, bytes_ds, cudaMemcpyDeviceToHost);  
150 -  
151 -}  
stim/cuda/cuda_texture.cuh
@@ -41,6 +41,46 @@ namespace stim @@ -41,6 +41,46 @@ namespace stim
41 texDesc.normalizedCoords = 0; 41 texDesc.normalizedCoords = 0;
42 } 42 }
43 43
  44 +
  45 + ///Enable the nromalized texture coordinates.
  46 + ///@param bool, 1 for on, 0 for off
  47 + void
  48 + SetTextureCoordinates(bool val)
  49 + {
  50 + if(val)
  51 + texDesc.normalizedCoords = 1;
  52 + else
  53 + texDesc.normalizedCoords = 0;
  54 + }
  55 +
  56 + ///sets the dimension dim to used the mode at the borders of the texture.
  57 + ///@param dim : 0-x, 1-y, 2-z
  58 + ///@param mode: cudaAddressModeWrap = 0,
  59 + /// cudaAddressModeClamp = 1,
  60 + /// cudaAddressMNodeMirror = 2,
  61 + /// cudaAddressModeBorder = 3,
  62 + void
  63 + SetAddressMode(int dim, int mode)
  64 + {
  65 + switch(mode)
  66 + {
  67 + case 0:
  68 + texDesc.addressMode[dim] = cudaAddressModeWrap;
  69 + break;
  70 + case 1:
  71 + texDesc.addressMode[dim] = cudaAddressModeClamp;
  72 + break;
  73 + case 2:
  74 + texDesc.addressMode[dim] = cudaAddressModeMirror;
  75 + break;
  76 + case 3:
  77 + texDesc.addressMode[dim] = cudaAddressModeBorder;
  78 + break;
  79 + default:
  80 + break;
  81 + }
  82 + }
  83 +
44 //-------------------------------------------------------------------------// 84 //-------------------------------------------------------------------------//
45 //-------------------------------CUDA_MAPPING------------------------------// 85 //-------------------------------CUDA_MAPPING------------------------------//
46 //-------------------------------------------------------------------------// 86 //-------------------------------------------------------------------------//
stim/cuda/filter.cuh 0 โ†’ 100644
  1 +#ifndef STIM_FILTER_H
  2 +#define STIM_FILTER_H
  3 +
  4 +#include <assert.h>
  5 +#include <cuda.h>
  6 +#include <cuda_runtime.h>
  7 +#include <stdio.h>
  8 +#include <stim/visualization/colormap.h>
  9 +#include <sstream>
  10 +#include <stim/cuda/cudatools/devices.h>
  11 +#include <stim/cuda/cudatools/threads.h>
  12 +#include <stim/cuda/cuda_texture.cuh>
  13 +#include <stim/cuda/ivote.cuh>
  14 +#include <stim/cuda/arraymath.cuh>
  15 +
  16 +#define IMAD(a,b,c) ( __mul24((a), (b)) + (c) )
  17 +#define M_PI 3.141592654f
  18 +
  19 +
  20 +namespace stim
  21 +{
  22 + namespace cuda
  23 + {
  24 +
  25 + float* gpuLoG;
  26 + float* LoG;
  27 + float* res;
  28 + float* centers;
  29 + stim::cuda::cuda_texture tx;
  30 +
  31 +
  32 +
  33 + void initArray(int DIM_X, int DIM_Y, int kl)
  34 + {
  35 +
  36 + LoG = (float*) malloc(kl*kl*sizeof(float));
  37 + HANDLE_ERROR(
  38 + cudaMalloc( (void**) &gpuLoG, kl*kl*sizeof(float))
  39 + );
  40 + // checkCUDAerrors("Memory Allocation, LoG");
  41 + HANDLE_ERROR(
  42 + cudaMalloc( (void**) &res, DIM_Y*DIM_X*sizeof(float))
  43 + );
  44 + HANDLE_ERROR(
  45 + cudaMalloc( (void**) &centers, DIM_Y*DIM_X*sizeof(float))
  46 + );
  47 + // checkCUDAerrors("Memory Allocation, Result");
  48 + }
  49 +
  50 + void cleanUp(cudaGraphicsResource_t src)
  51 + {
  52 + HANDLE_ERROR(
  53 + cudaFree(gpuLoG)
  54 + );
  55 + HANDLE_ERROR(
  56 + cudaFree(res)
  57 + );
  58 + HANDLE_ERROR(
  59 + cudaFree(centers)
  60 + );
  61 + free(LoG);
  62 + }
  63 +
  64 + void
  65 + filterKernel (float kl, float sigma, float *LoG)
  66 + {
  67 + float t = 0.0;
  68 + float kr = kl/2;
  69 + float x, y;
  70 + int idx;
  71 + for(int i = 0; i < kl; i++){
  72 + for(int j = 0; j < kl; j++){
  73 + idx = j*kl+i;
  74 + x = i - kr - 0.5;
  75 + y = j - kr - 0.5;
  76 + LoG[idx] = (-1.0/M_PI/powf(sigma, 4))* (1 - (powf(x,2)+powf(y,2))/2.0/powf(sigma, 2))
  77 + *expf(-(powf(x,2)+powf(y,2))/2/powf(sigma,2));
  78 + t +=LoG[idx];
  79 + }
  80 + }
  81 +
  82 + for(int i = 0; i < kl*kl; i++)
  83 + {
  84 + LoG[i] = LoG[i]/t;
  85 + }
  86 +
  87 + }
  88 +
  89 + //Shared memory would be better.
  90 + __global__
  91 + void
  92 + applyFilter(cudaTextureObject_t texIn, unsigned int DIM_X, unsigned int DIM_Y, int kr, int kl, float *res, float* gpuLoG){
  93 + //R = floor(size/2)
  94 + //THIS IS A NAIVE WAY TO DO IT, and there is a better way)
  95 +
  96 + __shared__ float shared[7][7];
  97 + int x = blockIdx.x;
  98 + int y = blockIdx.y;
  99 + int xi = threadIdx.x;
  100 + int yi = threadIdx.y;
  101 + float val = 0;
  102 + float tu = (x-kr+xi)/(float)DIM_X;
  103 + float tv = (y-kr+yi)/(float)DIM_Y;
  104 + shared[xi][yi] = gpuLoG[yi*kl+xi]*(255.0-(float)tex2D<unsigned char>(texIn, tu, tv));
  105 + __syncthreads();
  106 +
  107 +
  108 + //x = max(0,x);
  109 + //x = min(x, width-1);
  110 + //y = max(y, 0);
  111 + //y = min(y, height - 1);
  112 +
  113 + int idx = y*DIM_X+x;
  114 + int k_idx;
  115 + for(unsigned int step = blockDim.x/2; step >= 1; step >>= 1)
  116 + {
  117 + __syncthreads();
  118 + if (xi < step)
  119 + {
  120 + shared[xi][yi] += shared[xi + step][yi];
  121 + }
  122 + __syncthreads();
  123 + }
  124 + __syncthreads();
  125 +
  126 + for(unsigned int step = blockDim.y/2; step >= 1; step >>= 1)
  127 + {
  128 + __syncthreads();
  129 + if(yi < step)
  130 + {
  131 + shared[xi][yi] += shared[xi][yi + step];
  132 + }
  133 + __syncthreads();
  134 + }
  135 + __syncthreads();
  136 + if(xi == 0 && yi == 0)
  137 + res[idx] = shared[0][0];
  138 + }
  139 +
  140 + extern "C"
  141 + float *
  142 + get_centers(GLint texbufferID, GLenum texType, int DIM_X, int DIM_Y, int sizeK, float sigma, float conn, float threshold)
  143 + {
  144 + tx.SetTextureCoordinates(1);
  145 + tx.SetAddressMode(1, 3);
  146 + tx.MapCudaTexture(texbufferID, texType);
  147 + float* result = (float*) malloc(DIM_X*DIM_Y*sizeof(float));
  148 +
  149 + initArray(DIM_X, DIM_Y, sizeK);
  150 +
  151 + filterKernel(sizeK, sigma, LoG);
  152 + cudaMemcpy(gpuLoG, LoG, sizeK*sizeK*sizeof(float), cudaMemcpyHostToDevice);
  153 + dim3 numBlocks(DIM_X, DIM_Y);
  154 + dim3 threadsPerBlock(sizeK, sizeK);
  155 +
  156 + applyFilter <<< numBlocks, threadsPerBlock >>> (tx.getTexture(), DIM_X, DIM_Y, floor(sizeK/2), sizeK, res, gpuLoG);
  157 +
  158 +
  159 + stim::cuda::gpu_local_max<float>(centers, res, threshold, conn, DIM_X, DIM_Y);
  160 +
  161 + cudaDeviceSynchronize();
  162 +
  163 +
  164 + cudaMemcpy(result, centers, DIM_X*DIM_Y*sizeof(float), cudaMemcpyDeviceToHost);
  165 +
  166 + tx.UnmapCudaTexture();
  167 + cleanUP();
  168 + return result;
  169 + }
  170 +
  171 + }
  172 +}
  173 +#endif
stim/cuda/filter.h deleted
1 -#include <assert.h>  
2 -#include <cuda.h>  
3 -#include <cuda_runtime.h>  
4 -#include <stdio.h>  
5 -#include <stim/visualization/colormap.h>  
6 -#include <sstream>  
7 -  
8 -#define IMAD(a,b,c) ( __mul24((a), (b)) + (c) )  
9 -  
10 -int kr;  
11 -int kl;  
12 -float sigma;  
13 -float* LoG;  
14 -float* result;  
15 -cudaArray* srcArray;  
16 -texture<uchar, cudaTextureType2D, cudaReadModeElementType> texIn;  
17 -  
18 -  
19 -__device__ float filterKernel ()  
20 -{  
21 - float t = 0;  
22 - idx = j*kl+i;  
23 - for(int i = 0; i < kl; i++){  
24 - for(int j = 0; j < kl; j++){  
25 - x = i - floor(kl);  
26 - y = j - floor(kl);  
27 - LoG(idx) = (-1/M_PI/sigma^4)* (1 - (x^2+y^2)/2/sigma^2)  
28 - *exp(-(x^2+y^2)/2/sigma^2);  
29 - t +=LoG(idx);  
30 - }  
31 - }  
32 - LoG =/ t;  
33 -}  
34 -  
35 -void initArray(cudaGraphicsResource_t src, int DIM_X, int DIM_Y)  
36 -{  
37 - HANDLE_ERROR(  
38 - cudaGraphicsMapResources(1, &src)  
39 - );  
40 - HANDLE_ERROR(  
41 - cudaGraphicsSubResourceGetMappedArray(&srcArray, src, 0,0)  
42 - );  
43 - HANDLE_ERROR(  
44 - cudaBindTertureToArray(texIn, srcArray)  
45 - );  
46 - cudaMalloc( (void**) &LoG, kl*kl*sizeof(float));  
47 - checkCUDAerrors("Memory Allocation, LoG");  
48 - cudaMalloc( (void**) &result, DIM_Y*DIM_X*sizeof(float));  
49 - checkCUDAerrors("Memory Allocation, Result");  
50 -}  
51 -  
52 -void cleanUp(cudaGraphicsResource_t src);  
53 -{  
54 - HANDLE_ERROR(  
55 - cudaUnbindTexture(texIn)  
56 - );  
57 - HANDLE_ERROR(  
58 - cudaFree(LoG)  
59 - );  
60 - HANDLE_ERROR(  
61 - cudaFree(result)  
62 - );  
63 - HANDLE_ERROR(  
64 - cudaGraphicsUnmapResources(1, &src)  
65 - );  
66 -}  
67 -  
68 -//Shared memory would be better.  
69 -__global__  
70 -void  
71 -applyFilter(unsigned int DIM_X, unsigned int DIM_Y){  
72 -//R = floor(size/2)  
73 -//THIS IS A NAIVE WAY TO DO IT, and there is a better way)  
74 - //__shared__ float shared[(DIM_X+2*R), (DIM_Y+2*R)];  
75 -  
76 - const int x = IMAD(blockDim.x, blockIdx.x, threadIdx.x);  
77 - const int y = IMAD(blockDim.y, blockIdx.y, threadIdx.y);  
78 - float val = 0;  
79 - //x = max(0,x);  
80 - //x = min(x, width-1);  
81 - //y = max(y, 0);  
82 - //y = min(y, height - 1);  
83 -  
84 - int idx = y*DIM_X+x;  
85 - //unsigned int bindex = threadIdx.y * blockDim.y + threadIdx.x;  
86 -  
87 - //float valIn = tex2D(texIn, x, y);  
88 - for (int i = -kr; i <= kr; i++){ //rows  
89 - for (int j = -kr; i <= kr; j++){ //colls  
90 - k_idx = (j+kr)+(i+kr)*kl;  
91 - xi = max(0, x+i);  
92 - xi = min(x+i, DIM_X-1);  
93 - yj = max(y+j, 0);  
94 - yj = min(y+j, DIM_Y-1);  
95 - val += LoG(k_idx)*tex2D(texIn,x+i, y+j);  
96 - }  
97 - }  
98 -  
99 - result[idx] = val;  
100 -}  
stim/cuda/sharedmem.cuh
@@ -35,34 +35,6 @@ namespace stim{ @@ -35,34 +35,6 @@ namespace stim{
35 } 35 }
36 } 36 }
37 37
38 - template<typename T, typename D>  
39 - __device__ void sharedMemcpy_tex2D(T* dest, cudaTextureObject_t src,  
40 - unsigned int x, unsigned int y, unsigned int X, unsigned int Y,  
41 - dim3 threadIdx, dim3 blockDim){  
42 -  
43 - //calculate the number of iterations required for the copy  
44 - unsigned int xI, yI;  
45 - xI = X/blockDim.x + 1; //number of iterations along X  
46 - yI = Y/blockDim.y + 1; //number of iterations along Y  
47 -  
48 - //for each iteration  
49 - for(unsigned int xi = 0; xi < xI; xi++){  
50 - for(unsigned int yi = 0; yi < yI; yi++){  
51 -  
52 - //calculate the index into shared memory  
53 - unsigned int sx = xi * blockDim.x + threadIdx.x;  
54 - unsigned int sy = yi * blockDim.y + threadIdx.y;  
55 -  
56 - //calculate the index into the texture  
57 - unsigned int tx = x + sx;  
58 - unsigned int ty = y + sy;  
59 -  
60 - //perform the copy  
61 - if(sx < X && sy < Y)  
62 - dest[sy * X + sx] = abs(255 - tex2D<D>(src, tx, ty));  
63 - }  
64 - }  
65 - }  
66 38
67 } 39 }
68 } 40 }
stim/cuda/testKernel.cuh
@@ -14,9 +14,9 @@ @@ -14,9 +14,9 @@
14 ///Initialization function, allocates the memory and passes the necessary 14 ///Initialization function, allocates the memory and passes the necessary
15 ///handles from OpenGL and Cuda. 15 ///handles from OpenGL and Cuda.
16 ///@param DIM_Y --integer controlling how much memory to allocate. 16 ///@param DIM_Y --integer controlling how much memory to allocate.
17 - void initArray() 17 + void initArray(int x, int y)
18 { 18 {
19 - cudaMalloc( (void**) &print, 216*16*sizeof(float)); ///temporary 19 + cudaMalloc( (void**) &print, x*y*sizeof(float)); ///temporary
20 } 20 }
21 21
22 ///Deinit function that frees the memery used and releases the texture resource 22 ///Deinit function that frees the memery used and releases the texture resource
@@ -48,12 +48,14 @@ @@ -48,12 +48,14 @@
48 { 48 {
49 int x = threadIdx.x + blockIdx.x * blockDim.x; 49 int x = threadIdx.x + blockIdx.x * blockDim.x;
50 int y = threadIdx.y + blockIdx.y * blockDim.y; 50 int y = threadIdx.y + blockIdx.y * blockDim.y;
51 - int idx = y*16+x; 51 + int idx = y*64+x;
  52 +// int idx = y*32+x;
  53 +// int idx = y*16+x;
52 54
53 float valIn = tex2D<unsigned char>(texIn, x, y); 55 float valIn = tex2D<unsigned char>(texIn, x, y);
54 float templa = templ(x); 56 float templa = templ(x);
55 - //print[idx] = abs(valIn); ///temporary  
56 - print[idx] = abs(templa); ///temporary 57 + print[idx] = valIn; ///temporary
  58 + //print[idx] = abs(templa); ///temporary
57 59
58 } 60 }
59 61
@@ -64,7 +66,7 @@ @@ -64,7 +66,7 @@
64 ///@param GLenum texType --either GL_TEXTURE_1D, GL_TEXTURE_2D or GL_TEXTURE_3D 66 ///@param GLenum texType --either GL_TEXTURE_1D, GL_TEXTURE_2D or GL_TEXTURE_3D
65 /// may work with other gl texture types, but untested. 67 /// may work with other gl texture types, but untested.
66 ///@param DIM_Y, the number of samples in the template. 68 ///@param DIM_Y, the number of samples in the template.
67 - void test(GLint texbufferID, GLenum texType) 69 + void test(GLint texbufferID, GLenum texType, int x, int y)
68 { 70 {
69 71
70 //Bind the Texture in GL and allow access to cuda. 72 //Bind the Texture in GL and allow access to cuda.
@@ -72,16 +74,12 @@ @@ -72,16 +74,12 @@
72 74
73 //initialize the return arrays. 75 //initialize the return arrays.
74 76
75 - initArray();  
76 -  
77 - int x = 16;  
78 - int y = 27*8;  
79 - y = 8* 1089; 77 + initArray(x,y);
  78 + dim3 numBlocks(1, y);
  79 + dim3 threadsPerBlock(x, 1);
80 int max_threads = stim::maxThreadsPerBlock(); 80 int max_threads = stim::maxThreadsPerBlock();
81 //dim3 threads(max_threads, 1); 81 //dim3 threads(max_threads, 1);
82 //dim3 blocks(x / threads.x + 1, y); 82 //dim3 blocks(x / threads.x + 1, y);
83 - dim3 numBlocks(1, 1089);  
84 - dim3 threadsPerBlock(16, 8);  
85 //dim3 numBlocks(2, 2); 83 //dim3 numBlocks(2, 2);
86 //dim3 threadsPerBlock(8, 108); 84 //dim3 threadsPerBlock(8, 108);
87 85
@@ -92,7 +90,7 @@ @@ -92,7 +90,7 @@
92 cudaDeviceSynchronize(); 90 cudaDeviceSynchronize();
93 stringstream name; //for debugging 91 stringstream name; //for debugging
94 name << "FromTex.bmp"; 92 name << "FromTex.bmp";
95 - stim::gpu2image<float>(print, name.str(),16,1089*8,0,1.0); 93 + stim::gpu2image<float>(print, name.str(),x,y,0,255);
96 94
97 tx.UnmapCudaTexture(); 95 tx.UnmapCudaTexture();
98 cleanUP(); 96 cleanUP();
stim/gl/gl_spider.h
@@ -23,6 +23,7 @@ @@ -23,6 +23,7 @@
23 #include <stim/cuda/branch_detection.cuh> 23 #include <stim/cuda/branch_detection.cuh>
24 #include "../../../volume-spider/fiber.h" 24 #include "../../../volume-spider/fiber.h"
25 #include "../../../volume-spider/glnetwork.h" 25 #include "../../../volume-spider/glnetwork.h"
  26 +#include <stim/visualization/cylinder.h>
26 //#include <stim/cuda/testKernel.cuh> 27 //#include <stim/cuda/testKernel.cuh>
27 28
28 //#include <stim/cuda/testKernel.cuh> 29 //#include <stim/cuda/testKernel.cuh>
@@ -81,8 +82,8 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -81,8 +82,8 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
81 int numSamplesPos; 82 int numSamplesPos;
82 int numSamplesMag; 83 int numSamplesMag;
83 84
84 -// float stepsize = 4.0; //Step size.  
85 - float stepsize = 3.0; //Step size. 85 + float stepsize = 5.0; //Step size.
  86 +// float stepsize = 3.0; //Step size.
86 int current_cost; //variable to store the cost of the current step. 87 int current_cost; //variable to store the cost of the current step.
87 88
88 89
@@ -95,7 +96,6 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -95,7 +96,6 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
95 std::vector< stim::vec<float> > cD; //Direction of line currently being traced. 96 std::vector< stim::vec<float> > cD; //Direction of line currently being traced.
96 std::vector< stim::vec<float> > cM; //Magnitude of line currently being traced. 97 std::vector< stim::vec<float> > cM; //Magnitude of line currently being traced.
97 98
98 - stim::glObj<float> sk; //object to store the skeleton.  
99 stim::glnetwork<float> nt; //object for storing the network. 99 stim::glnetwork<float> nt; //object for storing the network.
100 100
101 stim::vec<float> rev; //reverse vector; 101 stim::vec<float> rev; //reverse vector;
@@ -169,6 +169,7 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -169,6 +169,7 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
169 169
170 ///subject to change. 170 ///subject to change.
171 ///finds branches. 171 ///finds branches.
  172 + ///depreciated
172 void 173 void
173 branchDetection() 174 branchDetection()
174 { 175 {
@@ -196,14 +197,8 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -196,14 +197,8 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
196 -p[1] + cylp[1]*S[1]*R[1], 197 -p[1] + cylp[1]*S[1]*R[1],
197 -p[2] + cylp[2]*S[2]*R[2]); 198 -p[2] + cylp[2]*S[2]*R[2]);
198 seeddir = seeddir.norm(); 199 seeddir = seeddir.norm();
199 -// float seedm = m[0]/2.0;  
200 float seedm = m[0]; 200 float seedm = m[0];
201 // Uncomment for global run 201 // Uncomment for global run
202 -/* stim::vec<float> lSeed = getLastSeed();  
203 - if(sqrt(pow((lSeed[0] - vec[0]),2)  
204 - + pow((lSeed[1] - vec[1]),2) +  
205 - pow((lSeed[2] - vec[2]),2)) > m[0]/4.0  
206 - && */  
207 if( 202 if(
208 !(vec[0] > size[0] || vec[1] > size[1] 203 !(vec[0] > size[0] || vec[1] > size[1]
209 || vec[2] > size[2] || vec[0] < 0 204 || vec[2] > size[2] || vec[0] < 0
@@ -218,6 +213,56 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -218,6 +213,56 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
218 213
219 } 214 }
220 215
  216 +
  217 + ///finds all the branches in the a given fiber.
  218 + ///using LoG method.
  219 + void
  220 + branchDetection2(int n = 8, int l_template = 8, int l_square = 8)
  221 + {
  222 + if(cL.size() < 4){}
  223 + else{
  224 + setMatrix(1);
  225 + DrawLongCylinder(n, l_template, l_square);
  226 + stim::cylinder<float> cyl(cL, cM);
  227 + std::vector< stim::vec<float> > result = find_branch(btexbufferID, GL_TEXTURE_2D, n*l_square, (cL.size()-1)*l_template);
  228 + stim::vec<float> size(S[0]*R[0], S[1]*R[1], S[2]*R[2]);
  229 + float pval;
  230 + if(!result.empty())
  231 + {
  232 + for(int i = 0; i < result.size(); i++)
  233 + {
  234 + int id = result[i][2];
  235 + if(fmod(result[i][2], id) != 0 && id != 0)
  236 + {
  237 +
  238 + pval = ((cyl.getl(id+1)-cyl.getl(id))*
  239 + (fmod(result[i][2], id))+cyl.getl(id))/cyl.getl(cL.size()-1);
  240 + }
  241 + else if(id == 0)
  242 + {
  243 + pval = (cyl.getl(id+1)*result[i][2])/cyl.getl(cL.size()-1);
  244 + }
  245 + else
  246 + {
  247 + pval = (cyl.getl(id)/cyl.getl(cL.size()-1));
  248 + }
  249 + stim::vec<float> v = cyl.surf(pval, result[i][0]);
  250 + stim::vec<float> di = cyl.p(pval);
  251 + float rad = cyl.r(pval);
  252 + if(
  253 + !(v[0] > size[0] || v[1] > size[1]
  254 + || v[2] > size[2] || v[0] < 0
  255 + || v[1] < 0 || v[2] < 0))
  256 + {
  257 + setSeed(v);
  258 + setSeedVec((v-di).norm());
  259 + setSeedMag(rad);
  260 + }
  261 + }
  262 + }
  263 + }
  264 + }
  265 +
221 266
222 //--------------------------------------------------------------------------// 267 //--------------------------------------------------------------------------//
223 //---------------------TEMPLATE CREATION METHODS----------------------------// 268 //---------------------TEMPLATE CREATION METHODS----------------------------//
@@ -459,6 +504,7 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -459,6 +504,7 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
459 void 504 void
460 GenerateFBO(unsigned int width, unsigned int height, GLuint &textureID, GLuint &framebufferID) 505 GenerateFBO(unsigned int width, unsigned int height, GLuint &textureID, GLuint &framebufferID)
461 { 506 {
  507 + glDeleteFramebuffers(1, &framebufferID);
462 glGenFramebuffers(1, &framebufferID); 508 glGenFramebuffers(1, &framebufferID);
463 glBindFramebuffer(GL_FRAMEBUFFER, framebufferID); 509 glBindFramebuffer(GL_FRAMEBUFFER, framebufferID);
464 int numChannels = 1; 510 int numChannels = 1;
@@ -506,45 +552,60 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -506,45 +552,60 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
506 } 552 }
507 553
508 554
  555 + ///IF type == 0
509 ///Method for using the gl manipulation to align templates from 556 ///Method for using the gl manipulation to align templates from
510 ///Template space (-0.5 0.5) to Texture space (0.0, 1.0), 557 ///Template space (-0.5 0.5) to Texture space (0.0, 1.0),
511 ///Based on the p of the spider in real space (arbitrary). 558 ///Based on the p of the spider in real space (arbitrary).
  559 +
  560 + ///IF type == 1
  561 + ///Method for using the gl manipulation to set up a matrix
  562 + ///To transform from tissue space into texture space.
512 ///All transformation happen in glMatrixMode(GL_TEXTURE). 563 ///All transformation happen in glMatrixMode(GL_TEXTURE).
513 - void setMatrix() 564 + ///All transformation happen in glMatrixMode(GL_TEXTURE).
  565 + void setMatrix(int type = 0)
514 { 566 {
515 - float curTrans[16]; //array to store the matrix values.  
516 - stim::vec<float> rot = getRotation(d); //get the rotation parameters for the current direction vector.  
517 - glMatrixMode(GL_TEXTURE);  
518 - glLoadIdentity(); 567 + if(type == 0)
  568 + {
  569 + float curTrans[16]; //array to store the matrix values.
  570 + stim::vec<float> rot = getRotation(d); //get the rotation parameters for the current direction vector.
  571 + glMatrixMode(GL_TEXTURE);
  572 + glLoadIdentity();
519 573
520 - //Scale by the voxel size and number of slices.  
521 - glScalef(1.0/S[0]/R[0], 1.0/S[1]/R[1], 1.0/S[2]/R[2]);  
522 - //translate to the current position of the spider in the texture.  
523 - glTranslatef(p[0],  
524 - p[1],  
525 - p[2]);  
526 - //rotate to the current direction of the spider.  
527 - glRotatef(rot[0], rot[1], rot[2], rot[3]);  
528 - //scale to the magnitude of the spider.  
529 - glScalef(m[0],  
530 - m[0],  
531 - m[0]);  
532 - //get and store the current transformation matrix for later use.  
533 - glGetFloatv(GL_TEXTURE_MATRIX, curTrans);  
534 - cT.set(curTrans);  
535 - // printTransform();  
536 -  
537 - CHECK_OPENGL_ERROR  
538 - //revert back to default gl mode.  
539 - glMatrixMode(GL_MODELVIEW); 574 + //Scale by the voxel size and number of slices.
  575 + glScalef(1.0/S[0]/R[0], 1.0/S[1]/R[1], 1.0/S[2]/R[2]);
  576 + //translate to the current position of the spider in the texture.
  577 + glTranslatef(p[0],
  578 + p[1],
  579 + p[2]);
  580 + //rotate to the current direction of the spider.
  581 + glRotatef(rot[0], rot[1], rot[2], rot[3]);
  582 + //scale to the magnitude of the spider.
  583 + glScalef(m[0],
  584 + m[0],
  585 + m[0]);
  586 + //get and store the current transformation matrix for later use.
  587 + glGetFloatv(GL_TEXTURE_MATRIX, curTrans);
  588 + cT.set(curTrans);
  589 + // printTransform();
  590 +
  591 + CHECK_OPENGL_ERROR
  592 + //revert back to default gl mode.
  593 + glMatrixMode(GL_MODELVIEW);
  594 + }
  595 + else if(type == 1)
  596 + {
  597 + glMatrixMode(GL_TEXTURE);
  598 + glLoadIdentity();
  599 + glScalef(1.0/S[0]/R[0], 1.0/S[1]/R[1], 1.0/S[2]/R[2]);
  600 + glMatrixMode(GL_MODELVIEW);
  601 + }
540 } 602 }
541 603
542 ///Method for controling the buffer and texture binding. 604 ///Method for controling the buffer and texture binding.
543 ///Clears the buffer upon binding. 605 ///Clears the buffer upon binding.
544 void 606 void
545 - Bind() 607 + Bind(float len = 8.0)
546 { 608 {
547 - float len = 8.0;  
548 glBindFramebuffer(GL_FRAMEBUFFER, fboID);//set up GL buffer 609 glBindFramebuffer(GL_FRAMEBUFFER, fboID);//set up GL buffer
549 glFramebufferTexture2D( 610 glFramebufferTexture2D(
550 GL_FRAMEBUFFER, 611 GL_FRAMEBUFFER,
@@ -576,9 +637,8 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -576,9 +637,8 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
576 ///@param GLuint &framebufferID, framebuffer used for storage. 637 ///@param GLuint &framebufferID, framebuffer used for storage.
577 ///@param int nSamples, number of rectanges to create. 638 ///@param int nSamples, number of rectanges to create.
578 void 639 void
579 - Bind(GLuint &textureID, GLuint &framebufferID, int nSamples) 640 + Bind(GLuint &textureID, GLuint &framebufferID, int nSamples, float len = 8.0)
580 { 641 {
581 - float len = 8.0;  
582 glBindFramebuffer(GL_FRAMEBUFFER, framebufferID);//set up GL buffer 642 glBindFramebuffer(GL_FRAMEBUFFER, framebufferID);//set up GL buffer
583 glFramebufferTexture2D( 643 glFramebufferTexture2D(
584 GL_FRAMEBUFFER, 644 GL_FRAMEBUFFER,
@@ -1085,7 +1145,7 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -1085,7 +1145,7 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
1085 { 1145 {
1086 float x, y, z, u, v, w, m; 1146 float x, y, z, u, v, w, m;
1087 myfile >> x >> y >> z >> u >> v >> w >> m; 1147 myfile >> x >> y >> z >> u >> v >> w >> m;
1088 - setSeed(x, y , z); 1148 + setSeed(x, y, z);
1089 setSeedVec(u, v, w); 1149 setSeedVec(u, v, w);
1090 setSeedMag(m); 1150 setSeedMag(m);
1091 } 1151 }
@@ -1099,14 +1159,28 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -1099,14 +1159,28 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
1099 void 1159 void
1100 saveNetwork(std::string name) 1160 saveNetwork(std::string name)
1101 { 1161 {
  1162 + stim::glObj<float> sk;
  1163 + for(int i = 0; i < nt.sizeE(); i++)
  1164 + {
  1165 + std::vector<stim::vec< float > > cm = nt.getEdgeCenterLineMag(i);
  1166 + std::vector<stim::vec< float > > ce = nt.getEdgeCenterLine(i);
  1167 + sk.Begin(stim::OBJ_LINE);
  1168 + for(int j = 0; j < ce.size(); j++)
  1169 + {
  1170 + sk.TexCoord(cm[j][0]);
  1171 + sk.Vertex(ce[j][0], ce[j][1], ce[j][2]);
  1172 + }
  1173 + sk.End();
  1174 + }
1102 sk.save(name); 1175 sk.save(name);
1103 } 1176 }
1104 1177
  1178 + ///Depreciated, but might be reused later()
1105 ///returns a COPY of the entire stim::glObj object. 1179 ///returns a COPY of the entire stim::glObj object.
1106 stim::glObj<float> 1180 stim::glObj<float>
1107 getNetwork() 1181 getNetwork()
1108 { 1182 {
1109 - return sk; 1183 +// return sk;
1110 } 1184 }
1111 1185
1112 ///returns a COPY of the entire stim::glnetwork object. 1186 ///returns a COPY of the entire stim::glnetwork object.
@@ -1216,6 +1290,37 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -1216,6 +1290,37 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
1216 glEnd(); 1290 glEnd();
1217 glEndList(); 1291 glEndList();
1218 } 1292 }
  1293 +
  1294 +///need to return the cylinder.
  1295 + void
  1296 + DrawLongCylinder(int n = 8, int l_template = 8,int l_square = 8)
  1297 + {
  1298 + int cylLen = cL.size()-1;
  1299 + GenerateFBO(n*l_square, cylLen*l_template, btexbufferID, bfboID);
  1300 + Bind(btexbufferID, bfboID, cylLen, l_template*l_square/2.0);
  1301 + stim::cylinder<float> cyl(cL, cM);
  1302 + std::vector<std::vector<stim::vec<float> > > p = cyl.getPoints(n);
  1303 + for(int i = 0; i < p.size()-1; i++) ///number of circles
  1304 + {
  1305 + for(int j = 0; j < p[0].size()-1; j++) ///points in the circle
  1306 + {
  1307 + glBegin(GL_QUADS);
  1308 + glTexCoord3f(p[i][j][0], p[i][j][1], p[i][j][2]);
  1309 + glVertex2f(j*l_square, i*(float)l_template);
  1310 +
  1311 + glTexCoord3f(p[i][j+1][0], p[i][j+1][1], p[i][j+1][2]);
  1312 + glVertex2f(j*l_square+l_square, i*(float)l_template);
  1313 +
  1314 + glTexCoord3f(p[i+1][j+1][0], p[i+1][j+1][1], p[i+1][j+1][2]);
  1315 + glVertex2f(j*l_square+l_square, i*(float)l_template+(float)l_template);
  1316 +
  1317 + glTexCoord3f(p[i+1][j][0], p[i+1][j][1], p[i+1][j][2]);
  1318 + glVertex2f(j*l_square,i*(float)l_template+(float)l_template);
  1319 + glEnd();
  1320 + }
  1321 + }
  1322 + Unbind();
  1323 + }
1219 1324
1220 1325
1221 ///@param min_cost the cost value used for tracing 1326 ///@param min_cost the cost value used for tracing
@@ -1223,114 +1328,35 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -1223,114 +1328,35 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
1223 void 1328 void
1224 trace(int min_cost) 1329 trace(int min_cost)
1225 { 1330 {
1226 - Bind();  
1227 - rev = stim::vec<float>(0.0,0.0,1.0); 1331 +// rev = stim::vec<float>(0.0,0.0,1.0);
1228 bool sEmpty = true; 1332 bool sEmpty = true;
1229 float lastmag = 16.0;; 1333 float lastmag = 16.0;;
1230 - while(!seeds.empty()) 1334 + stim::vec<float> curSeed;
  1335 + stim::vec<float> curSeedVec;
  1336 + float curSeedMag;
  1337 + while(!Empty())
1231 { 1338 {
1232 //clear the currently traced line and start a new one. 1339 //clear the currently traced line and start a new one.
1233 cL.clear(); 1340 cL.clear();
1234 cM.clear(); 1341 cM.clear();
1235 - sk.Begin(stim::OBJ_LINE);  
1236 - stim::vec<float> curSeed = seeds.top();  
1237 -// std::cout << "The current seeds is " << curSeed << std::endl;  
1238 - stim::vec<float> curSeedVec = seedsvecs.top();  
1239 - float curSeedMag = seedsmags.top(); 1342 + cD.clear();
  1343 + curSeed = seeds.top();
  1344 + curSeedVec = seedsvecs.top();
  1345 + curSeedMag = seedsmags.top();
1240 seeds.pop(); 1346 seeds.pop();
1241 seedsvecs.pop(); 1347 seedsvecs.pop();
1242 seedsmags.pop(); 1348 seedsmags.pop();
1243 // std::cout << "The current seed Vector is " << curSeedVec << std::endl; 1349 // std::cout << "The current seed Vector is " << curSeedVec << std::endl;
1244 setPosition(curSeed); 1350 setPosition(curSeed);
1245 setDirection(curSeedVec); 1351 setDirection(curSeedVec);
1246 - cL.push_back(curSeed);  
1247 - cM.push_back(curSeedMag);  
1248 - sk.createFromSelf(GL_SELECT);  
1249 - traceLine(min_cost);  
1250 -  
1251 - sk.rev();  
1252 - // std::cout << "reversed" << std::endl;  
1253 - std::reverse(cL.begin(), cL.end());  
1254 - std::reverse(cM.begin(), cM.end());  
1255 - setPosition(curSeed);  
1256 - setDirection(-rev);  
1257 - setMagnitude(16.0);  
1258 - sk.createFromSelf(GL_SELECT);  
1259 - traceLine(min_cost);  
1260 - sk.End(); 1352 + setMagnitude(curSeedMag);
  1353 +// cL.push_back(curSeed);
  1354 +// cM.push_back(curSeedMag);
  1355 +// cD.push_back(curSeedMag);
  1356 + pair<stim::fiber<float>, int> a = traceLine(p, m, min_cost);
1261 } 1357 }
1262 - Unbind();  
1263 } 1358 }
1264 1359
1265 - ///@param min_cost the cost value used for tracing  
1266 - ///traces the seedpoint passed to completion in one directions.  
1267 - void  
1268 - traceLine(int min_cost)  
1269 - {  
1270 - stim::vec<float> pos;  
1271 - stim::vec<float> mag;  
1272 - int h;  
1273 - bool started = false;  
1274 - bool running = true;  
1275 - stim::vec<float> size(S[0]*R[0], S[1]*R[1], S[2]*R[2]);  
1276 - while(running)  
1277 - {  
1278 - int cost = Step();  
1279 - if (cost > min_cost){  
1280 - running = false;  
1281 - break;  
1282 - } else {  
1283 - //Have we found an edge?  
1284 - pos = getPosition();  
1285 - if(pos[0] > size[0] || pos[1] > size[1]  
1286 - || pos[2] > size[2] || pos[0] < 0  
1287 - || pos[1] < 0 || pos[2] < 0)  
1288 - {  
1289 -// std::cout << "Found Edge" << std::endl;  
1290 - running = false;  
1291 - break;  
1292 - }  
1293 - //If this is the first step in the trace,  
1294 - // save the direction  
1295 - //(to be used later to trace the fiber in the opposite direction)  
1296 - if(started == false){  
1297 - rev = -getDirection();  
1298 - started = true;  
1299 - }  
1300 -// std::cout << i << p << std::endl;  
1301 - m = getMagnitude();  
1302 - //Has the template size gotten unreasonable?  
1303 - if(m[0] > 75 || m[0] < 1){  
1304 -// std::cout << "Magnitude Limit" << std::endl;  
1305 - running = false;  
1306 - break;  
1307 - }  
1308 - else  
1309 - {  
1310 - h = selectObject(pos, getDirection(), m[0]);  
1311 - //Have we hit something previously traced?  
1312 - if(h != -1){  
1313 - std::cout << "I hit a line" << h << std::endl;  
1314 - running = false;  
1315 - break;  
1316 - }  
1317 - else {  
1318 - cL.push_back(stim::vec<float>(p[0], p[1],p[2]));//  
1319 - sk.TexCoord(m[0]);  
1320 - sk.Vertex(p[0], p[1], p[2]);  
1321 - Bind(btexbufferID, bfboID, 27);  
1322 - CHECK_OPENGL_ERROR  
1323 - branchDetection();  
1324 - CHECK_OPENGL_ERROR  
1325 - Unbind();  
1326 - CHECK_OPENGL_ERROR  
1327 - }  
1328 - }  
1329 - }  
1330 - }  
1331 - }  
1332 -  
1333 -  
1334 int 1360 int
1335 selectObject(stim::vec<float> loc, stim::vec<float> dir, float mag) 1361 selectObject(stim::vec<float> loc, stim::vec<float> dir, float mag)
1336 { 1362 {
@@ -1468,10 +1494,10 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -1468,10 +1494,10 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
1468 spos[2] = spos[2]-sdir[2]*smag[0]/2.; 1494 spos[2] = spos[2]-sdir[2]*smag[0]/2.;
1469 int h = selectObject(spos, -sdir, smag[0]); 1495 int h = selectObject(spos, -sdir, smag[0]);
1470 //did start with a fiber? 1496 //did start with a fiber?
1471 - if(h != -1){ 1497 + if(h != -1 && h != nt.sizeE()){
1472 // std::cout << "got here double" << smag.str() << std::endl; 1498 // std::cout << "got here double" << smag.str() << std::endl;
1473 nt.addEdge(ce,cm, h, in.second); 1499 nt.addEdge(ce,cm, h, in.second);
1474 - } 1500 + } else { nt.addEdge(ce,cm, -1, -1);}
1475 } 1501 }
1476 } 1502 }
1477 } 1503 }
@@ -1494,7 +1520,7 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -1494,7 +1520,7 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
1494 stim::vec<float> sdir = getDirection(); 1520 stim::vec<float> sdir = getDirection();
1495 1521
1496 Bind(); 1522 Bind();
1497 - sk.Begin(stim::OBJ_LINE); 1523 +// sk.Begin(stim::OBJ_LINE);
1498 1524
1499 1525
1500 // sk.createFromSelf(GL_SELECT); 1526 // sk.createFromSelf(GL_SELECT);
@@ -1514,7 +1540,8 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -1514,7 +1540,8 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
1514 int cost = Step(); 1540 int cost = Step();
1515 if (cost > min_cost){ 1541 if (cost > min_cost){
1516 running = false; 1542 running = false;
1517 - sk.End(); 1543 +// sk.End();
  1544 + branchDetection2();
1518 pair<stim::fiber<float>, int> a(stim::fiber<float> (cL, cM), -1); 1545 pair<stim::fiber<float>, int> a(stim::fiber<float> (cL, cM), -1);
1519 addToNetwork(a, spos, smag, sdir); 1546 addToNetwork(a, spos, smag, sdir);
1520 return a; 1547 return a;
@@ -1526,9 +1553,8 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -1526,9 +1553,8 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
1526 || pos[2] > size[2] || pos[0] < 0 1553 || pos[2] > size[2] || pos[0] < 0
1527 || pos[1] < 0 || pos[2] < 0) 1554 || pos[1] < 0 || pos[2] < 0)
1528 { 1555 {
1529 -// std::cout << "Found Edge" << std::endl;  
1530 running = false; 1556 running = false;
1531 - sk.End(); 1557 + branchDetection2();
1532 pair<stim::fiber<float>, int> a(stim::fiber<float> (cL, cM), -1); 1558 pair<stim::fiber<float>, int> a(stim::fiber<float> (cL, cM), -1);
1533 addToNetwork(a, spos, smag, sdir); 1559 addToNetwork(a, spos, smag, sdir);
1534 return a; 1560 return a;
@@ -1541,13 +1567,11 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -1541,13 +1567,11 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
1541 rev = -getDirection(); 1567 rev = -getDirection();
1542 started = true; 1568 started = true;
1543 } 1569 }
1544 -// std::cout << i << p << std::endl;  
1545 //Has the template size gotten unreasonable? 1570 //Has the template size gotten unreasonable?
1546 mag = getMagnitude(); 1571 mag = getMagnitude();
1547 if(mag[0] > 75 || mag[0] < 1){ 1572 if(mag[0] > 75 || mag[0] < 1){
1548 -// std::cout << "Magnitude Limit" << std::endl;  
1549 running = false; 1573 running = false;
1550 - sk.End(); 1574 + branchDetection2();
1551 pair<stim::fiber<float>, int> a(stim::fiber<float> (cL, cM), -1); 1575 pair<stim::fiber<float>, int> a(stim::fiber<float> (cL, cM), -1);
1552 addToNetwork(a, spos, smag, sdir); 1576 addToNetwork(a, spos, smag, sdir);
1553 return a; 1577 return a;
@@ -1559,7 +1583,7 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -1559,7 +1583,7 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
1559 //Have we hit something previously traced? 1583 //Have we hit something previously traced?
1560 if(h != -1){ 1584 if(h != -1){
1561 running = false; 1585 running = false;
1562 - sk.End(); 1586 + branchDetection2();
1563 pair<stim::fiber<float>, int> a(stim::fiber<float> (cL, cM), h); 1587 pair<stim::fiber<float>, int> a(stim::fiber<float> (cL, cM), h);
1564 addToNetwork(a, spos, smag, sdir); 1588 addToNetwork(a, spos, smag, sdir);
1565 return a; 1589 return a;
@@ -1568,14 +1592,7 @@ class gl_spider : public virtual gl_texture&lt;T&gt; @@ -1568,14 +1592,7 @@ class gl_spider : public virtual gl_texture&lt;T&gt;
1568 else { 1592 else {
1569 cL.push_back(stim::vec<float>(p[0], p[1],p[2])); 1593 cL.push_back(stim::vec<float>(p[0], p[1],p[2]));
1570 cM.push_back(stim::vec<float>(m[0], m[0])); 1594 cM.push_back(stim::vec<float>(m[0], m[0]));
1571 -// cM.push_back(m[0]);  
1572 -  
1573 - sk.TexCoord(m[0]);  
1574 - sk.Vertex(p[0], p[1], p[2]);  
1575 - Bind(btexbufferID, bfboID, 27);  
1576 - CHECK_OPENGL_ERROR  
1577 - branchDetection();  
1578 - CHECK_OPENGL_ERROR 1595 +// Bind(btexbufferID, bfboID, 27);
1579 Unbind(); 1596 Unbind();
1580 CHECK_OPENGL_ERROR 1597 CHECK_OPENGL_ERROR
1581 1598
stim/math/circle.h
1 #ifndef STIM_CIRCLE_H 1 #ifndef STIM_CIRCLE_H
2 #define STIM_CIRCLE_H 2 #define STIM_CIRCLE_H
3 3
4 -//enable CUDA_CALLABLE macro  
5 #include <stim/cuda/cudatools/callable.h> 4 #include <stim/cuda/cudatools/callable.h>
  5 +#include <stim/math/plane.h>
6 #include <stim/math/vector.h> 6 #include <stim/math/vector.h>
7 #include <stim/math/triangle.h> 7 #include <stim/math/triangle.h>
8 -#include <stim/math/quaternion.h>  
9 -#include <stim/math/rect.h>  
10 -#include <iostream>  
11 -#include <iomanip> 8 +#include <assert.h>
12 #include <algorithm> 9 #include <algorithm>
  10 +#include <iostream>
13 11
14 -namespace stim  
15 -{ 12 +namespace stim{
16 13
17 -template <class T>  
18 -struct circle : rect<T> 14 +template <typename T>
  15 +class circle : plane<T>
19 { 16 {
20 - private:  
21 - T theta;  
22 -  
23 - public:  
24 -  
25 - using stim::rect<T>::p;  
26 - using stim::rect<T>::normal;  
27 - using stim::rect<T>::center;  
28 - using stim::rect<T>::scale;  
29 - ///base constructor  
30 - ///@param th value of the angle of the starting point from 0 to 360.  
31 - CUDA_CALLABLE circle(float th = 0.0) : rect<T>()  
32 - {  
33 - theta = th;  
34 - }  
35 17
36 - ///create a rectangle given a size and position in Z space.  
37 - ///@param size: size of the rectangle in ND space.  
38 - ///@param z_pos z coordinate of the rectangle.  
39 - ///@param th value of the angle of the starting point from 0 to 360.  
40 - CUDA_CALLABLE circle(T size, T zpos = (T)0, float th = 0.0) : rect<T>(size, zpos)  
41 - {  
42 - theta = th;  
43 - } 18 +private:
  19 +
  20 + stim::vec<T> Y;
44 21
45 - ///create a rectangle from a center point, normal  
46 - ///@param c: x,y,z location of the center.  
47 - ///@param n: x,y,z direction of the normal.  
48 - ///@param th value of the angle of the starting point from 0 to 360.  
49 - CUDA_CALLABLE circle(vec<T> c, vec<T> n = vec<T>(0,0,1), float th = 0.0) : rect<T>(c, n)  
50 - {  
51 - theta = th;  
52 - }  
53 -  
54 - ///create a rectangle from a center point, normal, and size  
55 - ///@param c: x,y,z location of the center.  
56 - ///@param s: size of the rectangle.  
57 - ///@param n: x,y,z direction of the normal.  
58 - ///@param th value of the angle of the starting point from 0 to 360.  
59 - CUDA_CALLABLE circle(vec<T> c, T s, vec<T> n = vec<T>(0,0,1), float th = 0.0):rect<T>(c,s,n)  
60 - {  
61 - theta = th;  
62 - } 22 + CUDA_CALLABLE void
  23 + init()
  24 + {
  25 + Y = U.cross(N).norm();
  26 + }
63 27
64 - ///creates a rectangle from a centerpoint and an X and Y direction vectors.  
65 - ///@param center: x,y,z location of the center.  
66 - ///@param directionX: u,v,w direction of the X vector.  
67 - ///@param directionY: u,v,w direction of the Y vector.  
68 - ///@param th value of the angle of the starting point from 0 to 360.  
69 - CUDA_CALLABLE circle(vec<T> center, vec<T> directionX, vec<T> directionY, float th = 0.0) : rect<T>(center, directionX, directionY)  
70 - {  
71 - theta = th;  
72 - } 28 +public:
  29 + using stim::plane<T>::n;
  30 + using stim::plane<T>::P;
  31 + using stim::plane<T>::N;
  32 + using stim::plane<T>::U;
  33 + using stim::plane<T>::rotate;
  34 + using stim::plane<T>::setU;
73 35
74 - ///creates a rectangle from a size, centerpoint, X, and Y direction vectors.  
75 - ///@param size of the rectangle in ND space.  
76 - ///@param center: x,y,z location of the center.  
77 - ///@param directionX: u,v,w direction of the X vector.  
78 - ///@param directionY: u,v,w direction of the Y vector.  
79 - ///@param th value of the angle of the starting point from 0 to 360.  
80 - CUDA_CALLABLE circle(T size, vec<T> center, vec<T> directionX, vec<T> directionY, float th = 0.0) : rect<T>(size, center, directionX, directionY)  
81 - {  
82 - theta = th;  
83 - }  
84 -  
85 - ///creates a rectangle from a size, centerpoint, X, and Y direction vectors.  
86 - ///@param size of the rectangle in ND space, size[0] = size in X, size[1] = size in Y.  
87 - ///@param center: x,y,z location of the center.  
88 - ///@param directionX: u,v,w direction of the X vector.  
89 - ///@param directionY: u,v,w direction of the Y vector.  
90 - ///@param th value of the angle of the starting point from 0 to 360.  
91 - CUDA_CALLABLE circle(vec<T> size, vec<T> center, vec<T> directionX, vec<T> directionY, float th = 0.0) : rect<T>(size, center, directionX, directionY)  
92 - {  
93 - theta = th;  
94 - } 36 + ///base constructor
  37 + ///@param th value of the angle of the starting point from 0 to 360.
  38 + CUDA_CALLABLE
  39 + circle() : plane<T>()
  40 + {
  41 + init();
  42 + }
95 43
96 - ///returns a vector with the points on the initialized circle.  
97 - ///connecting the points results in a circle.  
98 - ///@param n: integer for the number of points representing the circle.  
99 - std::vector<stim::vec<T> >  
100 - getPoints(int n)  
101 - {  
102 - std::vector<stim::vec<T> > result;  
103 - stim::vec<T> point;  
104 - T x,y;  
105 - float step = 360.0/(float) n;  
106 - for(float j = theta; j <= theta+360.0; j += step)  
107 - {  
108 - y = 0.5*cos(j*2.0*M_PI/360.0)+0.5;  
109 - x = 0.5*sin(j*2.0*M_PI/360.0)+0.5;  
110 - result.push_back(p(x,y));  
111 - }  
112 -  
113 - return result;  
114 - } 44 + ///create a rectangle given a size and position in Z space.
  45 + ///@param size: size of the rectangle in ND space.
  46 + ///@param z_pos z coordinate of the rectangle.
  47 + CUDA_CALLABLE
  48 + circle(T size, T z_pos = (T)0) : plane<T>()
  49 + {
  50 + init();
  51 + center(stim::vec<T>(0,0,z_pos));
  52 + scale(size);
  53 + }
  54 +
  55 + ///create a rectangle from a center point, normal
  56 + ///@param c: x,y,z location of the center.
  57 + ///@param n: x,y,z direction of the normal.
  58 + CUDA_CALLABLE
  59 + circle(vec<T> c, vec<T> n = vec<T>(0,0,1)) : plane<T>()
  60 + {
  61 + center(c);
  62 + normal(n);
  63 + init();
  64 + }
  65 +
  66 + ///create a rectangle from a center point, normal, and size
  67 + ///@param c: x,y,z location of the center.
  68 + ///@param s: size of the rectangle.
  69 + ///@param n: x,y,z direction of the normal.
  70 + CUDA_CALLABLE
  71 + circle(vec<T> c, T s, vec<T> n = vec<T>(0,0,1)) : plane<T>()
  72 + {
  73 + init();
  74 + center(c);
  75 + rotate(n, U, Y);
  76 + scale(s);
  77 + }
  78 +
  79 + ///create a rectangle from a center point, normal, and size
  80 + ///@param c: x,y,z location of the center.
  81 + ///@param s: size of the rectangle.
  82 + ///@param n: x,y,z direction of the normal.
  83 + ///@param u: x,y,z direction for the zero vector (from where the rotation starts)
  84 + CUDA_CALLABLE
  85 + circle(vec<T> c, T s, vec<T> n = vec<T>(0,0,1), vec<T> u = vec<T>(1, 0, 0)) : plane<T>()
  86 + {
  87 + init();
  88 + setU(u);
  89 + center(c);
  90 + normal(n);
  91 + scale(s);
  92 + }
  93 +
  94 + ///scales the circle by a certain factor
  95 + ///@param factor: the factor by which the dimensions of the shape are scaled.
  96 + CUDA_CALLABLE
  97 + void scale(T factor)
  98 + {
  99 + U *= factor;
  100 + Y *= factor;
  101 + }
  102 +
  103 + ///sets the normal for the cirlce
  104 + ///@param n: x,y,z direction of the normal.
  105 + CUDA_CALLABLE void
  106 + normal(vec<T> n)
  107 + {
  108 + rotate(n, Y);
  109 + }
115 110
116 - ///returns a vector with the points on the initialized circle.  
117 - ///connecting the points results in a circle.  
118 - ///@param n: integer for the number of points representing the circle.  
119 - stim::vec<T>  
120 - p(T theta) 111 + ///sets the center of the circle.
  112 + ///@param n: x,y,z location of the center.
  113 + CUDA_CALLABLE T
  114 + center(vec<T> p)
  115 + {
  116 + this->P = p;
  117 + }
  118 +
  119 + ///boolean comparison
  120 + bool
  121 + operator==(const circle<T> & rhs)
  122 + {
  123 + if(P == rhs.P && U == rhs.U && Y == rhs.Y)
  124 + return true;
  125 + else
  126 + return false;
  127 + }
  128 +
  129 + ///get the world space value given the planar coordinates a, b in [0, 1]
  130 + CUDA_CALLABLE stim::vec<T> p(T a, T b)
  131 + {
  132 + stim::vec<T> result;
  133 +
  134 + vec<T> A = this->P - this->U * (T)0.5 - Y * (T)0.5;
  135 + result = A + this->U * a + Y * b;
  136 + return result;
  137 + }
  138 +
  139 + ///parenthesis operator returns the world space given rectangular coordinates a and b in [0 1]
  140 + CUDA_CALLABLE stim::vec<T> operator()(T a, T b)
  141 + {
  142 + return p(a,b);
  143 + }
  144 +
  145 + ///returns a vector with the points on the initialized circle.
  146 + ///connecting the points results in a circle.
  147 + ///@param n: integer for the number of points representing the circle.
  148 + std::vector<stim::vec<T> >
  149 + getPoints(int n)
  150 + {
  151 + std::vector<stim::vec<T> > result;
  152 + stim::vec<T> point;
  153 + T x,y;
  154 + float step = 360.0/(float) n;
  155 + for(float j = 0; j <= 360.0; j += step)
121 { 156 {
122 - T x,y;  
123 - y = 0.5*cos(theta*2.0*M_PI/360.0)+0.5;  
124 - x = 0.5*sin(theta*2.0*M_PI/360.0)+0.5;  
125 - return p(x,y); 157 + y = 0.5*cos(j*2.0*M_PI/360.0)+0.5;
  158 + x = 0.5*sin(j*2.0*M_PI/360.0)+0.5;
  159 + result.push_back(p(x,y));
126 } 160 }
127 -}; 161 + return result;
  162 + }
  163 +
  164 + ///returns a vector with the points on the initialized circle.
  165 + ///connecting the points results in a circle.
  166 + ///@param n: integer for the number of points representing the circle.
  167 + stim::vec<T>
  168 + p(T theta)
  169 + {
  170 + T x,y;
  171 + y = 0.5*cos(theta*2.0*M_PI/360.0)+0.5;
  172 + x = 0.5*sin(theta*2.0*M_PI/360.0)+0.5;
  173 + return p(x,y);
  174 + }
128 175
  176 +};
129 } 177 }
130 - 178 +>>>>>>> origin/Master_Clone_W_Branch
131 #endif 179 #endif
@@ -194,6 +194,17 @@ class plane @@ -194,6 +194,17 @@ class plane
194 194
195 } 195 }
196 196
  197 + CUDA_CALLABLE void rotate(vec<T> n, vec<T> &Y)
  198 + {
  199 + quaternion<T> q;
  200 + q.CreateRotation(N, n);
  201 +
  202 + N = q.toMatrix3() * N;
  203 + U = q.toMatrix3() * U;
  204 + Y = q.toMatrix3() * Y;
  205 +
  206 + }
  207 +
197 CUDA_CALLABLE void rotate(vec<T> n, vec<T> &X, vec<T> &Y) 208 CUDA_CALLABLE void rotate(vec<T> n, vec<T> &X, vec<T> &Y)
198 { 209 {
199 quaternion<T> q; 210 quaternion<T> q;
stim/visualization/cylinder.h
@@ -12,89 +12,134 @@ class cylinder @@ -12,89 +12,134 @@ class cylinder
12 { 12 {
13 private: 13 private:
14 stim::circle<T> s; //an arbitrary circle 14 stim::circle<T> s; //an arbitrary circle
15 - std::vector< stim::vec<T> > pos; //positions of the cylinder.  
16 - std::vector< stim::vec<T> > mags; //radii at each position 15 + std::vector<stim::circle<T> > e;
  16 + std::vector<stim::vec<T> > mags;
17 std::vector< T > L; //length of the cylinder at each position. 17 std::vector< T > L; //length of the cylinder at each position.
18 -  
19 - ///default init 18 +
  19 + ///default init
20 void 20 void
21 - init(){ 21 + init()
  22 + {
22 23
23 } 24 }
24 25
25 ///inits the cylinder from a list of points (inP) and radii (inM) 26 ///inits the cylinder from a list of points (inP) and radii (inM)
26 void 27 void
27 - init(std::vector<stim::vec<T> > inP, std::vector<stim::vec<T> > inM){  
28 - pos = inP; 28 + init(std::vector<stim::vec<T> > inP, std::vector<stim::vec<T> > inM)
  29 + {
29 mags = inM; 30 mags = inM;
  31 + stim::vec<float> v1;
  32 + stim::vec<float> v2;
  33 + e.resize(inP.size());
  34 + if(inP.size() < 2)
  35 + return;
30 36
31 //calculate each L. 37 //calculate each L.
32 - L.resize(pos.size()-1); 38 + L.resize(inP.size());
33 T temp = (T)0; 39 T temp = (T)0;
34 - for(int i = 0; i < L.size(); i++) 40 + L[0] = 0;
  41 + for(int i = 1; i < L.size(); i++)
35 { 42 {
36 - temp += (pos[i] - pos[i+1]).len(); 43 + temp += (inP[i-1] - inP[i]).len();
37 L[i] = temp; 44 L[i] = temp;
38 } 45 }
39 - }  
40 46
  47 + stim::vec<T> dr = (inP[1] - inP[0]).norm();
  48 + s = stim::circle<T>(inP[0], inM[0][0], dr, stim::vec<T>(1,0,0));
  49 + e[0] = s;
  50 + for(int i = 1; i < inP.size()-1; i++)
  51 + {
  52 + s.center(inP[i]);
  53 + v1 = (inP[i] - inP[i-1]).norm();
  54 + v2 = (inP[i+1] - inP[i]).norm();
  55 + dr = (v1+v2).norm();
  56 + s.normal(dr);
  57 + s.scale(inM[i][0]/inM[i-1][0]);
  58 + e[i] = s;
  59 + }
  60 +
  61 + int j = inP.size()-1;
  62 + s.center(inP[j]);
  63 + dr = (inP[j] - inP[j-1]).norm();
  64 + s.normal(dr);
  65 + s.scale(inM[j][0]/inM[j-1][0]);
  66 + e[j] = s;
  67 + }
  68 +
41 ///returns the direction vector at point idx. 69 ///returns the direction vector at point idx.
42 stim::vec<T> 70 stim::vec<T>
43 - d(int idx){  
44 - return (pos[idx] - pos[idx+1]).norm(); 71 + d(int idx)
  72 + {
  73 + if(idx == 0)
  74 + {
  75 + return (e[idx+1].P - e[idx].P).norm();
  76 + }
  77 + else if(idx == e.size()-1)
  78 + {
  79 + return (e[idx].P - e[idx-1].P).norm();
  80 + }
  81 + else
  82 + {
  83 +// return (e[idx+1].P - e[idx].P).norm();
  84 + stim::vec<float> v1 = (e[idx].P-e[idx-1].P).norm();
  85 + stim::vec<float> v2 = (e[idx+1].P-e[idx].P).norm();
  86 + return (v1+v2).norm();
  87 + }
  88 + // return e[idx].N;
  89 +
45 } 90 }
46 91
47 - ///returns the total length of the line at index j.  
48 - T  
49 - getl(int j){  
50 - for(int i = 0; i < j-1; ++i) 92 + stim::vec<T>
  93 + d(T l, int idx)
  94 + {
  95 + if(idx == 0 || idx == e.size()-1)
51 { 96 {
52 - temp += (pos[i] - pos[i+1]).len();  
53 - L[i] = temp; 97 + return e[idx].N;
54 } 98 }
  99 + else
  100 + {
  101 + T rat = (l-L[idx])/(L[idx+1]-L[idx]);
  102 + return( e[idx].N + (e[idx+1].N - e[idx].N)*rat);
  103 + }
55 } 104 }
56 105
  106 +
57 ///finds the index of the point closest to the length l on the lower bound. 107 ///finds the index of the point closest to the length l on the lower bound.
58 ///binary search. 108 ///binary search.
59 int 109 int
60 - findIdx(T l){  
61 - int i = pos.size()/2;  
62 - while(i > 0 && i < pos.size()) 110 + findIdx(T l)
  111 + {
  112 + unsigned int i = L.size()/2;
  113 + unsigned int max = L.size()-1;
  114 + unsigned int min = 0;
  115 + while(i > 0 && i < L.size()-1)
63 { 116 {
64 - if(L[i] < l) 117 +// std::cerr << "Trying " << i << std::endl;
  118 +// std::cerr << "l is " << l << ", L[" << i << "]" << L[i] << std::endl;
  119 + if(l < L[i])
65 { 120 {
66 - i = i/2; 121 + max = i;
  122 + i = min+(max-min)/2;
67 } 123 }
68 - else if(L[i] < l && L[i+1] > l) 124 + else if(L[i] <= l && L[i+1] >= l)
69 { 125 {
70 break; 126 break;
71 } 127 }
72 else 128 else
73 { 129 {
74 - i = i+i/2; 130 + min = i;
  131 + i = min+(max-min)/2;
75 } 132 }
76 } 133 }
77 return i; 134 return i;
78 } 135 }
79 136
80 - //initializes the length array given the current set of positions  
81 - void init_length(){  
82 - vec<T> p0, p1;  
83 - p0 = pos[0]; //initialize the first point in the segment to the first point in the cylinder  
84 - T l; //allocate space for the segment length  
85 - for(unsigned p = 1; p < pos.size(); p++){ //for each point in the cylinder  
86 - p1 = pos[p]; //get the second point in the segment  
87 - l = (p1 - p0).len(); //calculate the length of the segment  
88 -  
89 - if(p == 1) L[0] = l; //set the length for the first segment  
90 - else L[p-1] = L[p-2] + l; //calculate and set the running length for each additional segment  
91 - }  
92 -  
93 - }  
94 -  
95 public: 137 public:
96 ///default constructor 138 ///default constructor
97 - cylinder(){} 139 + cylinder()
  140 + {
  141 +
  142 + }
98 143
99 ///constructor to create a cylinder from a set of points, radii, and the number of sides for the cylinder. 144 ///constructor to create a cylinder from a set of points, radii, and the number of sides for the cylinder.
100 ///@param inP: Vector of stim vecs composing the points of the centerline. 145 ///@param inP: Vector of stim vecs composing the points of the centerline.
@@ -127,12 +172,16 @@ class cylinder @@ -127,12 +172,16 @@ class cylinder
127 ///interpolates the position along the line. 172 ///interpolates the position along the line.
128 ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1). 173 ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1).
129 stim::vec<T> 174 stim::vec<T>
130 - p(T pvalue){ 175 + p(T pvalue)
  176 + {
131 if(pvalue < 0.0 || pvalue > 1.0) 177 if(pvalue < 0.0 || pvalue > 1.0)
132 - return; 178 + {
  179 + return stim::vec<float>(-1,-1,-1);
  180 + }
133 T l = pvalue*L[L.size()-1]; 181 T l = pvalue*L[L.size()-1];
134 int idx = findIdx(l); 182 int idx = findIdx(l);
135 - return (pos[idx] + (pos[idx+1]-pos[idx])*((l-L[idx])/(L[idx+1]- L[idx]))); 183 + T rat = (l-L[idx])/(L[idx+1]-L[idx]);
  184 + return( e[idx].P + (e[idx+1].P-e[idx].P)*rat);
136 } 185 }
137 186
138 ///Returns a position vector at the given length into the fiber (based on the pvalue). 187 ///Returns a position vector at the given length into the fiber (based on the pvalue).
@@ -140,20 +189,25 @@ class cylinder @@ -140,20 +189,25 @@ class cylinder
140 ///@param l: the location of the in the cylinder. 189 ///@param l: the location of the in the cylinder.
141 ///@param idx: integer location of the point closest to l but prior to it. 190 ///@param idx: integer location of the point closest to l but prior to it.
142 stim::vec<T> 191 stim::vec<T>
143 - p(T l, int idx){  
144 - return (pos[idx] + (pos[idx+1]-pos[idx])*((l-L[idx])/(L[idx+1]- L[idx]))); 192 + p(T l, int idx)
  193 + {
  194 + T rat = (l-L[idx])/(L[idx+1]-L[idx]);
  195 + return( e[idx].P + (e[idx+1].P-e[idx].P)*rat);
  196 +// return(
  197 +// return (pos[idx] + (pos[idx+1]-pos[idx])*((l-L[idx])/(L[idx+1]- L[idx])));
145 } 198 }
146 199
147 ///Returns a radius at the given p-value (p value ranges from 0 to 1). 200 ///Returns a radius at the given p-value (p value ranges from 0 to 1).
148 ///interpolates the radius along the line. 201 ///interpolates the radius along the line.
149 ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1). 202 ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1).
150 T 203 T
151 - r(T pvalue){ 204 + r(T pvalue)
  205 + {
152 if(pvalue < 0.0 || pvalue > 1.0) 206 if(pvalue < 0.0 || pvalue > 1.0)
153 return; 207 return;
154 T l = pvalue*L[L.size()-1]; 208 T l = pvalue*L[L.size()-1];
155 int idx = findIdx(l); 209 int idx = findIdx(l);
156 - return (mags[idx] + (mags[idx+1]-mags[idx])*((l-L[idx])/(L[idx+1]- L[idx]))); 210 + return (e[idx].U.len() + (e[idx+1].U.len() - e[idx].U.len())*((l-L[idx])/(L[idx+1]- L[idx])));
157 } 211 }
158 212
159 ///Returns a radius at the given length into the fiber (based on the pvalue). 213 ///Returns a radius at the given length into the fiber (based on the pvalue).
@@ -161,8 +215,10 @@ class cylinder @@ -161,8 +215,10 @@ class cylinder
161 ///@param l: the location of the in the cylinder. 215 ///@param l: the location of the in the cylinder.
162 ///@param idx: integer location of the point closest to l but prior to it. 216 ///@param idx: integer location of the point closest to l but prior to it.
163 T 217 T
164 - r(T l, int idx){  
165 - return (mags[idx] + (mags[idx+1]-mags[idx])*((l-L[idx])/(L[idx+1]- L[idx]))); 218 + r(T l, int idx)
  219 + {
  220 + T rat = (l-L[idx])/(L[idx+1]-L[idx]);
  221 + return( e[idx].U.len() + (e[idx+1].U.len() - e[idx].U.len())*rat);
166 } 222 }
167 223
168 /// Returns the magnitude at the given index 224 /// Returns the magnitude at the given index
@@ -192,8 +248,6 @@ class cylinder @@ -192,8 +248,6 @@ class cylinder
192 return mags[0].size(); 248 return mags[0].size();
193 } 249 }
194 250
195 -  
196 -  
197 ///returns the position of the point with a given pvalue and theta on the surface 251 ///returns the position of the point with a given pvalue and theta on the surface
198 ///in x, y, z coordinates. Theta is in degrees from 0 to 360. 252 ///in x, y, z coordinates. Theta is in degrees from 0 to 360.
199 ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1). 253 ///@param pvalue: the location of the in the cylinder, from 0 (beginning to 1).
@@ -202,46 +256,45 @@ class cylinder @@ -202,46 +256,45 @@ class cylinder
202 surf(T pvalue, T theta) 256 surf(T pvalue, T theta)
203 { 257 {
204 if(pvalue < 0.0 || pvalue > 1.0) 258 if(pvalue < 0.0 || pvalue > 1.0)
205 - return; 259 + {
  260 + return stim::vec<float>(-1,-1,-1);
  261 + } else {
206 T l = pvalue*L[L.size()-1]; 262 T l = pvalue*L[L.size()-1];
207 int idx = findIdx(l); 263 int idx = findIdx(l);
208 - stim::vec<T> ps = p(l, idx); 264 + stim::vec<T> ps = p(l, idx);
209 T m = r(l, idx); 265 T m = r(l, idx);
210 - stim::vec<T> dr = d(idx);  
211 - s = stim::circle<T>(ps, m, dr); 266 + s = e[idx];
  267 + s.center(ps);
  268 + s.normal(d(l, idx));
  269 + s.scale(m/e[idx].U.len());
212 return(s.p(theta)); 270 return(s.p(theta));
  271 + }
213 } 272 }
214 273
215 ///returns a vector of points necessary to create a circle at every position in the fiber. 274 ///returns a vector of points necessary to create a circle at every position in the fiber.
216 - ///@param sides: the number of sides of each circle. 275 + ///@param sides: the number of sides of each circle.
217 std::vector<std::vector<vec<T> > > 276 std::vector<std::vector<vec<T> > >
218 getPoints(int sides) 277 getPoints(int sides)
219 { 278 {
220 - if(pos.size() < 2) 279 + std::vector<std::vector <vec<T> > > points;
  280 + points.resize(e.size());
  281 + for(int i = 0; i < e.size(); i++)
221 { 282 {
222 - return;  
223 - } else {  
224 - std::vector<std::vector <vec<T> > > points;  
225 - points.resize(pos.size());  
226 - stim::vec<T> d = (pos[0] - pos[1]).norm();  
227 - s = stim::circle<T>(pos[0], mags[0][0], d);  
228 - points[0] = s.getPoints(sides);  
229 - for(int i = 1; i < pos.size(); i++)  
230 - {  
231 - d = (pos[i] - pos[i-1]).norm();  
232 - s.center(pos[i]);  
233 - s.normal(d);  
234 - s.scale(mags[i][0]/mags[i-1][0], mags[i][0]/mags[i-1][0]);  
235 - points[i] = s.getPoints(sides);  
236 - }  
237 - return points; 283 + points[i] = e[i].getPoints(sides);
238 } 284 }
  285 + return points;
239 } 286 }
240 287
  288 + ///returns the total length of the line at index j.
  289 + T
  290 + getl(int j)
  291 + {
  292 + return (L[j]);
  293 + }
241 /// Allows a point on the centerline to be accessed using bracket notation 294 /// Allows a point on the centerline to be accessed using bracket notation
242 295
243 vec<T> operator[](unsigned int i){ 296 vec<T> operator[](unsigned int i){
244 - return pos[i]; 297 + return e[i].P;
245 } 298 }
246 299
247 /// Returns the total length of the cylinder centerline 300 /// Returns the total length of the cylinder centerline
@@ -294,13 +347,13 @@ class cylinder @@ -294,13 +347,13 @@ class cylinder
294 347
295 std::vector< vec<T> > result; 348 std::vector< vec<T> > result;
296 349
297 - vec<T> p0 = pos[0]; //initialize p0 to the first point on the centerline 350 + vec<T> p0 = e[i].P; //initialize p0 to the first point on the centerline
298 vec<T> p1; 351 vec<T> p1;
299 unsigned N = size(); //number of points in the current centerline 352 unsigned N = size(); //number of points in the current centerline
300 353
301 //for each line segment on the centerline 354 //for each line segment on the centerline
302 for(unsigned int i = 1; i < N; i++){ 355 for(unsigned int i = 1; i < N; i++){
303 - p1 = pos[i]; //get the second point in the line segment 356 + p1 = e[i].P; //get the second point in the line segment
304 357
305 vec<T> v = p1 - p0; //calculate the vector between these two points 358 vec<T> v = p1 - p0; //calculate the vector between these two points
306 T d = v.len(); //calculate the distance between these two points (length of the line segment) 359 T d = v.len(); //calculate the distance between these two points (length of the line segment)
@@ -317,12 +370,13 @@ class cylinder @@ -317,12 +370,13 @@ class cylinder
317 p0 = p1; //shift the points to move to the next line segment 370 p0 = p1; //shift the points to move to the next line segment
318 } 371 }
319 372
320 - result.push_back(pos[size() - 1]); //push the last point in the centerline 373 + result.push_back(e[size() - 1].P); //push the last point in the centerline
321 374
322 return cylinder<T>(result); 375 return cylinder<T>(result);
323 376
324 } 377 }
325 378
  379 +
326 }; 380 };
327 381
328 } 382 }