Commit 88088186b35fbdc00bb2b844c351a647b922ea6c

Authored by David Mayerich
2 parents 5bccf89d bf23ee36

Merge branch 'Glnetwork'

stim/cuda/arraymath/array_cart2polar.cuh
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 namespace stim{ 4 namespace stim{
5 namespace cuda{ 5 namespace cuda{
6 template<typename T> 6 template<typename T>
7 - __global__ void cuda_cart2polar(T* a, int x, int y){ 7 + __global__ void cuda_cart2polar(T* a, int x, int y, float rotation){
8 8
9 9
10 // calculate the 2D coordinates for this current thread. 10 // calculate the 2D coordinates for this current thread.
@@ -20,21 +20,21 @@ namespace stim{ @@ -20,21 +20,21 @@ namespace stim{
20 float yl = a[i * 2 + 1]; 20 float yl = a[i * 2 + 1];
21 float theta = atan2( yl, xl ) ; 21 float theta = atan2( yl, xl ) ;
22 float r = sqrt(xl * xl + yl * yl); 22 float r = sqrt(xl * xl + yl * yl);
23 - a[i * 2 + 0] = theta; 23 + a[i * 2 + 0] = theta + rotation;
24 a[i * 2 + 1] = r; 24 a[i * 2 + 1] = r;
25 25
26 } 26 }
27 27
28 28
29 template<typename T> 29 template<typename T>
30 - void gpu_cart2polar(T* gpuGrad, unsigned int x, unsigned int y){ 30 + void gpu_cart2polar(T* gpuGrad, unsigned int x, unsigned int y, float rotation = 0){
31 31
32 unsigned int max_threads = stim::maxThreadsPerBlock(); 32 unsigned int max_threads = stim::maxThreadsPerBlock();
33 dim3 threads(max_threads, 1); 33 dim3 threads(max_threads, 1);
34 dim3 blocks(x/threads.x + (x %threads.x == 0 ? 0:1) , y); 34 dim3 blocks(x/threads.x + (x %threads.x == 0 ? 0:1) , y);
35 35
36 //call the kernel to do the multiplication 36 //call the kernel to do the multiplication
37 - cuda_cart2polar <<< blocks, threads >>>(gpuGrad, x, y); 37 + cuda_cart2polar <<< blocks, threads >>>(gpuGrad, x, y, rotation);
38 38
39 } 39 }
40 40
@@ -67,4 +67,4 @@ namespace stim{ @@ -67,4 +67,4 @@ namespace stim{
67 } 67 }
68 } 68 }
69 69
70 -#endif  
71 \ No newline at end of file 70 \ No newline at end of file
  71 +#endif
stim/cuda/branch_detection.cuh 0 → 100644
  1 +#include <iostream>
  2 +#include <fstream>
  3 +#include <cuda_runtime.h>
  4 +#include <stim/math/vector.h>
  5 +//#include <math.h>
  6 +#include <stim/visualization/colormap.h>
  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>
  13 +typedef unsigned int uint;
  14 +typedef unsigned int uchar;
  15 +
  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 +
  90 +std::vector< stim::vec<float> >
  91 +find_branch(GLint texbufferID, GLenum texType, unsigned int x, unsigned int y)
  92 +{
  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);
  108 +
  109 + stringstream name;
  110 +
  111 +
  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 + );
  126 + cudaDeviceSynchronize();
  127 +
  128 +
  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 +
  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 + }
  146 +
  147 + 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++)
  151 + {
  152 + int ix = (i % x);
  153 + int iy = (i / x);
  154 + if((cpuCenters[i] == 1) && (ix > 4) && (ix < x-4))
  155 + {
  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 + }
  163 + }
  164 +
  165 +
  166 + t.UnmapCudaTexture();
  167 + cleanCuda();
  168 + free(cpuTable);
  169 + free(cpuCenters);
  170 + return output;
  171 +}
stim/cuda/branch_detection2.cuh 0 → 100644
  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 0 → 100644
  1 +#ifndef STIM_CUDA_TEXTURE_H
  2 +#define STIM_CUDA_TEXTURE_H
  3 +
  4 +#include <assert.h>
  5 +#include <stim/cuda/cudatools/error.h>
  6 +#include <cuda.h>
  7 +#include <cuda_runtime.h>
  8 +#include <cublas_v2.h>
  9 +#include <stdio.h>
  10 +#include <GL/glew.h>
  11 +#include <GL/glut.h>
  12 +#include <sstream>
  13 +#include <stim/visualization/colormap.h>
  14 +#include <stim/cuda/cudatools/devices.h>
  15 +#include <stim/cuda/cudatools/threads.h>
  16 +#include <stim/math/vector.h>
  17 +
  18 +///A container for the texture based methods used by the spider class.
  19 +namespace stim
  20 +{
  21 + namespace cuda
  22 + {
  23 + class cuda_texture
  24 + {
  25 + public:
  26 + cudaArray* srcArray;
  27 + cudaGraphicsResource_t resource;
  28 + struct cudaResourceDesc resDesc;
  29 + struct cudaTextureDesc texDesc;
  30 + cudaTextureObject_t tObj;
  31 +
  32 +
  33 + ///basic constructor that creates the texture with default parameters.
  34 + cuda_texture()
  35 + {
  36 + memset(&texDesc, 0, sizeof(texDesc));
  37 + texDesc.addressMode[0] = cudaAddressModeWrap;
  38 + texDesc.addressMode[1] = cudaAddressModeWrap;
  39 + texDesc.filterMode = cudaFilterModePoint;
  40 + texDesc.readMode = cudaReadModeElementType;
  41 + texDesc.normalizedCoords = 0;
  42 + }
  43 +
  44 +//-------------------------------------------------------------------------//
  45 +//-------------------------------CUDA_MAPPING------------------------------//
  46 +//-------------------------------------------------------------------------//
  47 +//Methods for creating the cuda texture.
  48 + ///@param GLuint tex -- GLtexture (must be contained in a frame buffer object)
  49 + /// that holds that data that will be handed to cuda.
  50 + ///@param GLenum target -- either GL_TEXTURE_1D, GL_TEXTURE_2D or GL_TEXTURE_3D
  51 + /// map work with other gl texture types but untested.
  52 + ///Maps the gl texture in cuda memory, binds that data to a cuda array, and binds the cuda
  53 + ///array to a cuda texture.
  54 + void
  55 + MapCudaTexture(GLuint tex, GLenum target)
  56 + {
  57 + HANDLE_ERROR(
  58 + cudaGraphicsGLRegisterImage(
  59 + &resource,
  60 + tex,
  61 + target,
  62 +// cudaGraphicsMapFlagsReadOnly
  63 + cudaGraphicsRegisterFlagsNone
  64 + )
  65 + );
  66 +
  67 + HANDLE_ERROR(
  68 + cudaGraphicsMapResources(1, &resource)
  69 + );
  70 +
  71 + HANDLE_ERROR(
  72 + cudaGraphicsSubResourceGetMappedArray(&srcArray, resource, 0, 0)
  73 + );
  74 +
  75 + memset(&resDesc, 0, sizeof(resDesc));
  76 + resDesc.resType = cudaResourceTypeArray;
  77 + resDesc.res.array.array = srcArray;
  78 + HANDLE_ERROR(
  79 + cudaCreateTextureObject(&tObj, &resDesc, &texDesc, NULL)
  80 + );
  81 + }
  82 +
  83 + ///Unmaps the gl texture, binds that data to a cuda array, and binds the cuda
  84 + ///array to a cuda texture.
  85 + void
  86 + UnmapCudaTexture()
  87 + {
  88 + HANDLE_ERROR(
  89 + cudaGraphicsUnmapResources(1, &resource)
  90 + );
  91 + HANDLE_ERROR(
  92 + cudaGraphicsUnregisterResource(resource)
  93 + );
  94 + HANDLE_ERROR(
  95 + cudaDestroyTextureObject(tObj)
  96 + );
  97 + }
  98 +
  99 +//-------------------------------------------------------------------------//
  100 +//------------------------------GET/SET METHODS----------------------------//
  101 +//-------------------------------------------------------------------------//
  102 +
  103 +///Returns the bound texture object.
  104 + cudaTextureObject_t
  105 + getTexture()
  106 + {
  107 + return tObj;
  108 + }
  109 +
  110 + cudaArray*
  111 + getArray()
  112 + {
  113 + return srcArray;
  114 + }
  115 + };
  116 +}
  117 +}
  118 +
  119 +
  120 +#endif
stim/cuda/cudatools/devices.h
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 #include <cuda.h> 4 #include <cuda.h>
5 5
6 namespace stim{ 6 namespace stim{
7 - 7 +extern "C"
8 int maxThreadsPerBlock() 8 int maxThreadsPerBlock()
9 { 9 {
10 int device; 10 int device;
@@ -14,6 +14,7 @@ int maxThreadsPerBlock() @@ -14,6 +14,7 @@ int maxThreadsPerBlock()
14 return props.maxThreadsPerBlock; 14 return props.maxThreadsPerBlock;
15 } 15 }
16 16
  17 +extern "C"
17 int sharedMemPerBlock() 18 int sharedMemPerBlock()
18 { 19 {
19 int device; 20 int device;
stim/cuda/ivote/update_dir.cuh
@@ -164,6 +164,9 @@ namespace stim{ @@ -164,6 +164,9 @@ namespace stim{
164 //free allocated memory 164 //free allocated memory
165 cudaFree(gpuDir); 165 cudaFree(gpuDir);
166 166
  167 + cudaDestroyTextureObject(texObj);
  168 + cudaFreeArray(cuArray);
  169 +
167 } 170 }
168 171
169 template<typename T> 172 template<typename T>
@@ -211,4 +214,4 @@ namespace stim{ @@ -211,4 +214,4 @@ namespace stim{
211 } 214 }
212 } 215 }
213 216
214 -#endif  
215 \ No newline at end of file 217 \ No newline at end of file
  218 +#endif
stim/cuda/ivote/vote.cuh
@@ -124,6 +124,9 @@ namespace stim{ @@ -124,6 +124,9 @@ namespace stim{
124 124
125 cuda_vote <<< blocks, threads,share_bytes >>>(gpuVote, texObj, gpuTable, phi, rmax, x , y); 125 cuda_vote <<< blocks, threads,share_bytes >>>(gpuVote, texObj, gpuTable, phi, rmax, x , y);
126 126
  127 + cudaDestroyTextureObject(texObj);
  128 + cudaFreeArray(cuArray);
  129 +
127 } 130 }
128 131
129 132
@@ -169,4 +172,4 @@ namespace stim{ @@ -169,4 +172,4 @@ namespace stim{
169 } 172 }
170 } 173 }
171 174
172 -#endif  
173 \ No newline at end of file 175 \ No newline at end of file
  176 +#endif
stim/cuda/sharedmem.cuh
@@ -34,9 +34,38 @@ namespace stim{ @@ -34,9 +34,38 @@ namespace stim{
34 } 34 }
35 } 35 }
36 } 36 }
  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 + }
37 66
38 } 67 }
39 } 68 }
40 69
41 70
42 -#endif  
43 \ No newline at end of file 71 \ No newline at end of file
  72 +#endif
stim/cuda/spider_cost.cuh 0 → 100644
  1 +#ifndef STIM_SPIDER_COST_H
  2 +#define STIM_SPIDER_COST_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/math/vector.h>
  11 +#include <stim/cuda/cudatools/devices.h>
  12 +#include <stim/cuda/cudatools/threads.h>
  13 +#include <stim/cuda/cuda_texture.cuh>
  14 +namespace stim{
  15 + namespace cuda
  16 + {
  17 +
  18 + stim::cuda::cuda_texture t; //texture object.
  19 + float* result;
  20 + float* print;
  21 +
  22 + ///Initialization function, allocates the memory and passes the necessary
  23 + ///handles from OpenGL and Cuda.
  24 + ///@param DIM_Y --integer controlling how much memory to allocate.
  25 + void initArray(int DIM_Y)
  26 + {
  27 +// cudaMalloc( (void**) &print, DIM_Y*16*sizeof(float)); ///temporary
  28 + cudaMalloc( (void**) &result, DIM_Y*sizeof(float));
  29 + }
  30 +
  31 + ///Deinit function that frees the memery used and releases the texture resource
  32 + ///back to OpenGL.
  33 + void cleanUP()
  34 + {
  35 + cudaFree(result);
  36 +// cudaFree(print); ///temporary
  37 + }
  38 +
  39 + ///A virtual representation of a uniform template.
  40 + ///Returns the value of the template pixel.
  41 + ///@param int x --location of a pixel.
  42 + __device__
  43 + float Template(int x)
  44 + {
  45 + if(x < 16/6 || x > 16*5/6 || (x > 16*2/6 && x < 16*4/6)){
  46 + return 1.0;
  47 + }else{
  48 + return 0.0;
  49 + }
  50 +
  51 + }
  52 +
  53 + ///Find the difference of the given set of samples and the template
  54 + ///using cuda acceleration.
  55 + ///@param stim::cuda::cuda_texture t --stim texture that holds all the references
  56 + /// to the data.
  57 + ///@param float* result --a pointer to the memory that stores the result.
  58 + __global__
  59 + //void get_diff (float *result)
  60 + void get_diff (cudaTextureObject_t texIn, float *result)
  61 + {
  62 + __shared__ float shared[16][8];
  63 + int x = threadIdx.x + blockIdx.x * blockDim.x;
  64 + int y = threadIdx.y + blockIdx.y * blockDim.y;
  65 + int x_t = threadIdx.x;
  66 + int y_t = threadIdx.y;
  67 +// int idx = y*16+x;
  68 + int g_idx = blockIdx.y;
  69 +
  70 + float valIn = tex2D<unsigned char>(texIn, x, y)/255.0;
  71 + float valTemp = Template(x);
  72 +
  73 +// print[idx] = abs(valIn); ///temporary
  74 +
  75 + shared[x_t][y_t] = abs(valIn-valTemp);
  76 +
  77 + __syncthreads();
  78 +
  79 + for(unsigned int step = blockDim.x/2; step >= 1; step >>= 1)
  80 + {
  81 + __syncthreads();
  82 + if (x_t < step)
  83 + {
  84 + shared[x_t][y_t] += shared[x_t + step][y_t];
  85 + }
  86 + __syncthreads();
  87 + }
  88 + __syncthreads();
  89 +
  90 + for(unsigned int step = blockDim.y/2; step >= 1; step >>= 1)
  91 + {
  92 + __syncthreads();
  93 + if(y_t < step)
  94 + {
  95 + shared[x_t][y_t] += shared[x_t][y_t + step];
  96 + }
  97 + __syncthreads();
  98 + }
  99 + __syncthreads();
  100 + if(x_t == 0 && y_t == 0)
  101 + result[g_idx] = shared[0][0];
  102 +
  103 +
  104 + // //result[idx] = abs(valIn);
  105 + }
  106 +
  107 +
  108 + ///External access-point to the cuda function
  109 + ///@param GLuint texbufferID --GLtexture (most be contained in a framebuffer object)
  110 + /// that holds the data that will be handed to cuda.
  111 + ///@param GLenum texType --either GL_TEXTURE_1D, GL_TEXTURE_2D or GL_TEXTURE_3D
  112 + /// may work with other gl texture types, but untested.
  113 + ///@param DIM_Y, the number of samples in the template.
  114 + extern "C"
  115 + stim::vec<int> get_cost(GLint texbufferID, GLenum texType, int DIM_Y)
  116 + {
  117 +
  118 + //Bind the Texture in GL and allow access to cuda.
  119 + t.MapCudaTexture(texbufferID, texType);
  120 +
  121 + //initialize the return arrays.
  122 + float* output;
  123 + output = (float* ) malloc(DIM_Y*sizeof(float));
  124 +
  125 + stim::vec<int> ret(0, 0);
  126 + initArray(DIM_Y);
  127 +
  128 +
  129 + //variables for finding the min.
  130 + float mini = 10000000000000000.0;
  131 + int idx = 0;
  132 +
  133 + //cuda launch variables.
  134 + dim3 numBlocks(1, DIM_Y);
  135 + dim3 threadsPerBlock(16, 8);
  136 +
  137 +
  138 + get_diff <<< numBlocks, threadsPerBlock >>> (t.getTexture(), result);
  139 +
  140 + HANDLE_ERROR(
  141 + cudaMemcpy(output, result, DIM_Y*sizeof(float), cudaMemcpyDeviceToHost)
  142 + );
  143 +
  144 + for( int i = 0; i<DIM_Y; i++){
  145 + if(output[i] < mini){
  146 + mini = output[i];
  147 + idx = i;
  148 + }
  149 + }
  150 +
  151 +// stringstream name; //for debugging
  152 +// name << "Test.bmp";
  153 +// stim::gpu2image<float>(print, name.str(),16,218,0,256);
  154 +
  155 + t.UnmapCudaTexture();
  156 + cleanUP();
  157 + ret[0] = idx; ret[1] = (int) output[idx];
  158 + free(output);
  159 + return ret;
  160 + }
  161 +
  162 + }
  163 +}
  164 +
  165 +
  166 +#endif
stim/cuda/templates/conv2.cuh
@@ -102,8 +102,10 @@ namespace stim{ @@ -102,8 +102,10 @@ namespace stim{
102 dim3 blocks(w / threads + 1, h); 102 dim3 blocks(w / threads + 1, h);
103 103
104 //call the kernel to do the multiplication 104 //call the kernel to do the multiplication
105 - cuda_conv2 <<< blocks, threads >>>(mask, copy, texObj, w, h, M);  
106 - 105 + //cuda_conv2 <<< blocks, threads >>>(img, mask, copy, w, h, M);
  106 + cuda_conv2 <<< blocks, threads >>>(img, mask, copy, texObj, w, h, M);
  107 + cudaDestroyTextureObject(texObj);
  108 + cudaFreeArray(cuArray);
107 } 109 }
108 110
109 template<typename T> 111 template<typename T>
@@ -139,4 +141,4 @@ namespace stim{ @@ -139,4 +141,4 @@ namespace stim{
139 } 141 }
140 142
141 143
142 -#endif  
143 \ No newline at end of file 144 \ No newline at end of file
  145 +#endif
stim/cuda/templates/conv2sep.cuh
@@ -30,7 +30,7 @@ namespace stim{ @@ -30,7 +30,7 @@ namespace stim{
30 int byi = blockIdx.y; 30 int byi = blockIdx.y;
31 31
32 //copy the portion of the image necessary for this block to shared memory 32 //copy the portion of the image necessary for this block to shared memory
33 - stim::cuda::sharedMemcpy_tex2D(s, in, bxi - kr, byi, 2 * kr + blockDim.x, 1, threadIdx, blockDim); 33 + stim::cuda::sharedMemcpy_tex2D<float, unsigned char>(s, in, bxi - kr, byi, 2 * kr + blockDim.x, 1, threadIdx, blockDim);
34 34
35 //calculate the thread index 35 //calculate the thread index
36 int ti = threadIdx.x; 36 int ti = threadIdx.x;
@@ -88,7 +88,7 @@ namespace stim{ @@ -88,7 +88,7 @@ namespace stim{
88 int byi = blockIdx.y * blockDim.y; 88 int byi = blockIdx.y * blockDim.y;
89 89
90 //copy the portion of the image necessary for this block to shared memory 90 //copy the portion of the image necessary for this block to shared memory
91 - stim::cuda::sharedMemcpy_tex2D(s, in, bxi, byi - kr, 1, 2 * kr + blockDim.y, threadIdx, blockDim); 91 + stim::cuda::sharedMemcpy_tex2D<float, unsigned char>(s, in, bxi, byi - kr, 1, 2 * kr + blockDim.y, threadIdx, blockDim);
92 92
93 //calculate the thread index 93 //calculate the thread index
94 int ti = threadIdx.y; 94 int ti = threadIdx.y;
@@ -213,6 +213,8 @@ namespace stim{ @@ -213,6 +213,8 @@ namespace stim{
213 //free allocated memory 213 //free allocated memory
214 cudaFree(cuArray); 214 cudaFree(cuArray);
215 215
  216 + cudaDestroyTextureObject(texObj);
  217 +
216 } 218 }
217 219
218 /// Applies a Gaussian blur to a 2D image stored on the CPU 220 /// Applies a Gaussian blur to a 2D image stored on the CPU
@@ -257,4 +259,4 @@ namespace stim{ @@ -257,4 +259,4 @@ namespace stim{
257 }; 259 };
258 }; 260 };
259 261
260 -#endif  
261 \ No newline at end of file 262 \ No newline at end of file
  263 +#endif
stim/cuda/templates/gaussian_blur.cuh
@@ -7,7 +7,6 @@ @@ -7,7 +7,6 @@
7 #include <stim/cuda/sharedmem.cuh> 7 #include <stim/cuda/sharedmem.cuh>
8 #include <stim/cuda/templates/conv2sep.cuh> //GPU-based separable convolution algorithm 8 #include <stim/cuda/templates/conv2sep.cuh> //GPU-based separable convolution algorithm
9 9
10 -#define pi 3.14159  
11 10
12 namespace stim{ 11 namespace stim{
13 namespace cuda{ 12 namespace cuda{
@@ -37,12 +36,14 @@ namespace stim{ @@ -37,12 +36,14 @@ namespace stim{
37 36
38 //copy the kernel to the GPU 37 //copy the kernel to the GPU
39 T* gpuKernel0; 38 T* gpuKernel0;
  39 + HANDLE_ERROR(cudaMalloc(&gpuKernel0, kwidth*sizeof(T)));
40 HANDLE_ERROR(cudaMemcpy(gpuKernel0, kernel0, kwidth * sizeof(T), cudaMemcpyHostToDevice)); 40 HANDLE_ERROR(cudaMemcpy(gpuKernel0, kernel0, kwidth * sizeof(T), cudaMemcpyHostToDevice));
41 41
42 //perform the gaussian blur as a separable convolution 42 //perform the gaussian blur as a separable convolution
43 stim::cuda::tex_conv2sep(out, x, y, texObj, cuArray, gpuKernel0, kwidth, gpuKernel0, kwidth); 43 stim::cuda::tex_conv2sep(out, x, y, texObj, cuArray, gpuKernel0, kwidth, gpuKernel0, kwidth);
44 44
45 HANDLE_ERROR(cudaFree(gpuKernel0)); 45 HANDLE_ERROR(cudaFree(gpuKernel0));
  46 + free(kernel0);
46 47
47 } 48 }
48 49
@@ -58,7 +59,7 @@ namespace stim{ @@ -58,7 +59,7 @@ namespace stim{
58 59
59 //copy the kernel to the GPU 60 //copy the kernel to the GPU
60 T* gpuKernel0; 61 T* gpuKernel0;
61 - HANDLE_ERROR(cudaMalloc(&gpuKernel0, kwidth * sizeof(T))); 62 + HANDLE_ERROR(cudaMalloc(&gpuKernel0, kwidth*sizeof(T)));
62 HANDLE_ERROR(cudaMemcpy(gpuKernel0, kernel0, kwidth * sizeof(T), cudaMemcpyHostToDevice)); 63 HANDLE_ERROR(cudaMemcpy(gpuKernel0, kernel0, kwidth * sizeof(T), cudaMemcpyHostToDevice));
63 64
64 //perform the gaussian blur as a separable convolution 65 //perform the gaussian blur as a separable convolution
@@ -87,4 +88,4 @@ namespace stim{ @@ -87,4 +88,4 @@ namespace stim{
87 }; 88 };
88 }; 89 };
89 90
90 -#endif  
91 \ No newline at end of file 91 \ No newline at end of file
  92 +#endif
stim/cuda/testKernel.cuh 0 → 100644
  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 +#include <stim/math/vector.h>
  8 +#include <stim/cuda/cudatools/devices.h>
  9 +#include <stim/cuda/cudatools/threads.h>
  10 +#include <stim/cuda/cuda_texture.cuh>
  11 + stim::cuda::cuda_texture tx; //texture object.
  12 + float* print;
  13 +
  14 + ///Initialization function, allocates the memory and passes the necessary
  15 + ///handles from OpenGL and Cuda.
  16 + ///@param DIM_Y --integer controlling how much memory to allocate.
  17 + void initArray()
  18 + {
  19 + cudaMalloc( (void**) &print, 216*16*sizeof(float)); ///temporary
  20 + }
  21 +
  22 + ///Deinit function that frees the memery used and releases the texture resource
  23 + ///back to OpenGL.
  24 + void cleanUP()
  25 + {
  26 + cudaFree(print); ///temporary
  27 + }
  28 +
  29 + __device__
  30 + float templ(int x)
  31 + {
  32 + if(x < 16/6 || x > 16*5/6 || (x > 16*2/6 && x < 16*4/6)){
  33 + return 1.0;
  34 + }else{
  35 + return 0.0;
  36 + }
  37 +
  38 + }
  39 +
  40 + ///Find the difference of the given set of samples and the template
  41 + ///using cuda acceleration.
  42 + ///@param stim::cuda::cuda_texture t --stim texture that holds all the references
  43 + /// to the data.
  44 + ///@param float* result --a pointer to the memory that stores the result.
  45 + __global__
  46 + //void get_diff (float *result)
  47 + void get_diff (cudaTextureObject_t texIn, float *print)
  48 + {
  49 + int x = threadIdx.x + blockIdx.x * blockDim.x;
  50 + int y = threadIdx.y + blockIdx.y * blockDim.y;
  51 + int idx = y*16+x;
  52 +
  53 + float valIn = tex2D<unsigned char>(texIn, x, y);
  54 + float templa = templ(x);
  55 + //print[idx] = abs(valIn); ///temporary
  56 + print[idx] = abs(templa); ///temporary
  57 +
  58 + }
  59 +
  60 +
  61 + ///External access-point to the cuda function
  62 + ///@param GLuint texbufferID --GLtexture (most be contained in a framebuffer object)
  63 + /// that holds the data that will be handed to cuda.
  64 + ///@param GLenum texType --either GL_TEXTURE_1D, GL_TEXTURE_2D or GL_TEXTURE_3D
  65 + /// may work with other gl texture types, but untested.
  66 + ///@param DIM_Y, the number of samples in the template.
  67 + void test(GLint texbufferID, GLenum texType)
  68 + {
  69 +
  70 + //Bind the Texture in GL and allow access to cuda.
  71 + tx.MapCudaTexture(texbufferID, texType);
  72 +
  73 + //initialize the return arrays.
  74 +
  75 + initArray();
  76 +
  77 + int x = 16;
  78 + int y = 27*8;
  79 + y = 8* 1089;
  80 + int max_threads = stim::maxThreadsPerBlock();
  81 + //dim3 threads(max_threads, 1);
  82 + //dim3 blocks(x / threads.x + 1, y);
  83 + dim3 numBlocks(1, 1089);
  84 + dim3 threadsPerBlock(16, 8);
  85 + //dim3 numBlocks(2, 2);
  86 + //dim3 threadsPerBlock(8, 108);
  87 +
  88 +
  89 +// get_diff <<< blocks, threads >>> (tx.getTexture(), print);
  90 + get_diff <<< numBlocks, threadsPerBlock >>> (tx.getTexture(), print);
  91 +
  92 + cudaDeviceSynchronize();
  93 + stringstream name; //for debugging
  94 + name << "FromTex.bmp";
  95 + stim::gpu2image<float>(print, name.str(),16,1089*8,0,1.0);
  96 +
  97 + tx.UnmapCudaTexture();
  98 + cleanUP();
  99 + }
  100 +
stim/gl/gl_spider.h
@@ -13,50 +13,101 @@ @@ -13,50 +13,101 @@
13 #include "stim/math/vector.h" 13 #include "stim/math/vector.h"
14 #include "stim/math/rect.h" 14 #include "stim/math/rect.h"
15 #include "stim/math/matrix.h" 15 #include "stim/math/matrix.h"
16 -#include "stim/cuda/cost.h" 16 +#include "stim/cuda/spider_cost.cuh"
17 #include <stim/cuda/cudatools/glbind.h> 17 #include <stim/cuda/cudatools/glbind.h>
18 -#include <stim/visualization/obj.h> 18 +#include <stim/cuda/arraymath.cuh>
  19 +#include <stim/cuda/cudatools.h>
  20 +#include <stim/cuda/ivote.cuh>
  21 +#include <stim/visualization/glObj.h>
19 #include <vector> 22 #include <vector>
  23 +#include <stim/cuda/branch_detection.cuh>
  24 +#include "../../../volume-spider/fiber.h"
  25 +#include "../../../volume-spider/glnetwork.h"
  26 +//#include <stim/cuda/testKernel.cuh>
  27 +
  28 +//#include <stim/cuda/testKernel.cuh>
20 29
21 #include <iostream> 30 #include <iostream>
22 #include <fstream> 31 #include <fstream>
  32 +#ifdef TESTING
  33 + #include <iostream>
  34 + #include <cstdio>
  35 + #include <ctime>
  36 +#endif
23 37
24 38
25 -  
26 -/* Technically since gl_spider inherits from gl_texture, we could  
27 - call the init with a path to an image stack, and upload  
28 - the images while creating the spider (calling init) */  
29 namespace stim 39 namespace stim
30 { 40 {
31 41
32 template<typename T> 42 template<typename T>
33 -class gl_spider 43 +class gl_spider : public virtual gl_texture<T>
34 { 44 {
35 //doen't use gl_texture really, just needs the GLuint id. 45 //doen't use gl_texture really, just needs the GLuint id.
36 //doesn't even need the texture iD really. 46 //doesn't even need the texture iD really.
37 private: 47 private:
  48 +
  49 + //
38 stim::vec<float> p; //vector designating the position of the spider. 50 stim::vec<float> p; //vector designating the position of the spider.
39 stim::vec<float> d; //vector designating the orientation of the spider 51 stim::vec<float> d; //vector designating the orientation of the spider
40 //always a unit vector. 52 //always a unit vector.
41 stim::vec<float> m; //magnitude of the spider vector. 53 stim::vec<float> m; //magnitude of the spider vector.
42 //mag[0] = length. 54 //mag[0] = length.
43 //mag[1] = width. 55 //mag[1] = width.
44 - std::vector<stim::vec<float> > dV;  
45 - std::vector<stim::vec<float> > pV;  
46 - std::vector<stim::vec<float> > mV;  
47 - //currentTransform  
48 - stim::matrix<float, 4> cT; 56 + std::vector<stim::vec<float> > dV; //A list of all the direction vectors.
  57 + std::vector<stim::vec<float> > pV; //A list of all the position vectors.
  58 + std::vector<stim::vec<float> > mV; //A list of all the size vectors.
  59 +
  60 + stim::matrix<float, 4> cT; //current Transformation matrix
  61 + //From tissue space to texture space.
49 GLuint texID; 62 GLuint texID;
50 - stim::vec<float> S;  
51 - stim::vec<float> R;  
52 - cudaGraphicsResource_t resource; 63 + stim::vec<float> S; //Size of a voxel in the volume.
  64 + stim::vec<float> R; //Dimensions of the volume.
  65 +
  66 +
  67 + //GL and Cuda variables
  68 + GLuint dList; //displaylist ID
  69 + GLuint fboID; //framebuffer ID
  70 + GLuint texbufferID; //texbuffer ID, only necessary for
  71 + //cuda aspect of the calculation.
  72 + GLuint pfboID; //buffer object for position tracking.
  73 + GLuint ptexbufferID; //texture object for position tracking.
  74 +
  75 + GLuint mfboID; //buffer object for magnitude adjustment.
  76 + GLuint mtexbufferID; //texture object for magnitude adjustment.
  77 + GLuint bfboID; //buffer object for position adjustment.
  78 + GLuint btexbufferID; //buffer object for position adjustment.
  79 +
  80 + int numSamples; //The number of templates in the buffer.
  81 + int numSamplesPos;
  82 + int numSamplesMag;
  83 +
  84 +// float stepsize = 4.0; //Step size.
  85 + float stepsize = 3.0; //Step size.
  86 + int current_cost; //variable to store the cost of the current step.
  87 +
  88 +
  89 + //Tracing variables.
  90 + std::stack< stim::vec<float> > seeds; //seed positions.
  91 + std::stack< stim::vec<float> > seedsvecs; //seed directions.
  92 + std::stack< float > seedsmags; //seed magnitudes.
53 93
54 - GLuint dList;  
55 - GLuint fboID;  
56 - GLuint texbufferID;  
57 - int numSamples;  
58 - float stepsize = 3.0;  
59 - int current_cost; 94 + std::vector< stim::vec<float> > cL; //Positions of line currently being traced.
  95 + 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 +
  98 + stim::glObj<float> sk; //object to store the skeleton.
  99 + stim::glnetwork<float> nt; //object for storing the network.
  100 +
  101 + stim::vec<float> rev; //reverse vector;
  102 + stim::camera camSel;
  103 + stim::vec<float> ps;
  104 + stim::vec<float> ups;
  105 + stim::vec<float> ds;
  106 +
  107 +
  108 +//--------------------------------------------------------------------------//
  109 +//-------------------------------PRIVATE METHODS----------------------------//
  110 +//--------------------------------------------------------------------------//
60 111
61 /// Method for finding the best scale for the spider. 112 /// Method for finding the best scale for the spider.
62 /// changes the x, y, z size of the spider to minimize the cost 113 /// changes the x, y, z size of the spider to minimize the cost
@@ -64,42 +115,43 @@ class gl_spider @@ -64,42 +115,43 @@ class gl_spider
64 void 115 void
65 findOptimalDirection() 116 findOptimalDirection()
66 { 117 {
67 - setMatrix();  
68 - glCallList(dList);  
69 - int best = getCost();  
70 - stim::vec<float> next( 118 + setMatrix(); //create the transformation matrix.
  119 + glCallList(dList); //move the templates to p, d, m.
  120 + int best = getCost(texbufferID,numSamples); //find min cost.
  121 + stim::vec<float> next( //find next vector.
71 dV[best][0]*S[0]*R[0], 122 dV[best][0]*S[0]*R[0],
72 dV[best][1]*S[1]*R[1], 123 dV[best][1]*S[1]*R[1],
73 dV[best][2]*S[2]*R[2], 124 dV[best][2]*S[2]*R[2],
74 0); 125 0);
75 - next = (cT*next).norm();  
76 - //next = (cT*next); 126 + next = (cT*next).norm(); //find next vector.
77 setPosition( p[0]+next[0]*m[0]/stepsize, 127 setPosition( p[0]+next[0]*m[0]/stepsize,
78 p[1]+next[1]*m[0]/stepsize, 128 p[1]+next[1]*m[0]/stepsize,
79 p[2]+next[2]*m[0]/stepsize); 129 p[2]+next[2]*m[0]/stepsize);
80 setDirection(next[0], next[1], next[2]); 130 setDirection(next[0], next[1], next[2]);
  131 + //move forward and change direction.
81 } 132 }
82 133
83 - /// Method for finding the best d for the spider.  
84 - /// Not sure if necessary since the next p for the spider 134 + /// Method for finding the best d (direction) for the spider.
  135 + /// Not sure if necessary since the next p (position) for the spider
85 /// will be at d * m. 136 /// will be at d * m.
86 void 137 void
87 findOptimalPosition() 138 findOptimalPosition()
88 { 139 {
89 - setMatrix();  
90 - glCallList(dList+1);  
91 - int best = getCost();  
92 - stim::vec<float> next(  
93 - pV[best][0],  
94 - pV[best][1],  
95 - pV[best][2],  
96 - 1);  
97 - next = cT*next; 140 + setMatrix(); //create the transformation matrix.
  141 + glCallList(dList+1); //move the templates to p, d, m.
  142 + int best = getCost(ptexbufferID, numSamplesPos); //find min cost.
  143 + std::cerr << best << std::endl;
  144 + stim::vec<float> next( //find next position.
  145 + pV[best][0],
  146 + pV[best][1],
  147 + pV[best][2],
  148 + 1);
  149 + next = cT*next; //find next position.
98 setPosition( 150 setPosition(
99 next[0]*S[0]*R[0], 151 next[0]*S[0]*R[0],
100 next[1]*S[1]*R[1], 152 next[1]*S[1]*R[1],
101 next[2]*S[2]*R[2] 153 next[2]*S[2]*R[2]
102 - ); 154 + ); //adjust position.
103 } 155 }
104 156
105 /// Method for finding the best scale for the spider. 157 /// Method for finding the best scale for the spider.
@@ -108,33 +160,64 @@ class gl_spider @@ -108,33 +160,64 @@ class gl_spider
108 void 160 void
109 findOptimalScale() 161 findOptimalScale()
110 { 162 {
111 - setMatrix();  
112 - glCallList(dList+2);  
113 - int best = getCost();  
114 - setMagnitude(m[0]*mV[best][0]); 163 + setMatrix(); //create the transformation.
  164 + glCallList(dList+2); //move the templates to p, d, m.
  165 + int best = getCost(mtexbufferID, numSamplesMag); //get best cost.
  166 + setMagnitude(m[0]*mV[best][0]); //adjust the magnitude.
115 } 167 }
116 168
  169 +
  170 + ///subject to change.
  171 + ///finds branches.
117 void 172 void
118 branchDetection() 173 branchDetection()
119 { 174 {
120 - Bind();  
121 setMatrix(); 175 setMatrix();
122 glCallList(dList+3); 176 glCallList(dList+3);
123 -  
124 - // int best = getCost(); 177 + std::vector< stim::vec<float> > result = find_branch(
  178 + btexbufferID, GL_TEXTURE_2D, 16, 216);
  179 + stim::vec<float> size(S[0]*R[0], S[1]*R[1], S[2]*R[2]);
  180 + if(!result.empty())
  181 + {
  182 + for(int i = 1; i < result.size(); i++)
  183 + {
  184 + stim::vec<float> cylp(
  185 + 0.5 * cos(2*M_PI*(result[i][1])),
  186 + 0.5 * sin(2*M_PI*(result[i][1])),
  187 + result[i][0]-0.5,
  188 + 1.0);
  189 + cylp = cT*cylp;
  190 +
  191 + stim::vec<float> vec(
  192 + cylp[0]*S[0]*R[0],
  193 + cylp[1]*S[1]*R[1],
  194 + cylp[2]*S[2]*R[2]);
  195 + stim::vec<float> seeddir(-p[0] + cylp[0]*S[0]*R[0],
  196 + -p[1] + cylp[1]*S[1]*R[1],
  197 + -p[2] + cylp[2]*S[2]*R[2]);
  198 + seeddir = seeddir.norm();
  199 +// float seedm = m[0]/2.0;
  200 + float seedm = m[0];
  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(
  208 + !(vec[0] > size[0] || vec[1] > size[1]
  209 + || vec[2] > size[2] || vec[0] < 0
  210 + || vec[1] < 0 || vec[2] < 0))
  211 + {
  212 + setSeed(vec);
  213 + setSeedVec(seeddir);
  214 + setSeedMag(seedm);
  215 + }
  216 + }
  217 + }
125 218
126 } 219 }
127 220
128 -  
129 -  
130 - void  
131 - Optimize()  
132 - {  
133 - /*find the optimum d and scale */  
134 - }  
135 -  
136 -  
137 -  
138 221
139 //--------------------------------------------------------------------------// 222 //--------------------------------------------------------------------------//
140 //---------------------TEMPLATE CREATION METHODS----------------------------// 223 //---------------------TEMPLATE CREATION METHODS----------------------------//
@@ -142,14 +225,15 @@ class gl_spider @@ -142,14 +225,15 @@ class gl_spider
142 225
143 ///@param solidAngle, the size of the arc to sample. 226 ///@param solidAngle, the size of the arc to sample.
144 ///Method for populating the vector arrays with sampled vectors. 227 ///Method for populating the vector arrays with sampled vectors.
  228 + ///Objects created are rectangles the with the created directions.
  229 + ///All points are sampled from a texture.
  230 + ///Stored in a display list.
145 ///uses the default d vector <0,0,1> 231 ///uses the default d vector <0,0,1>
146 void 232 void
147 - genDirectionVectors(float solidAngle = 3*M_PI/2) 233 + genDirectionVectors(float solidAngle = 5/M_PI*4)
148 { 234 {
149 - //ofstream file;  
150 - //file.open("dvectors.txt");  
151 //Set up the vectors necessary for Rectangle creation. 235 //Set up the vectors necessary for Rectangle creation.
152 - vec<float> Y(1.0,0.0,0.0); 236 + vec<float> Y(1.0,0.0,0.0); //orthogonal vec.
153 vec<float> pos(0.0,0.0,0.0); 237 vec<float> pos(0.0,0.0,0.0);
154 vec<float> mag(1.0, 1.0, 1.0); 238 vec<float> mag(1.0, 1.0, 1.0);
155 vec<float> dir(0.0, 0.0, 1.0); 239 vec<float> dir(0.0, 0.0, 1.0);
@@ -158,12 +242,12 @@ class gl_spider @@ -158,12 +242,12 @@ class gl_spider
158 vec<float> d_s = d.cart2sph().norm(); 242 vec<float> d_s = d.cart2sph().norm();
159 vec<float> temp(0,0,0); 243 vec<float> temp(0,0,0);
160 int dim = (sqrt(numSamples)-1)/2; 244 int dim = (sqrt(numSamples)-1)/2;
161 - float p0 = -M_PI;  
162 - float dt = solidAngle/(2.0 * ((float)dim + 1.0));  
163 - float dp = p0/(2.0*((float)dim + 1.0)); 245 + float p0 = -M_PI; //phi angle in spherical coordinates.
  246 + float dt = solidAngle/(2.0 * ((float)dim + 1.0)); //step size in Theta.
  247 + float dp = p0/(2.0*((float)dim + 1.0)); //step size in Phi.
164 248
165 - glNewList(dList, GL_COMPILE);  
166 - //Loop over the space 249 + glNewList(dList, GL_COMPILE);
  250 + //Loop over the above defined space creating distinct vectors.
167 int idx = 0; 251 int idx = 0;
168 for(int i = -dim; i <= dim; i++){ 252 for(int i = -dim; i <= dim; i++){
169 for(int j = -dim; j <= dim; j++){ 253 for(int j = -dim; j <= dim; j++){
@@ -192,28 +276,30 @@ class gl_spider @@ -192,28 +276,30 @@ class gl_spider
192 glEndList(); 276 glEndList();
193 } 277 }
194 278
195 - ///@param solidAngle, the size of the arc to sample. 279 + ///@param float delta, How much the rectangles vary in position.
196 ///Method for populating the buffer with the sampled texture. 280 ///Method for populating the buffer with the sampled texture.
  281 + ///Objects created are rectangles the with the created positions.
  282 + ///All points are sampled from a texture.
  283 + ///Stored in a display list.
197 ///uses the default vector <0,0,0> 284 ///uses the default vector <0,0,0>
198 void 285 void
199 genPositionVectors(float delta = 0.4) 286 genPositionVectors(float delta = 0.4)
200 { 287 {
201 //Set up the vectors necessary for Rectangle creation. 288 //Set up the vectors necessary for Rectangle creation.
202 - vec<float> Y(1.0,0.0,0.0); 289 + vec<float> Y(1.0,0.0,0.0); //orthogonal vec.
203 vec<float> pos(0.0,0.0,0.0); 290 vec<float> pos(0.0,0.0,0.0);
204 vec<float> mag(1.0, 1.0, 1.0); 291 vec<float> mag(1.0, 1.0, 1.0);
205 vec<float> dir(0.0, 0.0, 1.0); 292 vec<float> dir(0.0, 0.0, 1.0);
206 293
207 //Set up the variable necessary for vector creation. 294 //Set up the variable necessary for vector creation.
208 vec<float> temp(0,0,0); 295 vec<float> temp(0,0,0);
209 - int dim = (sqrt(numSamples)-1)/2;  
210 - stim::rect<float> samplingPlane = 296 + int dim = (sqrt(numSamplesPos)-1)/2; //number of position vectors.
  297 + stim::rect<float> samplingPlane = //plane from which we pull position samples
211 stim::rect<float>(p, d); 298 stim::rect<float>(p, d);
212 samplingPlane.scale(mag[0]*delta, mag[0]*delta); 299 samplingPlane.scale(mag[0]*delta, mag[0]*delta);
213 - float step = 1.0/(dim); 300 + float step = 1.0/(dim); //step size.
214 301
215 - //Loop over the samples, keeping the original p sample  
216 - //in the center of the resulting texture. 302 + //Loop over the samples, keeping the original p samples in the center of the resulting texture to create a large number of position vectors.
217 int idx; 303 int idx;
218 glNewList(dList+1, GL_COMPILE); 304 glNewList(dList+1, GL_COMPILE);
219 for(int i = -dim; i <= dim; i++){ 305 for(int i = -dim; i <= dim; i++){
@@ -240,30 +326,32 @@ class gl_spider @@ -240,30 +326,32 @@ class gl_spider
240 glEndList(); 326 glEndList();
241 } 327 }
242 328
243 - ///@param solidAngle, the size of the arc to sample. 329 + ///@param float delta, How much the rectangles are allowed to expand.
244 ///Method for populating the buffer with the sampled texture. 330 ///Method for populating the buffer with the sampled texture.
  331 + ///Objects created are rectangles the with the created sizes.
  332 + ///All points are sampled from a texture.
  333 + ///Stored in a display list.
245 ///uses the default m <1,1,0> 334 ///uses the default m <1,1,0>
246 void 335 void
247 genMagnitudeVectors(float delta = 0.70) 336 genMagnitudeVectors(float delta = 0.70)
248 -// genMagnitudeVectors(float delta = 0.50)  
249 { 337 {
250 338
251 //Set up the vectors necessary for Rectangle creation. 339 //Set up the vectors necessary for Rectangle creation.
252 - vec<float> Y(1.0,0.0,0.0); 340 + vec<float> Y(1.0,0.0,0.0); //orthogonal vec.
253 vec<float> pos(0.0,0.0,0.0); 341 vec<float> pos(0.0,0.0,0.0);
254 vec<float> mag(1.0, 1.0, 1.0); 342 vec<float> mag(1.0, 1.0, 1.0);
255 vec<float> dir(0.0, 0.0, 1.0); 343 vec<float> dir(0.0, 0.0, 1.0);
256 344
257 //Set up the variable necessary for vector creation. 345 //Set up the variable necessary for vector creation.
258 - int dim = (sqrt(numSamples)-1)/2; 346 + int dim = (sqrt(numSamplesMag)-1)/2;
259 float min = 1.0-delta; 347 float min = 1.0-delta;
260 float max = 1.0+delta; 348 float max = 1.0+delta;
261 - float step = (max-min)/(numSamples-1); 349 + float step = (max-min)/(numSamplesMag-1);
262 float factor; 350 float factor;
263 vec<float> temp(0.0,0.0,0.0); 351 vec<float> temp(0.0,0.0,0.0);
264 352
265 glNewList(dList+2, GL_COMPILE); 353 glNewList(dList+2, GL_COMPILE);
266 - for(int i = 0; i < numSamples; i++){ 354 + for(int i = 0; i < numSamplesMag; i++){
267 //Create linear index 355 //Create linear index
268 factor = (min+step*i)*mag[0]; 356 factor = (min+step*i)*mag[0];
269 temp = factor; 357 temp = factor;
@@ -280,10 +368,11 @@ class gl_spider @@ -280,10 +368,11 @@ class gl_spider
280 } 368 }
281 glEndList(); 369 glEndList();
282 } 370 }
283 - ///@param v_x x-coordinate in buffer-space,  
284 - ///@param v_y y-coordinate in buffer-space.  
285 - ///Samples the texturespace and places a sample in the provided coordinates  
286 - ///of bufferspace. 371 +
  372 + ///@param float v_x x-coordinate in buffer-space,
  373 + ///@param float v_y y-coordinate in buffer-space.
  374 + ///Samples the texture space.
  375 + ///places a sample in the provided coordinates of bufferspace.
287 void 376 void
288 UpdateBuffer(float v_x, float v_y) 377 UpdateBuffer(float v_x, float v_y)
289 { 378 {
@@ -361,8 +450,37 @@ class gl_spider @@ -361,8 +450,37 @@ class gl_spider
361 //--------------------------------GL METHODS--------------------------------// 450 //--------------------------------GL METHODS--------------------------------//
362 //--------------------------------------------------------------------------// 451 //--------------------------------------------------------------------------//
363 452
364 - ///@param width sets the width of the buffer.  
365 - ///@param height sets the height of the buffer. 453 + ///@param uint width sets the width of the buffer.
  454 + ///@param uint height sets the height of the buffer.
  455 + ///@param GLuint &textureID gives the texture ID of the texture to be initialized.
  456 + ///@param GLuint &framebufferID gives the buffer ID of the texture to be initialized.
  457 + ///Function for setting up the 2D buffer that stores the samples.
  458 + ///Initiates and sets parameters.
  459 + void
  460 + GenerateFBO(unsigned int width, unsigned int height, GLuint &textureID, GLuint &framebufferID)
  461 + {
  462 + glGenFramebuffers(1, &framebufferID);
  463 + glBindFramebuffer(GL_FRAMEBUFFER, framebufferID);
  464 + int numChannels = 1;
  465 + unsigned char* texels = new unsigned char[width * height * numChannels];
  466 + glGenTextures(1, &textureID);
  467 + glBindTexture(GL_TEXTURE_2D, textureID);
  468 +
  469 + //Textures repeat and use linear interpolation, luminance format.
  470 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  471 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  472 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  473 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  474 + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
  475 + width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, texels);
  476 + delete[] texels;
  477 + glBindFramebuffer(GL_FRAMEBUFFER, 0);
  478 + glBindTexture(GL_TEXTURE_2D, 0);
  479 + CHECK_OPENGL_ERROR
  480 + }
  481 +
  482 + ///@param uint width sets the width of the buffer.
  483 + ///@param uint height sets the height of the buffer.
366 ///Function for setting up the 2D buffer that stores the samples. 484 ///Function for setting up the 2D buffer that stores the samples.
367 void 485 void
368 GenerateFBO(unsigned int width, unsigned int height) 486 GenerateFBO(unsigned int width, unsigned int height)
@@ -373,6 +491,8 @@ class gl_spider @@ -373,6 +491,8 @@ class gl_spider
373 unsigned char* texels = new unsigned char[width * height * numChannels]; 491 unsigned char* texels = new unsigned char[width * height * numChannels];
374 glGenTextures(1, &texbufferID); 492 glGenTextures(1, &texbufferID);
375 glBindTexture(GL_TEXTURE_2D, texbufferID); 493 glBindTexture(GL_TEXTURE_2D, texbufferID);
  494 +
  495 + //Textures repeat and use linear interpolation, luminance format.
376 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 496 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
377 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 497 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
378 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 498 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -382,39 +502,150 @@ class gl_spider @@ -382,39 +502,150 @@ class gl_spider
382 delete[] texels; 502 delete[] texels;
383 glBindFramebuffer(GL_FRAMEBUFFER, 0); 503 glBindFramebuffer(GL_FRAMEBUFFER, 0);
384 glBindTexture(GL_TEXTURE_2D, 0); 504 glBindTexture(GL_TEXTURE_2D, 0);
  505 + CHECK_OPENGL_ERROR
385 } 506 }
386 507
387 508
388 - ///Method for using the gl manipulation to alighn templates from 509 + ///Method for using the gl manipulation to align templates from
389 ///Template space (-0.5 0.5) to Texture space (0.0, 1.0), 510 ///Template space (-0.5 0.5) to Texture space (0.0, 1.0),
390 ///Based on the p of the spider in real space (arbitrary). 511 ///Based on the p of the spider in real space (arbitrary).
  512 + ///All transformation happen in glMatrixMode(GL_TEXTURE).
391 void setMatrix() 513 void setMatrix()
392 { 514 {
393 - float curTrans[16];  
394 - stim::vec<float> rot = getRotation(d); 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.
395 glMatrixMode(GL_TEXTURE); 517 glMatrixMode(GL_TEXTURE);
396 glLoadIdentity(); 518 glLoadIdentity();
397 - glScalef(1.0/S[0]/R[0], 1.0/S[1]/R[1], 1.0/S[2]/R[2]);  
398 -  
399 519
  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.
400 glTranslatef(p[0], 523 glTranslatef(p[0],
401 p[1], 524 p[1],
402 p[2]); 525 p[2]);
403 - 526 + //rotate to the current direction of the spider.
404 glRotatef(rot[0], rot[1], rot[2], rot[3]); 527 glRotatef(rot[0], rot[1], rot[2], rot[3]);
405 - 528 + //scale to the magnitude of the spider.
406 glScalef(m[0], 529 glScalef(m[0],
407 m[0], 530 m[0],
408 m[0]); 531 m[0]);
409 - 532 + //get and store the current transformation matrix for later use.
410 glGetFloatv(GL_TEXTURE_MATRIX, curTrans); 533 glGetFloatv(GL_TEXTURE_MATRIX, curTrans);
411 cT.set(curTrans); 534 cT.set(curTrans);
412 -// printTransform(); 535 + // printTransform();
413 536
414 CHECK_OPENGL_ERROR 537 CHECK_OPENGL_ERROR
  538 + //revert back to default gl mode.
415 glMatrixMode(GL_MODELVIEW); 539 glMatrixMode(GL_MODELVIEW);
416 } 540 }
  541 +
  542 + ///Method for controling the buffer and texture binding.
  543 + ///Clears the buffer upon binding.
  544 + void
  545 + Bind()
  546 + {
  547 + float len = 8.0;
  548 + glBindFramebuffer(GL_FRAMEBUFFER, fboID);//set up GL buffer
  549 + glFramebufferTexture2D(
  550 + GL_FRAMEBUFFER,
  551 + GL_COLOR_ATTACHMENT0,
  552 + GL_TEXTURE_2D,
  553 + texbufferID,
  554 + 0);
  555 + glBindFramebuffer(GL_FRAMEBUFFER, fboID);
  556 + GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
  557 + glDrawBuffers(1, DrawBuffers);
  558 + glBindTexture(GL_TEXTURE_2D, texbufferID);
  559 + glClearColor(1,1,1,1);
  560 + glClear(GL_COLOR_BUFFER_BIT);
  561 + glMatrixMode(GL_PROJECTION);
  562 + glLoadIdentity();
  563 + glMatrixMode(GL_MODELVIEW);
  564 + glLoadIdentity();
  565 + glViewport(0,0,2.0*len, numSamples*len);
  566 + gluOrtho2D(0.0,2.0*len,0.0,numSamples*len);
  567 + glEnable(GL_TEXTURE_3D);
  568 + glBindTexture(GL_TEXTURE_3D, texID);
  569 +
  570 + CHECK_OPENGL_ERROR
  571 + }
417 572
  573 + ///Method for controling the buffer and texture binding.
  574 + ///Clears the buffer upon binding.
  575 + ///@param GLuint &textureID, texture to be bound.
  576 + ///@param GLuint &framebufferID, framebuffer used for storage.
  577 + ///@param int nSamples, number of rectanges to create.
  578 + void
  579 + Bind(GLuint &textureID, GLuint &framebufferID, int nSamples)
  580 + {
  581 + float len = 8.0;
  582 + glBindFramebuffer(GL_FRAMEBUFFER, framebufferID);//set up GL buffer
  583 + glFramebufferTexture2D(
  584 + GL_FRAMEBUFFER,
  585 + GL_COLOR_ATTACHMENT0,
  586 + GL_TEXTURE_2D,
  587 + textureID,
  588 + 0);
  589 + glBindFramebuffer(GL_FRAMEBUFFER, framebufferID);
  590 + GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};
  591 + glDrawBuffers(1, DrawBuffers);
  592 + glBindTexture(GL_TEXTURE_2D, textureID);
  593 +// glClearColor(1,1,1,1);
  594 +// glClear(GL_COLOR_BUFFER_BIT);
  595 + glMatrixMode(GL_PROJECTION);
  596 + glLoadIdentity();
  597 + glMatrixMode(GL_MODELVIEW);
  598 + glLoadIdentity();
  599 + glViewport(0,0,2.0*len, nSamples*len);
  600 + gluOrtho2D(0.0,2.0*len,0.0,nSamples*len);
  601 + glEnable(GL_TEXTURE_3D);
  602 + glBindTexture(GL_TEXTURE_3D, texID);
  603 +
  604 + CHECK_OPENGL_ERROR
  605 + }
  606 +
  607 + ///Unbinds all texture resources.
  608 + void
  609 + Unbind()
  610 + {
  611 + //Finalize GL_buffer
  612 + glBindTexture(GL_TEXTURE_3D, 0);
  613 + CHECK_OPENGL_ERROR
  614 + glBindTexture(GL_TEXTURE_2D, 0);
  615 + CHECK_OPENGL_ERROR
  616 + glBindFramebuffer(GL_FRAMEBUFFER, 0);
  617 + CHECK_OPENGL_ERROR
  618 + glDisable(GL_TEXTURE_3D);
  619 + CHECK_OPENGL_ERROR
  620 + }
  621 +
  622 + ///Makes the spider take a step.
  623 + ///starting with the current p, d, m, find the next optimal p, d, m.
  624 + ///Performs the branch detection on each step.
  625 + int
  626 + StepP()
  627 + {
  628 + Bind();
  629 + CHECK_OPENGL_ERROR
  630 + #ifdef TESTING
  631 + start = std::clock();
  632 + #endif
  633 + findOptimalDirection();
  634 + findOptimalPosition();
  635 + findOptimalScale();
  636 + Unbind();
  637 + Bind(btexbufferID, bfboID, 27);
  638 + branchDetection();
  639 + Unbind();
  640 +
  641 + #ifdef TESTING
  642 + duration_sampling = duration_sampling +
  643 + (std::clock() - start) / (double) CLOCKS_PER_SEC;
  644 + num_sampling = num_sampling + 1.0;
  645 + #endif
  646 + return current_cost;
  647 + }
  648 +
418 649
419 650
420 651
@@ -422,95 +653,150 @@ class gl_spider @@ -422,95 +653,150 @@ class gl_spider
422 //--------------------------------CUDA METHODS------------------------------// 653 //--------------------------------CUDA METHODS------------------------------//
423 //--------------------------------------------------------------------------// 654 //--------------------------------------------------------------------------//
424 655
425 - /// Method for registering the texture with Cuda for shared  
426 - /// access.  
427 - void  
428 - createResource()  
429 - {  
430 - HANDLE_ERROR(  
431 - cudaGraphicsGLRegisterImage(  
432 - &resource,  
433 - texbufferID,  
434 - GL_TEXTURE_2D,  
435 - //CU_GRAPHICS_REGISTER_FLAGS_NONE)  
436 - cudaGraphicsMapFlagsReadOnly)  
437 - );  
438 - }  
439 -  
440 - ///Method for freeing the texture from Cuda for gl access.  
441 - void  
442 - destroyResource() 656 +
  657 + ///Entry-point into the cuda code for calculating the cost of a given samples array (in texture form)
  658 + ///finds the minimum cost and sets the current_cost to that value.
  659 + /// and returns the index of the template with the minimal cost.
  660 + int
  661 + getCost()
443 { 662 {
444 - HANDLE_ERROR(  
445 - cudaGraphicsUnregisterResource(resource)  
446 - ); 663 + #ifdef TESTING
  664 + start = std::clock();
  665 + #endif
  666 + stim::vec<int> cost =
  667 + stim::cuda::get_cost(texbufferID, GL_TEXTURE_2D, numSamples);
  668 + cudaDeviceSynchronize();
  669 + #ifdef TESTING
  670 + duration_cuda = duration_cuda +
  671 + (std::clock() - start) / (double) CLOCKS_PER_SEC;
  672 + num_cuda = num_cuda + 1.0;
  673 + #endif
  674 + current_cost = cost[1];
  675 + return cost[0];
447 } 676 }
448 677
449 - ///Entry-point into the cuda code for calculating the cost  
450 - /// of a given samples array (in texture form)  
451 int 678 int
452 - getCost() 679 + getCost(GLuint tID, int n)
453 { 680 {
454 - createResource();  
455 - stim::vec<int> cost = get_cost(resource, numSamples);  
456 - destroyResource();  
457 -// if (cost[1] >= 80)  
458 -// exit(0); 681 + #ifdef TESTING
  682 + start = std::clock();
  683 + #endif
  684 + stim::vec<int> cost =
  685 + stim::cuda::get_cost(tID, GL_TEXTURE_2D, n);
  686 + cudaDeviceSynchronize();
  687 + #ifdef TESTING
  688 + duration_cuda = duration_cuda +
  689 + (std::clock() - start) / (double) CLOCKS_PER_SEC;
  690 + num_cuda = num_cuda + 1.0;
  691 + #endif
459 current_cost = cost[1]; 692 current_cost = cost[1];
460 return cost[0]; 693 return cost[0];
461 } 694 }
462 695
463 public: 696 public:
  697 +
  698 + ///ininializes the cuda device and environment.
  699 + void
  700 + initCuda()
  701 + {
  702 + stim::cudaSetDevice();
  703 + //GLint max;
  704 + //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);
  705 + //std::cout << max << std::endl;
  706 + }
  707 +
  708 + //horizonal rectangle forming the spider.
464 stim::rect<float> hor; 709 stim::rect<float> hor;
  710 + //vectical rectangle forming the spider.
465 stim::rect<float> ver; 711 stim::rect<float> ver;
466 712
  713 + //Testing and Timing variables.
  714 + #ifdef TESTING
  715 + std::clock_t start;
  716 + double duration_sampling = 0.0;
  717 + double duration_cuda = 0.0;
  718 + double num_sampling = 0.0;
  719 + double num_cuda = 0.0;
  720 + #endif
  721 +
467 //--------------------------------------------------------------------------// 722 //--------------------------------------------------------------------------//
468 //-----------------------------CONSTRUCTORS---------------------------------// 723 //-----------------------------CONSTRUCTORS---------------------------------//
469 //--------------------------------------------------------------------------// 724 //--------------------------------------------------------------------------//
470 725
471 726
472 - ///@param samples, the number of samples this spider is going to use.  
473 - ///best results if samples is can create a perfect root. 727 + ///@param int samples, the number of samples this spider is going to use.
  728 + ///Best results if samples is can create a perfect root.
474 ///Default Constructor 729 ///Default Constructor
475 gl_spider 730 gl_spider
476 - (int samples = 1089) 731 + (int samples = 1089, int samplespos = 441,int samplesmag = 144)
477 { 732 {
478 p = vec<float>(0.0, 0.0, 0.0); 733 p = vec<float>(0.0, 0.0, 0.0);
479 d = vec<float>(0.0, 0.0, 1.0); 734 d = vec<float>(0.0, 0.0, 1.0);
480 m = vec<float>(1.0, 1.0); 735 m = vec<float>(1.0, 1.0);
481 S = vec<float>(1.0, 1.0, 1.0); 736 S = vec<float>(1.0, 1.0, 1.0);
482 R = vec<float>(1.0, 1.0, 1.0); 737 R = vec<float>(1.0, 1.0, 1.0);
483 - //setPosition(0.0,0.0,0.0);  
484 - //setDirection(0.0,0.0,1.0);  
485 - //setMagnitude(1.0);  
486 numSamples = samples; 738 numSamples = samples;
  739 + numSamplesPos = samplespos;
  740 + numSamplesMag = samplesmag;
487 } 741 }
488 742
489 - ///temporary constructor for convenience, will be removed in further updates. 743 + ///Position constructor: floats.
  744 + ///@param float pos_x, position x.
  745 + ///@param float pos_y, position y.
  746 + ///@param float pos_z, position z.
  747 + ///@param float dir_x, direction x.
  748 + ///@param float dir_y, direction y.
  749 + ///@param float dir_z, direction z.
  750 + ///@param float mag_x, size of the vector.
  751 + ///@param int samples, number of templates this spider is going to use.
490 gl_spider 752 gl_spider
491 (float pos_x, float pos_y, float pos_z, float dir_x, float dir_y, float dir_z, 753 (float pos_x, float pos_y, float pos_z, float dir_x, float dir_y, float dir_z,
492 - float mag_x, int numSamples = 1089) 754 + float mag_x, int numsamples = 1089, int numsamplespos = 441, int numsamplesmag =144)
493 { 755 {
494 p = vec<float>(pos_x, pos_y, pos_z); 756 p = vec<float>(pos_x, pos_y, pos_z);
495 d = vec<float>(dir_x, dir_y, dir_z); 757 d = vec<float>(dir_x, dir_y, dir_z);
496 m = vec<float>(mag_x, mag_x, mag_x); 758 m = vec<float>(mag_x, mag_x, mag_x);
497 S = vec<float>(1.0,1.0,1.0); 759 S = vec<float>(1.0,1.0,1.0);
498 R = vec<float>(1.0,1.0,1.0); 760 R = vec<float>(1.0,1.0,1.0);
499 - //setPosition(pos_x, pos_y, pos_z);  
500 - //setDirection(dir_x, dir_y, dir_z);  
501 - //setMagnitude(mag_x);  
502 - 761 + numSamples = numsamples;
  762 + numSamplesPos = numsamplespos;
  763 + numSamplesMag = numsamplesmag;
503 } 764 }
504 - 765 +
  766 + ///Position constructor: vecs of floats.
  767 + ///@param stim::vec<float> pos, position.
  768 + ///@param stim::vec<float> dir, direction.
  769 + ///@param float mag, size of the vector.
  770 + ///@param int samples, number of templates this spider is going to use.
  771 + gl_spider
  772 + (stim::vec<float> pos, stim::vec<float> dir, float mag, int samples = 1089, int samplesPos = 441, int samplesMag = 144)
  773 + {
  774 + p = pos;
  775 + d = dir;
  776 + m = vec<float>(mag, mag, mag);
  777 + S = vec<float>(1.0,1.0,1.0);
  778 + R = vec<float>(1.0,1.0,1.0);
  779 + numSamples = samples;
  780 + numSamplesPos = samplesPos;
  781 + numSamplesMag = samplesMag;
  782 + }
  783 +
  784 + ///destructor
505 ~gl_spider 785 ~gl_spider
506 (void) 786 (void)
507 { 787 {
508 Unbind(); 788 Unbind();
509 glDeleteTextures(1, &texbufferID); 789 glDeleteTextures(1, &texbufferID);
510 glDeleteBuffers(1, &fboID); 790 glDeleteBuffers(1, &fboID);
  791 + glDeleteTextures(1, &ptexbufferID);
  792 + glDeleteBuffers(1, &pfboID);
  793 + glDeleteTextures(1, &mtexbufferID);
  794 + glDeleteBuffers(1, &mfboID);
  795 + glDeleteTextures(1, &btexbufferID);
  796 + glDeleteBuffers(1, &bfboID);
511 } 797 }
512 798
513 - ///@param GLuint id texture that is going to be sampled. 799 + ///@param GLuint id, texture that is going to be sampled.
514 ///Attached the spider to the texture with the given GLuint ID. 800 ///Attached the spider to the texture with the given GLuint ID.
515 ///Samples in the default d acting as the init method. 801 ///Samples in the default d acting as the init method.
516 ///Also acts an init. 802 ///Also acts an init.
@@ -518,16 +804,26 @@ class gl_spider @@ -518,16 +804,26 @@ class gl_spider
518 attachSpider(GLuint id) 804 attachSpider(GLuint id)
519 { 805 {
520 texID = id; 806 texID = id;
521 - GenerateFBO(16, numSamples*8); 807 + //GenerateFBO(16, numSamples*8);
  808 + GenerateFBO(16, numSamples*8, texbufferID, fboID);
  809 + GenerateFBO(16, numSamplesPos*8, ptexbufferID, pfboID);
  810 + GenerateFBO(16, numSamplesMag*8, mtexbufferID, mfboID);
  811 + GenerateFBO(16, 216, btexbufferID, bfboID);
522 setDims(0.6, 0.6, 1.0); 812 setDims(0.6, 0.6, 1.0);
523 setSize(512.0, 512.0, 426.0); 813 setSize(512.0, 512.0, 426.0);
524 setMatrix(); 814 setMatrix();
525 dList = glGenLists(3); 815 dList = glGenLists(3);
526 glListBase(dList); 816 glListBase(dList);
527 - Bind();  
528 - genDirectionVectors(5*M_PI/4);  
529 - genPositionVectors();  
530 - genMagnitudeVectors(); 817 + Bind(texbufferID, fboID, numSamples);
  818 + genDirectionVectors(5*M_PI/4);
  819 + Unbind();
  820 + Bind(ptexbufferID, pfboID, numSamplesPos);
  821 + genPositionVectors();
  822 + Unbind();
  823 + Bind(mtexbufferID, mfboID, numSamplesMag);
  824 + genMagnitudeVectors();
  825 + Unbind();
  826 + Bind(btexbufferID, bfboID, 27);
531 DrawCylinder(); 827 DrawCylinder();
532 Unbind(); 828 Unbind();
533 } 829 }
@@ -556,7 +852,7 @@ class gl_spider @@ -556,7 +852,7 @@ class gl_spider
556 return m; 852 return m;
557 } 853 }
558 854
559 - ///@param vector pos, the new p. 855 + ///@param stim::vec<float> pos, the new p.
560 ///Sets the p vector to input vector pos. 856 ///Sets the p vector to input vector pos.
561 void 857 void
562 setPosition(vec<float> pos) 858 setPosition(vec<float> pos)
@@ -564,9 +860,9 @@ class gl_spider @@ -564,9 +860,9 @@ class gl_spider
564 p = pos; 860 p = pos;
565 } 861 }
566 862
567 - ///@param x x-coordinate.  
568 - ///@param y y-coordinate.  
569 - ///@param z z-coordinate. 863 + ///@param float x x-coordinate.
  864 + ///@param float y y-coordinate.
  865 + ///@param float z z-coordinate.
570 ///Sets the p vector to the input float coordinates x,y,z. 866 ///Sets the p vector to the input float coordinates x,y,z.
571 void 867 void
572 setPosition(float x, float y, float z) 868 setPosition(float x, float y, float z)
@@ -576,7 +872,7 @@ class gl_spider @@ -576,7 +872,7 @@ class gl_spider
576 p[2] = z; 872 p[2] = z;
577 } 873 }
578 874
579 - ///@param vector dir, the new d. 875 + ///@param stim::vec<float> dir, the new d.
580 ///Sets the d vector to input vector dir. 876 ///Sets the d vector to input vector dir.
581 void 877 void
582 setDirection(vec<float> dir) 878 setDirection(vec<float> dir)
@@ -584,9 +880,9 @@ class gl_spider @@ -584,9 +880,9 @@ class gl_spider
584 d = dir; 880 d = dir;
585 } 881 }
586 882
587 - ///@param x x-coordinate.  
588 - ///@param y y-coordinate.  
589 - ///@param z z-coordinate. 883 + ///@param stim::vec<float> x x-coordinate.
  884 + ///@param stim::vec<float> y y-coordinate.
  885 + ///@param stim::vec<float> z z-coordinate.
590 ///Sets the d vector to the input float coordinates x,y,z. 886 ///Sets the d vector to the input float coordinates x,y,z.
591 void 887 void
592 setDirection(float x, float y, float z) 888 setDirection(float x, float y, float z)
@@ -596,7 +892,7 @@ class gl_spider @@ -596,7 +892,7 @@ class gl_spider
596 d[2] = z; 892 d[2] = z;
597 } 893 }
598 894
599 - ///@param vector dir, the new d. 895 + ///@param stim::vec<float> dir, the new d.
600 ///Sets the m vector to the input vector mag. 896 ///Sets the m vector to the input vector mag.
601 void 897 void
602 setMagnitude(vec<float> mag) 898 setMagnitude(vec<float> mag)
@@ -605,17 +901,19 @@ class gl_spider @@ -605,17 +901,19 @@ class gl_spider
605 m[1] = mag[0]; 901 m[1] = mag[0];
606 } 902 }
607 903
608 - ///@param mag size of the sampled region. 904 + ///@param float mag, size of the sampled region.
609 ///Sets the m vector to the input mag for both templates. 905 ///Sets the m vector to the input mag for both templates.
610 void 906 void
611 setMagnitude(float mag) 907 setMagnitude(float mag)
612 { 908 {
613 m[0] = mag; 909 m[0] = mag;
614 m[1] = mag; 910 m[1] = mag;
615 - // m[2] = mag;  
616 } 911 }
617 912
618 - 913 + ///@param float x, voxel size in the x direction.
  914 + ///@param float y, voxel size in the y direction.
  915 + ///@param float z, voxel size in the z direction.
  916 + ///Sets the voxel sizes in each direction. necessary for non-standard data.
619 void 917 void
620 setDims(float x, float y, float z) 918 setDims(float x, float y, float z)
621 { 919 {
@@ -624,6 +922,18 @@ class gl_spider @@ -624,6 +922,18 @@ class gl_spider
624 S[2] = z; 922 S[2] = z;
625 } 923 }
626 924
  925 + ///@param stim::vec<float> Dims, voxel size.
  926 + ///Sets the voxel sizes in each direction. necessary for non-standard data.
  927 + void
  928 + setDims(stim::vec<float> Dims)
  929 + {
  930 + S = Dims;
  931 + }
  932 +
  933 + ///@param float x, size of the data in the x direction.
  934 + ///@param float y, size of the data in the y direction.
  935 + ///@param float z, size of the data in the z direction.
  936 + ///Sets the data volume sizes in each direction.
627 void 937 void
628 setSize(float x, float y, float z) 938 setSize(float x, float y, float z)
629 { 939 {
@@ -631,10 +941,19 @@ class gl_spider @@ -631,10 +941,19 @@ class gl_spider
631 R[1] = y; 941 R[1] = y;
632 R[2] = z; 942 R[2] = z;
633 } 943 }
  944 +
  945 + ///@param stim::vec<float> Dims, size of the volume.
  946 + ///Sets the data volume sizes in each direction.
  947 + void
  948 + setSize(stim::vec<float> Siz)
  949 + {
  950 + S = Siz;
  951 + }
634 952
635 - ///@param dir, the vector to which we are rotating  
636 - ///given a vector to align to, finds the required  
637 - ///axis and angle for glRotatef 953 + ///@param stim::vec<float> dir, the vector to which we are rotating.
  954 + ///given a vector to align to, finds the required axis and angle for glRotatef.
  955 + ///rotates from 0.0, 0.0, 1.0 to dir.
  956 + ///return is in degrees for use with glRotatef.
638 stim::vec<float> 957 stim::vec<float>
639 getRotation(stim::vec<float> dir) 958 getRotation(stim::vec<float> dir)
640 { 959 {
@@ -655,56 +974,156 @@ class gl_spider @@ -655,56 +974,156 @@ class gl_spider
655 } 974 }
656 return out; 975 return out;
657 } 976 }
  977 +
  978 + ///@param stim::vec<float> pos, the position of the seed to be added.
  979 + ///Adds a seed to the seed list.
  980 + ///Assumes that the coordinates passes are in tissue space.
  981 + void
  982 + setSeed(stim::vec<float> pos)
  983 + {
  984 + seeds.push(pos);
  985 + }
  986 +
  987 + ///@param stim::vec<float> dir, the direction of the seed to be added.
  988 + ///Adds a seed to the seed directions list.
  989 + void
  990 + setSeedVec(stim::vec<float> dir)
  991 + {
  992 + seedsvecs.push(dir);
  993 + }
  994 +
  995 + ///@param float mag, the size of the seed to be added.
  996 + ///Adds a seed to the seed list.
  997 + ///Assumes that the coordinates passes are in tissue space.
  998 + void
  999 + setSeedMag(float mag)
  1000 + {
  1001 + seedsmags.push(mag);
  1002 + }
  1003 +
  1004 +
  1005 + ///@param float x, x-position of the seed to be added.
  1006 + ///@param float y, y-position of the seed to be added.
  1007 + ///@param float z, z-position of the seed to be added.
  1008 + ///Adds a seed to the seed list.
  1009 + ///Assumes that the coordinates passes are in tissue space.
  1010 + void
  1011 + setSeed(float x, float y, float z)
  1012 + {
  1013 + seeds.push(stim::vec<float>(x, y, z));
  1014 + }
  1015 +
  1016 + ///@param float x, x-direction of the seed to be added.
  1017 + ///@param float y, y-direction of the seed to be added.
  1018 + ///@param float z, z-direction of the seed to be added.
  1019 + ///Adds a seed to the seed directions list.
  1020 + void
  1021 + setSeedVec(float x, float y, float z)
  1022 + {
  1023 + seedsvecs.push(stim::vec<float>(x, y, z));
  1024 + }
658 1025
659 - ///Function to get back the framebuffer Object attached to the spider.  
660 - ///For external access.  
661 - GLuint  
662 - getFB() 1026 + ///Method to get the top of the seed positions stack.
  1027 + stim::vec<float>
  1028 + getLastSeed()
  1029 + {
  1030 + stim::vec<float> tp = seeds.top();
  1031 + return tp;
  1032 + }
  1033 +
  1034 + ///Method to get the top of the seed direction stack.
  1035 + stim::vec<float>
  1036 + getLastSeedVec()
  1037 + {
  1038 + stim::vec<float> tp = seedsvecs.top();
  1039 + return tp;
  1040 + }
  1041 +
  1042 + ///Method to get the top of the seed magnitude stack.
  1043 + float
  1044 + getLastSeedMag()
663 { 1045 {
664 - return fboID; 1046 + float tp = seedsmags.top();
  1047 + return tp;
665 } 1048 }
666 1049
667 - ///Method for controling the buffer and texture binding in order to properly  
668 - ///do the render to texture. 1050 + ///deletes all data associated with the last seed.
669 void 1051 void
670 - Bind() 1052 + popSeed()
671 { 1053 {
672 - float len = 8.0;  
673 - glBindFramebuffer(GL_FRAMEBUFFER, fboID);//set up GL buffer  
674 - glFramebufferTexture2D(  
675 - GL_FRAMEBUFFER,  
676 - GL_COLOR_ATTACHMENT0,  
677 - GL_TEXTURE_2D,  
678 - texbufferID,  
679 - 0);  
680 - glBindFramebuffer(GL_FRAMEBUFFER, fboID);  
681 - GLenum DrawBuffers[1] = {GL_COLOR_ATTACHMENT0};  
682 - glDrawBuffers(1, DrawBuffers);  
683 - glBindTexture(GL_TEXTURE_2D, texbufferID);  
684 - glClearColor(1,1,1,1);  
685 - glClear(GL_COLOR_BUFFER_BIT);  
686 - glMatrixMode(GL_PROJECTION);  
687 - glLoadIdentity();  
688 - glMatrixMode(GL_MODELVIEW);  
689 - glLoadIdentity();  
690 - glViewport(0,0,2.0*len, numSamples*len);  
691 - gluOrtho2D(0.0,2.0*len,0.0,numSamples*len);  
692 - glEnable(GL_TEXTURE_3D);  
693 - glBindTexture(GL_TEXTURE_3D, texID); 1054 + seeds.pop();
  1055 + seedsvecs.pop();
  1056 + seedsmags.pop();
  1057 + }
  1058 +
  1059 + ///returns the seeds position stack.
  1060 + std::stack<stim::vec<float> >
  1061 + getSeeds()
  1062 + {
  1063 + return seeds;
  1064 + }
694 1065
695 - CHECK_OPENGL_ERROR 1066 + ///returns true if all seed stacks are empty, else false.
  1067 + bool
  1068 + Empty()
  1069 + {
  1070 + //return (seeds.empty() && seedsvecs.empty() && seedsmags.empty());
  1071 + return (seeds.empty() && seedsvecs.empty());
  1072 + }
  1073 +
  1074 + ///@param std::string file:file with variables to populate the seed stacks.
  1075 + ///Adds a seed to the seed list, including the position, direction and magnitude.
  1076 + ///Assumes that the coordinates passes are in tissue space.
  1077 + void
  1078 + setSeeds(std::string file)
  1079 + {
  1080 + std::ifstream myfile(file.c_str());
  1081 + string line;
  1082 + if(myfile.is_open())
  1083 + {
  1084 + while (getline(myfile, line))
  1085 + {
  1086 + float x, y, z, u, v, w, m;
  1087 + myfile >> x >> y >> z >> u >> v >> w >> m;
  1088 + setSeed(x, y , z);
  1089 + setSeedVec(u, v, w);
  1090 + setSeedMag(m);
  1091 + }
  1092 + myfile.close();
  1093 + } else {
  1094 + std::cerr<<"failed" << std::endl;
  1095 + }
696 } 1096 }
697 1097
698 - ///Method for Unbinding all of the texture resources 1098 + ///Saves the network to a file.
699 void 1099 void
700 - Unbind() 1100 + saveNetwork(std::string name)
701 { 1101 {
702 - //Finalize GL_buffer  
703 - glBindTexture(GL_TEXTURE_3D, 0);  
704 - glDisable(GL_TEXTURE_3D);  
705 - glBindFramebuffer(GL_FRAMEBUFFER,0);  
706 - glBindTexture(GL_TEXTURE_2D, 0); 1102 + sk.save(name);
  1103 + }
  1104 +
  1105 + ///returns a COPY of the entire stim::glObj object.
  1106 + stim::glObj<float>
  1107 + getNetwork()
  1108 + {
  1109 + return sk;
  1110 + }
  1111 +
  1112 + ///returns a COPY of the entire stim::glnetwork object.
  1113 + stim::glnetwork<T>
  1114 + getGLNetwork()
  1115 + {
  1116 + return nt;
  1117 + }
  1118 +
  1119 + ///Function to get back the framebuffer Object attached to the spider.
  1120 + ///For external access.
  1121 + GLuint
  1122 + getFB()
  1123 + {
  1124 + return bfboID;
707 } 1125 }
  1126 +
708 //--------------------------------------------------------------------------// 1127 //--------------------------------------------------------------------------//
709 //-----------------------------TEMPORARY METHODS----------------------------// 1128 //-----------------------------TEMPORARY METHODS----------------------------//
710 //--------------------------------------------------------------------------// 1129 //--------------------------------------------------------------------------//
@@ -726,12 +1145,26 @@ class gl_spider @@ -726,12 +1145,26 @@ class gl_spider
726 int 1145 int
727 Step() 1146 Step()
728 { 1147 {
729 - // Bind();  
730 - findOptimalDirection();  
731 - findOptimalPosition();  
732 - findOptimalScale();  
733 - branchDetection();  
734 - // Unbind(); 1148 + Bind(texbufferID, fboID, numSamples);
  1149 + CHECK_OPENGL_ERROR
  1150 + #ifdef TESTING
  1151 + start = std::clock();
  1152 + #endif
  1153 + findOptimalDirection();
  1154 + Unbind();
  1155 + Bind(ptexbufferID, pfboID, numSamplesPos);
  1156 + findOptimalPosition();
  1157 + Unbind();
  1158 + Bind(mtexbufferID, mfboID, numSamplesMag);
  1159 + findOptimalScale();
  1160 + Unbind();
  1161 + CHECK_OPENGL_ERROR
  1162 +
  1163 + #ifdef TESTING
  1164 + duration_sampling = duration_sampling +
  1165 + (std::clock() - start) / (double) CLOCKS_PER_SEC;
  1166 + num_sampling = num_sampling + 1.0;
  1167 + #endif
735 return current_cost; 1168 return current_cost;
736 } 1169 }
737 1170
@@ -742,16 +1175,6 @@ class gl_spider @@ -742,16 +1175,6 @@ class gl_spider
742 std::cout << cT << std::endl; 1175 std::cout << cT << std::endl;
743 } 1176 }
744 1177
745 - /* Method for initializing the cuda devices, necessary only  
746 - there are multiple cuda devices */  
747 - void  
748 - initCuda()  
749 - {  
750 - stim::cudaSetDevice();  
751 - //GLint max;  
752 - //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);  
753 - //std::cout << max << std::endl;  
754 - }  
755 1178
756 //--------------------------------------------------------------------------// 1179 //--------------------------------------------------------------------------//
757 //-----------------------------EXPERIMENTAL METHODS-------------------------// 1180 //-----------------------------EXPERIMENTAL METHODS-------------------------//
@@ -760,36 +1183,410 @@ class gl_spider @@ -760,36 +1183,410 @@ class gl_spider
760 void 1183 void
761 DrawCylinder() 1184 DrawCylinder()
762 { 1185 {
763 - Bind();  
764 glNewList(dList+3, GL_COMPILE); 1186 glNewList(dList+3, GL_COMPILE);
765 float z0 = -0.5; float z1 = 0.5; float r0 = 0.5; 1187 float z0 = -0.5; float z1 = 0.5; float r0 = 0.5;
766 float x,y; 1188 float x,y;
767 - float xold = 0.5; float yold = 0.5;  
768 - float step = 360.0/numSamples;  
769 - int j = 0; 1189 + float xold = 0.5; float yold = 0.0;
  1190 + float step = 360.0/numSamples*32;
  1191 + //float step = 360.0/8.0;
770 glEnable(GL_TEXTURE_3D); 1192 glEnable(GL_TEXTURE_3D);
771 glBindTexture(GL_TEXTURE_3D, texID); 1193 glBindTexture(GL_TEXTURE_3D, texID);
772 glBegin(GL_QUAD_STRIP); 1194 glBegin(GL_QUAD_STRIP);
  1195 + int j = 0;
773 for(float i = step; i <= 360.0; i += step) 1196 for(float i = step; i <= 360.0; i += step)
774 { 1197 {
775 x=r0*cos(i*2.0*M_PI/360.0); 1198 x=r0*cos(i*2.0*M_PI/360.0);
776 y=r0*sin(i*2.0*M_PI/360.0); 1199 y=r0*sin(i*2.0*M_PI/360.0);
777 glTexCoord3f(x,y,z0); 1200 glTexCoord3f(x,y,z0);
778 - glVertex2f(0.0, j*0.1+0.1); 1201 + glVertex2f(0.0, j*6.4+6.4);
  1202 +// glVertex2f(0.0, j*27.0+27.0);
779 glTexCoord3f(x,y,z1); 1203 glTexCoord3f(x,y,z1);
780 - glVertex2f(16.0, j*0.1+0.1); 1204 + glVertex2f(16.0, j*6.4+6.4);
  1205 +// glVertex2f(16.0, j*27.0+27.0);
781 glTexCoord3f(xold,yold,z1); 1206 glTexCoord3f(xold,yold,z1);
782 - glVertex2f(16.0, j*0.1); 1207 + glVertex2f(16.0, j*6.4);
  1208 +// glVertex2f(16.0, j*27.0);
783 glTexCoord3f(xold,yold,z0); 1209 glTexCoord3f(xold,yold,z0);
784 - glVertex2f(0.0, j*0.1); 1210 + glVertex2f(0.0, j*6.4);
  1211 +// glVertex2f(0.0, j*27.0);
785 xold=x; 1212 xold=x;
786 yold=y; 1213 yold=y;
787 j++; 1214 j++;
788 } 1215 }
789 glEnd(); 1216 glEnd();
790 glEndList(); 1217 glEndList();
791 - Unbind();  
792 } 1218 }
  1219 +
  1220 +
  1221 + ///@param min_cost the cost value used for tracing
  1222 + ///traces out each seedpoint in the seeds queue to completion in both directions.
  1223 + void
  1224 + trace(int min_cost)
  1225 + {
  1226 + Bind();
  1227 + rev = stim::vec<float>(0.0,0.0,1.0);
  1228 + bool sEmpty = true;
  1229 + float lastmag = 16.0;;
  1230 + while(!seeds.empty())
  1231 + {
  1232 + //clear the currently traced line and start a new one.
  1233 + cL.clear();
  1234 + 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();
  1240 + seeds.pop();
  1241 + seedsvecs.pop();
  1242 + seedsmags.pop();
  1243 +// std::cout << "The current seed Vector is " << curSeedVec << std::endl;
  1244 + setPosition(curSeed);
  1245 + 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();
  1261 + }
  1262 + Unbind();
  1263 + }
  1264 +
  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
  1335 + selectObject(stim::vec<float> loc, stim::vec<float> dir, float mag)
  1336 + {
  1337 + //Define the varibles and turn on Selection Mode
  1338 +
  1339 + float s = 3.0;
  1340 + GLuint selectBuf[2048];
  1341 + GLint hits;
  1342 + glSelectBuffer(2048, selectBuf);
  1343 + glDisable(GL_CULL_FACE);
  1344 + (void) glRenderMode(GL_SELECT);
  1345 + //Init Names stack
  1346 +
  1347 + glInitNames();
  1348 + glPushName(1);
  1349 +
  1350 + CHECK_OPENGL_ERROR
  1351 + //What would that vessel see in front of it.
  1352 + camSel.setPosition(loc);
  1353 + camSel.setFocalDistance(mag/s);
  1354 + camSel.LookAt((loc[0]+dir[0]*mag/s),
  1355 + (loc[1]+dir[1]*mag/s),
  1356 + (loc[2]+dir[2]*mag/s));
  1357 + ps = camSel.getPosition();
  1358 + ups = camSel.getUp();
  1359 + ds = camSel.getLookAt();
  1360 + glMatrixMode(GL_PROJECTION);
  1361 + glPushMatrix();
  1362 + glLoadIdentity();
  1363 + glOrtho(-mag/s/2.0, mag/s/2.0, -mag/s/2.0, mag/s/2.0, 0.0, mag/s/2.0);
  1364 + glMatrixMode(GL_MODELVIEW);
  1365 + glPushMatrix();
  1366 + glLoadIdentity();
  1367 +
  1368 + CHECK_OPENGL_ERROR
  1369 + gluLookAt(ps[0], ps[1], ps[2],
  1370 + ds[0], ds[1], ds[2],
  1371 + ups[0], ups[1], ups[2]);
  1372 +
  1373 +// sk.Render();
  1374 + nt.Render();
  1375 +
  1376 + CHECK_OPENGL_ERROR
  1377 +
  1378 +
  1379 +// glLoadName((int) sk.numL());
  1380 + glLoadName(nt.sizeE());
  1381 +
  1382 +// sk.RenderLine(cL);
  1383 + nt.RenderLine(cL);
  1384 +
  1385 +// glPopName();
  1386 + glFlush();
  1387 +
  1388 + glMatrixMode(GL_PROJECTION);
  1389 + glPopMatrix();
  1390 + glMatrixMode(GL_MODELVIEW);
  1391 + CHECK_OPENGL_ERROR
  1392 + glPopMatrix();
  1393 +
  1394 + // glEnable(GL_CULL_FACE);
  1395 + hits = glRenderMode(GL_RENDER);
  1396 + int found_hits = processHits(hits, selectBuf);
  1397 + return found_hits;
  1398 + }
  1399 +
  1400 + //Given a size of the array (hits) and the memory holding it (buffer)
  1401 + //returns whether a hit tool place or not.
  1402 + int
  1403 + processHits(GLint hits, GLuint buffer[])
  1404 + {
  1405 + GLuint names, *ptr;
  1406 + //printf("hits = %u\n", hits);
  1407 + ptr = (GLuint *) buffer;
  1408 + // for (int i = 0; i < hits; i++) { /* for each hit */
  1409 + names = *ptr;
  1410 + // printf (" number of names for hit = %u\n", names);
  1411 + ptr++;
  1412 + ptr++; //Skip the minimum depth value.
  1413 + ptr++; //Skip the maximum depth value.
  1414 + // printf (" the name is ");
  1415 + // for (int j = 0; j < names; j++) { /* for each name */
  1416 + // printf ("%u ", *ptr); ptr++;
  1417 + // }
  1418 + // printf ("\n");
  1419 + // }
  1420 +
  1421 +
  1422 + if(hits == 0)
  1423 + {
  1424 + return -1;
  1425 + }
  1426 + else
  1427 + {
  1428 +// printf ("%u ", *ptr);
  1429 + return *ptr;
  1430 + }
  1431 + }
  1432 +
  1433 + void
  1434 + clearCurrent()
  1435 + {
  1436 + cL.clear();
  1437 + cM.clear();
  1438 + }
  1439 +
  1440 + void
  1441 + addToNetwork(pair<stim::fiber<float>, int> in, stim::vec<float> spos,
  1442 + stim::vec<float> smag, stim::vec<float> sdir)
  1443 + {
  1444 + std::vector<stim::vec<float> > ce = in.first.centerline();
  1445 + std::vector<stim::vec<float> > cm = in.first.centerlinemag();
  1446 + //if the fiber is longer than 2 steps (the number it takes to diverge)
  1447 + if(ce.size() > 3)
  1448 + {
  1449 + //if we did not hit a fiber
  1450 + if(in.second == -1)
  1451 + {
  1452 + spos[0] = spos[0]-sdir[0]*smag[0]/2.;
  1453 + spos[1] = spos[1]-sdir[1]*smag[0]/2.;
  1454 + spos[2] = spos[2]-sdir[2]*smag[0]/2.;
  1455 + int h = selectObject(spos, -sdir, smag[0]);
  1456 + //did we start with a fiber?
  1457 + if(h != -1)
  1458 + nt.addEdge(ce, cm, h, -1);
  1459 + else
  1460 + nt.addEdge(ce, cm, -1, -1);
  1461 + }
  1462 + //if we hit a fiber?
  1463 + else if(in.second != -1)
  1464 + {
  1465 + nt.addEdge(ce,cm,-1, in.second);
  1466 + spos[0] = spos[0]-sdir[0]*smag[0]/2.;
  1467 + spos[1] = spos[1]-sdir[1]*smag[0]/2.;
  1468 + spos[2] = spos[2]-sdir[2]*smag[0]/2.;
  1469 + int h = selectObject(spos, -sdir, smag[0]);
  1470 + //did start with a fiber?
  1471 + if(h != -1){
  1472 + // std::cout << "got here double" << smag.str() << std::endl;
  1473 + nt.addEdge(ce,cm, h, in.second);
  1474 + }
  1475 + }
  1476 + }
  1477 + }
  1478 +
  1479 +
  1480 + void
  1481 + printSizes()
  1482 + {
  1483 + std::cout << nt.sizeE() << " edges " << std::endl;
  1484 + std::cout << nt.sizeV() << " nodes " << std::endl;
  1485 +
  1486 + }
  1487 +
  1488 + std::pair<stim::fiber<float>, int >
  1489 + traceLine(stim::vec<float> pos, stim::vec<float> mag, int min_cost)
  1490 + {
  1491 + //starting (seed) position and magnitude.
  1492 + stim::vec<float> spos = getPosition();
  1493 + stim::vec<float> smag = getMagnitude();
  1494 + stim::vec<float> sdir = getDirection();
  1495 +
  1496 + Bind();
  1497 + sk.Begin(stim::OBJ_LINE);
  1498 +
  1499 +
  1500 +// sk.createFromSelf(GL_SELECT);
  1501 + nt.createFromSelf(GL_SELECT);
  1502 +
  1503 + cL.push_back(pos);
  1504 + cM.push_back(mag);
  1505 +
  1506 +// setPosition(pos);
  1507 +// setMagnitude(mag);
  1508 + int h;
  1509 + bool started = false;
  1510 + bool running = true;
  1511 + stim::vec<float> size(S[0]*R[0], S[1]*R[1], S[2]*R[2]);
  1512 + while(running)
  1513 + {
  1514 + int cost = Step();
  1515 + if (cost > min_cost){
  1516 + running = false;
  1517 + sk.End();
  1518 + pair<stim::fiber<float>, int> a(stim::fiber<float> (cL, cM), -1);
  1519 + addToNetwork(a, spos, smag, sdir);
  1520 + return a;
  1521 + break;
  1522 + } else {
  1523 + //Have we found the edge of the map?
  1524 + pos = getPosition();
  1525 + if(pos[0] > size[0] || pos[1] > size[1]
  1526 + || pos[2] > size[2] || pos[0] < 0
  1527 + || pos[1] < 0 || pos[2] < 0)
  1528 + {
  1529 +// std::cout << "Found Edge" << std::endl;
  1530 + running = false;
  1531 + sk.End();
  1532 + pair<stim::fiber<float>, int> a(stim::fiber<float> (cL, cM), -1);
  1533 + addToNetwork(a, spos, smag, sdir);
  1534 + return a;
  1535 + break;
  1536 + }
  1537 + //If this is the first step in the trace,
  1538 + // save the direction
  1539 + //(to be used later to trace the fiber in the opposite direction)
  1540 + if(started == false){
  1541 + rev = -getDirection();
  1542 + started = true;
  1543 + }
  1544 +// std::cout << i << p << std::endl;
  1545 + //Has the template size gotten unreasonable?
  1546 + mag = getMagnitude();
  1547 + if(mag[0] > 75 || mag[0] < 1){
  1548 +// std::cout << "Magnitude Limit" << std::endl;
  1549 + running = false;
  1550 + sk.End();
  1551 + pair<stim::fiber<float>, int> a(stim::fiber<float> (cL, cM), -1);
  1552 + addToNetwork(a, spos, smag, sdir);
  1553 + return a;
  1554 + break;
  1555 + }
  1556 + else
  1557 + {
  1558 + h = selectObject(p, getDirection(), m[0]);
  1559 + //Have we hit something previously traced?
  1560 + if(h != -1){
  1561 + running = false;
  1562 + sk.End();
  1563 + pair<stim::fiber<float>, int> a(stim::fiber<float> (cL, cM), h);
  1564 + addToNetwork(a, spos, smag, sdir);
  1565 + return a;
  1566 + break;
  1567 + }
  1568 + else {
  1569 + cL.push_back(stim::vec<float>(p[0], p[1],p[2]));
  1570 + 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
  1579 + Unbind();
  1580 + CHECK_OPENGL_ERROR
  1581 +
  1582 + }
  1583 + }
  1584 + }
  1585 + }
  1586 + }
  1587 +
  1588 +
  1589 +
793 }; 1590 };
794 } 1591 }
795 #endif 1592 #endif
stim/gl/gl_texture.h
@@ -31,10 +31,9 @@ template&lt;typename T&gt; @@ -31,10 +31,9 @@ template&lt;typename T&gt;
31 class gl_texture : public virtual image_stack<T> 31 class gl_texture : public virtual image_stack<T>
32 { 32 {
33 private: 33 private:
34 - ///Method: setTextureType  
35 /// Sets the internal texture_type, based on the data 34 /// Sets the internal texture_type, based on the data
36 /// size. Either 3D, 2D, 1D textures. 35 /// size. Either 3D, 2D, 1D textures.
37 - 36 +
38 void 37 void
39 setTextureType() 38 setTextureType()
40 { 39 {
@@ -60,16 +59,14 @@ class gl_texture : public virtual image_stack&lt;T&gt; @@ -60,16 +59,14 @@ class gl_texture : public virtual image_stack&lt;T&gt;
60 59
61 public: 60 public:
62 61
63 - ///Method: Basic Constructor  
64 - /// Creates an instance of the gl_texture object. 62 + ///default constructor
65 gl_texture() 63 gl_texture()
66 { 64 {
67 65
68 } 66 }
69 67
70 - ///Method: Path Constructor  
71 - ///@param string file_path path to the directory with the files.  
72 - /// Creates an instance of the gl_texture object with a path to the data. 68 + ///@param string path to the directory with the image files.
  69 + ///Creates an instance of the gl_texture object with a path to the data.
73 70
74 gl_texture(std::string file_path) 71 gl_texture(std::string file_path)
75 { 72 {
@@ -77,8 +74,8 @@ class gl_texture : public virtual image_stack&lt;T&gt; @@ -77,8 +74,8 @@ class gl_texture : public virtual image_stack&lt;T&gt;
77 image_stack<T>::load_images(path.append("/*.jpg")); 74 image_stack<T>::load_images(path.append("/*.jpg"));
78 setTextureType(); 75 setTextureType();
79 } 76 }
80 - ///Method:getSize  
81 - ///returns the dimentions of 77 +
  78 + ///returns the dimentions of the data in the x, y, z directions.
82 vec<int> 79 vec<int>
83 getSize() 80 getSize()
84 { 81 {
@@ -86,7 +83,6 @@ class gl_texture : public virtual image_stack&lt;T&gt; @@ -86,7 +83,6 @@ class gl_texture : public virtual image_stack&lt;T&gt;
86 return size; 83 return size;
87 } 84 }
88 85
89 - ///Method:setTexParam  
90 ///@param GLint interp --GL_LINEAR, GL_NEAREST... 86 ///@param GLint interp --GL_LINEAR, GL_NEAREST...
91 ///@param GLint twrap --GL_REPEAR, GL_CLAMP_TO_EDGE... 87 ///@param GLint twrap --GL_REPEAR, GL_CLAMP_TO_EDGE...
92 ///@param GLenum dataType --GL_UNSIGNED_BYTE, GL_FLOAT16... 88 ///@param GLenum dataType --GL_UNSIGNED_BYTE, GL_FLOAT16...
@@ -103,7 +99,7 @@ class gl_texture : public virtual image_stack&lt;T&gt; @@ -103,7 +99,7 @@ class gl_texture : public virtual image_stack&lt;T&gt;
103 type = dataType; 99 type = dataType;
104 format = dataFormat; 100 format = dataFormat;
105 } 101 }
106 - ///Method:setDims 102 +
107 ///@param x size of the voxel in x direction 103 ///@param x size of the voxel in x direction
108 ///@param y size of the voxel in y direction 104 ///@param y size of the voxel in y direction
109 ///@param z size of the voxel in z direction 105 ///@param z size of the voxel in z direction
@@ -116,9 +112,7 @@ class gl_texture : public virtual image_stack&lt;T&gt; @@ -116,9 +112,7 @@ class gl_texture : public virtual image_stack&lt;T&gt;
116 S[3] = z; 112 S[3] = z;
117 } 113 }
118 114
119 - ///Method:getDims  
120 - /// get the dimenstions of the voxels.  
121 - 115 + ///Returns a stim::vec that contains the x, y, z sizes of the voxel.
122 vec<float> 116 vec<float>
123 getDims() 117 getDims()
124 { 118 {
@@ -126,11 +120,8 @@ class gl_texture : public virtual image_stack&lt;T&gt; @@ -126,11 +120,8 @@ class gl_texture : public virtual image_stack&lt;T&gt;
126 return dims; 120 return dims;
127 } 121 }
128 122
129 - ///Method:setPath  
130 ///@param file_Path location of the directory with the files 123 ///@param file_Path location of the directory with the files
131 /// Sets the path and calls the loader on that path. 124 /// Sets the path and calls the loader on that path.
132 -  
133 -  
134 void 125 void
135 setPath(std::string file_path) 126 setPath(std::string file_path)
136 { 127 {
@@ -139,19 +130,14 @@ class gl_texture : public virtual image_stack&lt;T&gt; @@ -139,19 +130,14 @@ class gl_texture : public virtual image_stack&lt;T&gt;
139 setTextureType(); 130 setTextureType();
140 } 131 }
141 132
142 - ///Method: getPath  
143 - ///Outputs: string path  
144 - /// Returns the path associated with an instance of the gl_texture class.  
145 - 133 + /// Returns an std::string path associated with an instance of the gl_texture class.
146 std::string 134 std::string
147 getPath() 135 getPath()
148 { 136 {
149 return path; 137 return path;
150 } 138 }
151 139
152 - ///Method: getTexture  
153 - ///Outputs: GLuint texID  
154 - /// Returns the id of the texture create by/associated with the 140 + /// Returns the GLuint id of the texture created by/associated with the
155 /// instance of the gl_texture class. 141 /// instance of the gl_texture class.
156 142
157 GLuint 143 GLuint
@@ -160,7 +146,6 @@ class gl_texture : public virtual image_stack&lt;T&gt; @@ -160,7 +146,6 @@ class gl_texture : public virtual image_stack&lt;T&gt;
160 return texID; 146 return texID;
161 } 147 }
162 148
163 - ///Method: createTexture  
164 /// Creates a texture and from the loaded data and 149 /// Creates a texture and from the loaded data and
165 /// assigns that texture to texID 150 /// assigns that texture to texID
166 //TO DO :::: 1D textures 151 //TO DO :::: 1D textures
1 -#ifndef RTS_PLANE_H  
2 -#define RTS_PLANE_H 1 +#ifndef STIM_PLANE_H
  2 +#define STIM_PLANE_H
3 3
4 #include <iostream> 4 #include <iostream>
5 #include <stim/math/vector.h> 5 #include <stim/math/vector.h>
6 -#include "rts/cuda/callable.h" 6 +#include <stim/cuda/cudatools/callable.h>
  7 +#include <stim/math/quaternion.h>
7 8
8 9
9 -namespace stim{  
10 -template <typename T, int D> class plane; 10 +namespace stim
  11 +{
  12 +template<typename T> class plane;
11 } 13 }
12 14
13 -template <typename T, int D>  
14 -CUDA_CALLABLE stim::plane<T, D> operator-(stim::plane<T, D> v);  
15 -  
16 -namespace stim{  
17 -  
18 -template <class T, int D = 3>  
19 -class plane{  
20 -  
21 - //a plane is defined by a point and a normal  
22 -  
23 -private:  
24 -  
25 - vec<T, D> P; //point on the plane  
26 - vec<T, D> N; //plane normal  
27 -  
28 - CUDA_CALLABLE void init(){  
29 - P = vec<T, D>(0, 0, 0);  
30 - N = vec<T, D>(0, 0, 1);  
31 - }  
32 -  
33 -  
34 -public:  
35 -  
36 - //default constructor  
37 - CUDA_CALLABLE plane(){  
38 - init();  
39 - } 15 +template<typename T>
  16 +CUDA_CALLABLE stim::plane<T> operator-(stim::plane<T> v);
  17 +
  18 +namespace stim
  19 +{
  20 +
  21 +template <typename T>
  22 +class plane
  23 +{
  24 + protected:
  25 + stim::vec<T> P;
  26 + stim::vec<T> N;
  27 + stim::vec<T> U;
  28 +
  29 + ///Initializes the plane with standard coordinates.
  30 + ///
  31 + CUDA_CALLABLE void init()
  32 + {
  33 + P = stim::vec<T>(0, 0, 0);
  34 + N = stim::vec<T>(0, 0, 1);
  35 + U = stim::vec<T>(1, 0, 0);
  36 + }
  37 +
  38 + public:
40 39
41 - CUDA_CALLABLE plane(vec<T, D> n, vec<T, D> p = vec<T, D>(0, 0, 0)){  
42 - P = p;  
43 - N = n.norm();  
44 - }  
45 -  
46 - CUDA_CALLABLE plane(T z_pos){  
47 - init();  
48 - P[2] = z_pos;  
49 - }  
50 -  
51 - //create a plane from three points (a triangle)  
52 - CUDA_CALLABLE plane(vec<T, D> a, vec<T, D> b, vec<T, D> c){  
53 - P = c;  
54 - N = (c - a).cross(b - a);  
55 - if(N.len() == 0) //handle the degenerate case when two vectors are the same, N = 0  
56 - N = 0;  
57 - else  
58 - N = N.norm();  
59 - }  
60 -  
61 - template< typename U >  
62 - CUDA_CALLABLE operator plane<U, D>(){  
63 -  
64 - plane<U, D> result(N, P);  
65 - return result;  
66 - }  
67 -  
68 - CUDA_CALLABLE vec<T, D> norm(){  
69 - return N;  
70 - }  
71 -  
72 - CUDA_CALLABLE vec<T, D> p(){  
73 - return P;  
74 - }  
75 -  
76 - //flip the plane front-to-back  
77 - CUDA_CALLABLE plane<T, D> flip(){  
78 - plane<T, D> result = *this;  
79 - result.N = -result.N;  
80 - return result;  
81 - }  
82 -  
83 - //determines how a vector v intersects the plane (1 = intersects front, 0 = within plane, -1 = intersects back)  
84 - CUDA_CALLABLE int face(vec<T, D> v){  
85 -  
86 - T dprod = v.dot(N); //get the dot product between v and N  
87 -  
88 - //conditional returns the appropriate value  
89 - if(dprod < 0)  
90 - return 1;  
91 - else if(dprod > 0)  
92 - return -1;  
93 - else  
94 - return 0;  
95 - }  
96 -  
97 - //determine on which side of the plane a point lies (1 = front, 0 = on the plane, -1 = back)  
98 - CUDA_CALLABLE int side(vec<T, D> p){  
99 -  
100 - vec<T, D> v = p - P; //get the vector from P to the query point p  
101 -  
102 - return face(v);  
103 - }  
104 -  
105 - //compute the component of v that is perpendicular to the plane  
106 - CUDA_CALLABLE vec<T, D> perpendicular(vec<T, D> v){  
107 - return N * v.dot(N);  
108 - }  
109 -  
110 - //compute the projection of v in the plane  
111 - CUDA_CALLABLE vec<T, D> parallel(vec<T, D> v){  
112 - return v - perpendicular(v);  
113 - }  
114 -  
115 - CUDA_CALLABLE void decompose(vec<T, D> v, vec<T, D>& para, vec<T, D>& perp){  
116 - perp = N * v.dot(N);  
117 - para = v - perp;  
118 - }  
119 -  
120 - //get both the parallel and perpendicular components of a vector v w.r.t. the plane  
121 - CUDA_CALLABLE void project(vec<T, D> v, vec<T, D> &v_par, vec<T, D> &v_perp){  
122 -  
123 - v_perp = v.dot(N);  
124 - v_par = v - v_perp;  
125 - }  
126 -  
127 - //compute the reflection of v off of the plane  
128 - CUDA_CALLABLE vec<T, D> reflect(vec<T, D> v){  
129 -  
130 - //compute the reflection using N_prime as the plane normal  
131 - vec<T, D> par = parallel(v);  
132 - vec<T, D> r = (-v) + par * 2;  
133 -  
134 - /*std::cout<<"----------------REFLECT-----------------------------"<<std::endl;  
135 - std::cout<<str()<<std::endl;  
136 - std::cout<<"v: "<<v<<std::endl;  
137 - std::cout<<"r: "<<r<<std::endl;  
138 - std::cout<<"Perpendicular: "<<perpendicular(v)<<std::endl;  
139 - std::cout<<"Parallel: "<<par<<std::endl;*/  
140 - return r;  
141 -  
142 - }  
143 -  
144 - CUDA_CALLABLE rts::plane<T, D> operator-()  
145 - {  
146 - rts::plane<T, D> p = *this;  
147 -  
148 - //negate the normal vector  
149 - p.N = -p.N;  
150 -  
151 - return p;  
152 - }  
153 -  
154 - //output a string  
155 - std::string str(){  
156 - std::stringstream ss;  
157 - ss<<"P: "<<P<<std::endl;  
158 - ss<<"N: "<<N;  
159 - return ss.str();  
160 - }  
161 -  
162 - ///////Friendship  
163 - //friend CUDA_CALLABLE rts::plane<T, D> operator- <> (rts::plane<T, D> v);  
164 -  
165 - 40 + CUDA_CALLABLE plane()
  41 + {
  42 + init();
  43 + }
  44 +
  45 + CUDA_CALLABLE plane(vec<T> n, vec<T> p = vec<T>(0, 0, 0))
  46 + {
  47 + init();
  48 + P = p;
  49 + rotate(n.norm());
  50 + }
  51 +
  52 + CUDA_CALLABLE plane(T z_pos)
  53 + {
  54 + init();
  55 + P[2] = z_pos;
  56 + }
  57 +
  58 + //create a plane from three points (a triangle)
  59 + CUDA_CALLABLE plane(vec<T> a, vec<T> b, vec<T> c)
  60 + {
  61 + init();
  62 + P = c;
  63 + stim::vec<T> n = (c - a).cross(b - a);
  64 + try
  65 + {
  66 + if(n.len() != 0)
  67 + {
  68 + rotate(n.norm());
  69 + } else {
  70 + throw 42;
  71 + }
  72 + }
  73 + catch(int i)
  74 + {
  75 + std::cerr << "No plane can be creates as all points a,b,c lie on a straight line" << std::endl;
  76 + }
  77 + }
  78 +
  79 + template< typename U >
  80 + CUDA_CALLABLE operator plane<U>()
  81 + {
  82 + plane<U> result(N, P);
  83 + return result;
  84 +
  85 + }
  86 +
  87 + CUDA_CALLABLE vec<T> n()
  88 + {
  89 + return N;
  90 + }
  91 +
  92 + CUDA_CALLABLE vec<T> p()
  93 + {
  94 + return P;
  95 + }
  96 +
  97 + CUDA_CALLABLE vec<T> u()
  98 + {
  99 + return U;
  100 + }
  101 +
  102 + ///flip the plane front-to-back
  103 + CUDA_CALLABLE plane<T> flip(){
  104 + plane<T> result = *this;
  105 + result.N = -result.N;
  106 + return result;
  107 + }
  108 +
  109 + //determines how a vector v intersects the plane (1 = intersects front, 0 = within plane, -1 = intersects back)
  110 + CUDA_CALLABLE int face(vec<T> v){
  111 +
  112 + T dprod = v.dot(N); //get the dot product between v and N
  113 +
  114 + //conditional returns the appropriate value
  115 + if(dprod < 0)
  116 + return 1;
  117 + else if(dprod > 0)
  118 + return -1;
  119 + else
  120 + return 0;
  121 + }
  122 +
  123 + //determine on which side of the plane a point lies (1 = front, 0 = on the plane, -1 = bac k)
  124 + CUDA_CALLABLE int side(vec<T> p){
  125 +
  126 + vec<T> v = p - P; //get the vector from P to the query point p
  127 +
  128 + return face(v);
  129 + }
  130 +
  131 + //compute the component of v that is perpendicular to the plane
  132 + CUDA_CALLABLE vec<T> perpendicular(vec<T> v){
  133 + return N * v.dot(N);
  134 + }
  135 +
  136 + //compute the projection of v in the plane
  137 + CUDA_CALLABLE vec<T> parallel(vec<T> v){
  138 + return v - perpendicular(v);
  139 + }
  140 +
  141 + CUDA_CALLABLE void setU(vec<T> v)
  142 + {
  143 + U = (parallel(v.norm())).norm();
  144 + }
  145 +
  146 + CUDA_CALLABLE void decompose(vec<T> v, vec<T>& para, vec<T>& perp){
  147 + perp = N * v.dot(N);
  148 + para = v - perp;
  149 + }
  150 +
  151 + //get both the parallel and perpendicular components of a vector v w.r.t. the plane
  152 + CUDA_CALLABLE void project(vec<T> v, vec<T> &v_par, vec<T> &v_perp){
  153 +
  154 + v_perp = v.dot(N);
  155 + v_par = v - v_perp;
  156 + }
  157 +
  158 + //compute the reflection of v off of the plane
  159 + CUDA_CALLABLE vec<T> reflect(vec<T> v){
  160 +
  161 + //compute the reflection using N_prime as the plane normal
  162 + vec<T> par = parallel(v);
  163 + vec<T> r = (-v) + par * 2;
  164 + return r;
  165 +
  166 + }
  167 +
  168 + CUDA_CALLABLE stim::plane<T> operator-()
  169 + {
  170 + stim::plane<T> p = *this;
  171 +
  172 + //negate the normal vector
  173 + p.N = -p.N;
  174 + return p;
  175 + }
  176 +
  177 + //output a string
  178 + std::string str(){
  179 + std::stringstream ss;
  180 + ss<<"P: "<<P<<std::endl;
  181 + ss<<"N: "<<N<<std::endl;
  182 + ss<<"U: "<<U;
  183 + return ss.str();
  184 + }
  185 +
  186 +
  187 + CUDA_CALLABLE void rotate(vec<T> n)
  188 + {
  189 + quaternion<T> q;
  190 + q.CreateRotation(N, n);
  191 +
  192 + N = q.toMatrix3() * N;
  193 + U = q.toMatrix3() * U;
  194 +
  195 + }
  196 +
  197 + CUDA_CALLABLE void rotate(vec<T> n, vec<T> &X, 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 + X = q.toMatrix3() * X;
  205 + Y = q.toMatrix3() * Y;
  206 +
  207 + }
166 208
167 }; 209 };
168 - 210 +
  211 +
169 } 212 }
170 -  
171 -//arithmetic operators  
172 -  
173 -//negative operator flips the plane (front to back)  
174 -//template <typename T, int D>  
175 -  
176 -  
177 -  
178 -  
179 #endif 213 #endif
stim/math/plane_old.h 0 → 100644
  1 +#ifndef RTS_PLANE_H
  2 +#define RTS_PLANE_H
  3 +
  4 +#include <iostream>
  5 +#include <stim/math/vector.h>
  6 +#include "rts/cuda/callable.h"
  7 +
  8 +
  9 +namespace stim{
  10 +template <typename T, int D> class plane;
  11 +}
  12 +
  13 +template <typename T, int D>
  14 +CUDA_CALLABLE stim::plane<T, D> operator-(stim::plane<T, D> v);
  15 +
  16 +namespace stim{
  17 +
  18 +template <class T, int D = 3>
  19 +class plane{
  20 +
  21 + //a plane is defined by a point and a normal
  22 +
  23 +private:
  24 +
  25 + vec<T, D> P; //point on the plane
  26 + vec<T, D> N; //plane normal
  27 +
  28 + CUDA_CALLABLE void init(){
  29 + P = vec<T, D>(0, 0, 0);
  30 + N = vec<T, D>(0, 0, 1);
  31 + }
  32 +
  33 +
  34 +public:
  35 +
  36 + //default constructor
  37 + CUDA_CALLABLE plane(){
  38 + init();
  39 + }
  40 +
  41 + CUDA_CALLABLE plane(vec<T, D> n, vec<T, D> p = vec<T, D>(0, 0, 0)){
  42 + P = p;
  43 + N = n.norm();
  44 + }
  45 +
  46 + CUDA_CALLABLE plane(T z_pos){
  47 + init();
  48 + P[2] = z_pos;
  49 + }
  50 +
  51 + //create a plane from three points (a triangle)
  52 + CUDA_CALLABLE plane(vec<T, D> a, vec<T, D> b, vec<T, D> c){
  53 + P = c;
  54 + N = (c - a).cross(b - a);
  55 + if(N.len() == 0) //handle the degenerate case when two vectors are the same, N = 0
  56 + N = 0;
  57 + else
  58 + N = N.norm();
  59 + }
  60 +
  61 + template< typename U >
  62 + CUDA_CALLABLE operator plane<U, D>(){
  63 +
  64 + plane<U, D> result(N, P);
  65 + return result;
  66 + }
  67 +
  68 + CUDA_CALLABLE vec<T, D> norm(){
  69 + return N;
  70 + }
  71 +
  72 + CUDA_CALLABLE vec<T, D> p(){
  73 + return P;
  74 + }
  75 +
  76 + //flip the plane front-to-back
  77 + CUDA_CALLABLE plane<T, D> flip(){
  78 + plane<T, D> result = *this;
  79 + result.N = -result.N;
  80 + return result;
  81 + }
  82 +
  83 + //determines how a vector v intersects the plane (1 = intersects front, 0 = within plane, -1 = intersects back)
  84 + CUDA_CALLABLE int face(vec<T, D> v){
  85 +
  86 + T dprod = v.dot(N); //get the dot product between v and N
  87 +
  88 + //conditional returns the appropriate value
  89 + if(dprod < 0)
  90 + return 1;
  91 + else if(dprod > 0)
  92 + return -1;
  93 + else
  94 + return 0;
  95 + }
  96 +
  97 + //determine on which side of the plane a point lies (1 = front, 0 = on the plane, -1 = back)
  98 + CUDA_CALLABLE int side(vec<T, D> p){
  99 +
  100 + vec<T, D> v = p - P; //get the vector from P to the query point p
  101 +
  102 + return face(v);
  103 + }
  104 +
  105 + //compute the component of v that is perpendicular to the plane
  106 + CUDA_CALLABLE vec<T, D> perpendicular(vec<T, D> v){
  107 + return N * v.dot(N);
  108 + }
  109 +
  110 + //compute the projection of v in the plane
  111 + CUDA_CALLABLE vec<T, D> parallel(vec<T, D> v){
  112 + return v - perpendicular(v);
  113 + }
  114 +
  115 + CUDA_CALLABLE void decompose(vec<T, D> v, vec<T, D>& para, vec<T, D>& perp){
  116 + perp = N * v.dot(N);
  117 + para = v - perp;
  118 + }
  119 +
  120 + //get both the parallel and perpendicular components of a vector v w.r.t. the plane
  121 + CUDA_CALLABLE void project(vec<T, D> v, vec<T, D> &v_par, vec<T, D> &v_perp){
  122 +
  123 + v_perp = v.dot(N);
  124 + v_par = v - v_perp;
  125 + }
  126 +
  127 + //compute the reflection of v off of the plane
  128 + CUDA_CALLABLE vec<T, D> reflect(vec<T, D> v){
  129 +
  130 + //compute the reflection using N_prime as the plane normal
  131 + vec<T, D> par = parallel(v);
  132 + vec<T, D> r = (-v) + par * 2;
  133 +
  134 + /*std::cout<<"----------------REFLECT-----------------------------"<<std::endl;
  135 + std::cout<<str()<<std::endl;
  136 + std::cout<<"v: "<<v<<std::endl;
  137 + std::cout<<"r: "<<r<<std::endl;
  138 + std::cout<<"Perpendicular: "<<perpendicular(v)<<std::endl;
  139 + std::cout<<"Parallel: "<<par<<std::endl;*/
  140 + return r;
  141 +
  142 + }
  143 +
  144 + CUDA_CALLABLE rts::plane<T, D> operator-()
  145 + {
  146 + rts::plane<T, D> p = *this;
  147 +
  148 + //negate the normal vector
  149 + p.N = -p.N;
  150 +
  151 + return p;
  152 + }
  153 +
  154 + //output a string
  155 + std::string str(){
  156 + std::stringstream ss;
  157 + ss<<"P: "<<P<<std::endl;
  158 + ss<<"N: "<<N;
  159 + return ss.str();
  160 + }
  161 +
  162 + ///////Friendship
  163 + //friend CUDA_CALLABLE rts::plane<T, D> operator- <> (rts::plane<T, D> v);
  164 +
  165 +
  166 +
  167 +};
  168 +
  169 +}
  170 +
  171 +//arithmetic operators
  172 +
  173 +//negative operator flips the plane (front to back)
  174 +//template <typename T, int D>
  175 +
  176 +
  177 +
  178 +
  179 +#endif
stim/math/quaternion.h
@@ -41,13 +41,14 @@ public: @@ -41,13 +41,14 @@ public:
41 z = u_hat[2]*(T)sin(theta/2); 41 z = u_hat[2]*(T)sin(theta/2);
42 } 42 }
43 43
44 - CUDA_CALLABLE void CreateRotation(vec<T> from, vec<T> to){ 44 + void CreateRotation(vec<T> from, vec<T> to){
45 45
46 vec<T> r = from.cross(to); //compute the rotation vector 46 vec<T> r = from.cross(to); //compute the rotation vector
47 T theta = asin(r.len()); //compute the angle of the rotation about r 47 T theta = asin(r.len()); //compute the angle of the rotation about r
48 //deal with a zero vector (both k and kn point in the same direction) 48 //deal with a zero vector (both k and kn point in the same direction)
49 - if(theta == (T)0) 49 + if(theta == (T)0){
50 return; 50 return;
  51 + }
51 52
52 //create a quaternion to capture the rotation 53 //create a quaternion to capture the rotation
53 CreateRotation(theta, r.norm()); 54 CreateRotation(theta, r.norm());
1 -#ifndef RTS_RECT_H  
2 -#define RTS_RECT_H 1 +#ifndef STIM_RECT_H
  2 +#define STIM_RECT_H
  3 +
3 4
4 //enable CUDA_CALLABLE macro 5 //enable CUDA_CALLABLE macro
5 #include <stim/cuda/cudatools/callable.h> 6 #include <stim/cuda/cudatools/callable.h>
  7 +#include <stim/math/plane.h>
6 #include <stim/math/vector.h> 8 #include <stim/math/vector.h>
7 #include <stim/math/triangle.h> 9 #include <stim/math/triangle.h>
8 -#include <stim/math/quaternion.h>  
9 #include <iostream> 10 #include <iostream>
10 #include <iomanip> 11 #include <iomanip>
11 #include <algorithm> 12 #include <algorithm>
  13 +#include <assert.h>
12 14
13 namespace stim{ 15 namespace stim{
14 16
15 //template for a rectangle class in ND space 17 //template for a rectangle class in ND space
16 -template <class T>  
17 -struct rect 18 +template <typename T>
  19 +class rect : plane <T>
18 { 20 {
19 /* 21 /*
20 ^ O 22 ^ O
21 | 23 |
22 | 24 |
23 - Y C 25 + Y P
24 | 26 |
25 | 27 |
26 O---------X---------> 28 O---------X--------->
@@ -28,106 +30,143 @@ struct rect @@ -28,106 +30,143 @@ struct rect
28 30
29 private: 31 private:
30 32
31 - stim::vec<T> C;  
32 stim::vec<T> X; 33 stim::vec<T> X;
33 stim::vec<T> Y; 34 stim::vec<T> Y;
34 35
35 - CUDA_CALLABLE void scale(T factor){  
36 - X *= factor;  
37 - Y *= factor;  
38 - }  
39 36
40 37
41 - CUDA_CALLABLE void normal(vec<T> n){ //orient the rectangle along the specified normal  
42 -  
43 - n = n.norm(); //normalize, just in case  
44 - vec<T> n_current = X.cross(Y).norm(); //compute the current normal  
45 - quaternion<T> q; //create a quaternion  
46 - q.CreateRotation(n_current, n); //initialize a rotation from n_current to n  
47 -  
48 - //apply the quaternion to the vectors and position  
49 - X = q.toMatrix3() * X;  
50 - Y = q.toMatrix3() * Y;  
51 - }  
52 -  
53 - CUDA_CALLABLE void init(){  
54 - C = vec<T>(0, 0, 0);  
55 - X = vec<T>(1, 0, 0);  
56 - Y = vec<T>(0, 1, 0);  
57 - }  
58 38
59 public: 39 public:
60 40
61 - CUDA_CALLABLE rect(){ 41 + using stim::plane<T>::n;
  42 + using stim::plane<T>::P;
  43 + using stim::plane<T>::N;
  44 + using stim::plane<T>::U;
  45 + using stim::plane<T>::rotate;
  46 +
  47 + ///base constructor.
  48 + CUDA_CALLABLE rect()
  49 + : plane<T>()
  50 + {
62 init(); 51 init();
63 } 52 }
64 53
65 - //create a rectangle given a size and position  
66 - CUDA_CALLABLE rect(T size, T z_pos = (T)0){ 54 + ///create a rectangle given a size and position in Z space.
  55 + ///@param size: size of the rectangle in ND space.
  56 + ///@param z_pos z coordinate of the rectangle.
  57 + CUDA_CALLABLE rect(T size, T z_pos = (T)0)
  58 + : plane<T>(z_pos)
  59 + {
67 init(); //use the default setup 60 init(); //use the default setup
68 scale(size); //scale the rectangle 61 scale(size); //scale the rectangle
69 - C[2] = z_pos;  
70 } 62 }
71 63
72 64
73 - //create a rectangle from a center point, normal, and size  
74 - CUDA_CALLABLE rect(vec<T> c, vec<T> n = vec<T>(0, 0, 1)){ 65 + ///create a rectangle from a center point, normal
  66 + ///@param c: x,y,z location of the center.
  67 + ///@param n: x,y,z direction of the normal.
  68 + CUDA_CALLABLE rect(vec<T> c, vec<T> n = vec<T>(0, 0, 1))
  69 + : plane<T>()
  70 + {
75 init(); //start with the default setting 71 init(); //start with the default setting
76 - C = c;  
77 normal(n); //orient 72 normal(n); //orient
78 } 73 }
79 74
  75 + ///create a rectangle from a center point, normal, and size
  76 + ///@param c: x,y,z location of the center.
  77 + ///@param s: size of the rectangle.
  78 + ///@param n: x,y,z direction of the normal.
  79 + CUDA_CALLABLE rect(vec<T> c, T s, vec<T> n = vec<T>(0, 0, 1))
  80 + : plane<T>()
  81 + {
  82 + init(); //start with the default setting
  83 + scale(s);
  84 + center(c);
  85 + rotate(n, X, Y);
  86 + }
  87 +
  88 + ///creates a rectangle from a centerpoint and an X and Y direction vectors.
  89 + ///@param center: x,y,z location of the center.
  90 + ///@param directionX: u,v,w direction of the X vector.
  91 + ///@param directionY: u,v,w direction of the Y vector.
80 CUDA_CALLABLE rect(vec<T> center, vec<T> directionX, vec<T> directionY ) 92 CUDA_CALLABLE rect(vec<T> center, vec<T> directionX, vec<T> directionY )
  93 + : plane<T>((directionX.cross(directionY)).norm(),center)
81 { 94 {
82 - C = center;  
83 X = directionX; 95 X = directionX;
84 Y = directionY; 96 Y = directionY;
85 } 97 }
86 98
  99 + ///creates a rectangle from a size, centerpoint, X, and Y direction vectors.
  100 + ///@param size of the rectangle in ND space.
  101 + ///@param center: x,y,z location of the center.
  102 + ///@param directionX: u,v,w direction of the X vector.
  103 + ///@param directionY: u,v,w direction of the Y vector.
87 CUDA_CALLABLE rect(T size, vec<T> center, vec<T> directionX, vec<T> directionY ) 104 CUDA_CALLABLE rect(T size, vec<T> center, vec<T> directionX, vec<T> directionY )
  105 + : plane<T>((directionX.cross(directionY)).norm(),center)
88 { 106 {
89 - C = center;  
90 X = directionX; 107 X = directionX;
91 Y = directionY; 108 Y = directionY;
92 scale(size); 109 scale(size);
93 } 110 }
94 -  
95 - CUDA_CALLABLE rect(vec<T> size, vec<T> center, vec<T> directionX, vec<T> directionY ) 111 +
  112 + ///creates a rectangle from a size, centerpoint, X, and Y direction vectors.
  113 + ///@param size of the rectangle in ND space, size[0] = size in X, size[1] = size in Y.
  114 + ///@param center: x,y,z location of the center.
  115 + ///@param directionX: u,v,w direction of the X vector.
  116 + ///@param directionY: u,v,w direction of the Y vector.
  117 + CUDA_CALLABLE rect(vec<T> size, vec<T> center, vec<T> directionX, vec<T> directionY)
  118 + : plane<T>((directionX.cross(directionY)).norm(), center)
96 { 119 {
97 - C = center;  
98 X = directionX; 120 X = directionX;
99 Y = directionY; 121 Y = directionY;
100 scale(size[0], size[1]); 122 scale(size[0], size[1]);
101 } 123 }
102 -  
103 - CUDA_CALLABLE void scale(T factor1, T factor2){ 124 +
  125 + CUDA_CALLABLE void scale(T factor){
  126 + X *= factor;
  127 + Y *= factor;
  128 + }
  129 +
  130 + ///scales a rectangle in ND space.
  131 + ///@param factor1: size of the scale in the X-direction.
  132 + ///@param factor2: size of the scale in the Y-direction.
  133 + CUDA_CALLABLE void scale(T factor1, T factor2)
  134 + {
104 X *= factor1; 135 X *= factor1;
105 Y *= factor2; 136 Y *= factor2;
106 } 137 }
107 138
  139 + ///@param n; vector with the normal.
  140 + ///Orients the rectangle along the normal n.
  141 + CUDA_CALLABLE void normal(vec<T> n)
  142 + {
  143 + //orient the rectangle along the specified normal
  144 + rotate(n, X, Y);
  145 + }
  146 +
  147 + ///general init method that sets a general rectangle.
  148 + CUDA_CALLABLE void init()
  149 + {
  150 + X = vec<T>(1, 0, 0);
  151 + Y = vec<T>(0, 1, 0);
  152 + }
  153 +
108 //boolean comparison 154 //boolean comparison
109 bool operator==(const rect<T> & rhs) 155 bool operator==(const rect<T> & rhs)
110 { 156 {
111 - if(C == rhs.C && X == rhs.X && Y == rhs.Y) 157 + if(P == rhs.P && X == rhs.X && Y == rhs.Y)
112 return true; 158 return true;
113 else 159 else
114 return false; 160 return false;
115 } 161 }
116 162
117 - /*******************************************  
118 - Return the normal for the rect  
119 - *******************************************/  
120 - CUDA_CALLABLE stim::vec<T> n()  
121 - {  
122 - return (X.cross(Y)).norm();  
123 - }  
124 163
125 //get the world space value given the planar coordinates a, b in [0, 1] 164 //get the world space value given the planar coordinates a, b in [0, 1]
126 CUDA_CALLABLE stim::vec<T> p(T a, T b) 165 CUDA_CALLABLE stim::vec<T> p(T a, T b)
127 { 166 {
128 stim::vec<T> result; 167 stim::vec<T> result;
129 //given the two parameters a, b = [0 1], returns the position in world space 168 //given the two parameters a, b = [0 1], returns the position in world space
130 - vec<T> A = C - X * (T)0.5 - Y * (T)0.5; 169 + vec<T> A = this->P - X * (T)0.5 - Y * (T)0.5;
131 result = A + X * a + Y * b; 170 result = A + X * a + Y * b;
132 171
133 return result; 172 return result;
@@ -142,16 +181,16 @@ public: @@ -142,16 +181,16 @@ public:
142 std::string str() 181 std::string str()
143 { 182 {
144 std::stringstream ss; 183 std::stringstream ss;
145 - vec<T> A = C - X * (T)0.5 - Y * (T)0.5; 184 + vec<T> A = P - X * (T)0.5 - Y * (T)0.5;
146 ss<<std::left<<"B="<<std::setfill('-')<<std::setw(20)<<A + Y<<">"<<"C="<<A + Y + X<<std::endl; 185 ss<<std::left<<"B="<<std::setfill('-')<<std::setw(20)<<A + Y<<">"<<"C="<<A + Y + X<<std::endl;
147 ss<<std::setfill(' ')<<std::setw(23)<<"|"<<"|"<<std::endl<<std::setw(23)<<"|"<<"|"<<std::endl; 186 ss<<std::setfill(' ')<<std::setw(23)<<"|"<<"|"<<std::endl<<std::setw(23)<<"|"<<"|"<<std::endl;
148 ss<<std::left<<"A="<<std::setfill('-')<<std::setw(20)<<A<<">"<<"D="<<A + X; 187 ss<<std::left<<"A="<<std::setfill('-')<<std::setw(20)<<A<<">"<<"D="<<A + X;
149 188
150 - return ss.str(); 189 + return ss.str();
151 190
152 } 191 }
153 192
154 - //scales the rectangle by a value rhs 193 + ///multiplication operator scales the rectangle by a value rhs.
155 CUDA_CALLABLE rect<T> operator*(T rhs) 194 CUDA_CALLABLE rect<T> operator*(T rhs)
156 { 195 {
157 //scales the plane by a scalar value 196 //scales the plane by a scalar value
@@ -164,36 +203,44 @@ public: @@ -164,36 +203,44 @@ public:
164 203
165 } 204 }
166 205
167 - //computes the distance between the specified point and this rectangle 206 + ///computes the distance between the specified point and this rectangle.
  207 + ///@param p: x, y, z coordinates of the point to calculate distance to.
168 CUDA_CALLABLE T dist(vec<T> p) 208 CUDA_CALLABLE T dist(vec<T> p)
169 { 209 {
170 //compute the distance between a point and this rect 210 //compute the distance between a point and this rect
171 211
172 - vec<T> A = C - X * (T)0.5 - Y * (T)0.5; 212 + vec<T> A = P - X * (T)0.5 - Y * (T)0.5;
173 213
174 - //first break the rect up into two triangles  
175 - triangle<T> T0(A, A+X, A+Y);  
176 - triangle<T> T1(A+X+Y, A+X, A+Y); 214 + //first break the rect up into two triangles
  215 + triangle<T> T0(A, A+X, A+Y);
  216 + triangle<T> T1(A+X+Y, A+X, A+Y);
177 217
178 218
179 - T d0 = T0.dist(p);  
180 - T d1 = T1.dist(p); 219 + T d0 = T0.dist(p);
  220 + T d1 = T1.dist(p);
181 221
182 - if(d0 < d1)  
183 - return d0;  
184 - else  
185 - return d1; 222 + if(d0 < d1)
  223 + return d0;
  224 + else
  225 + return d1;
  226 + }
  227 +
  228 + CUDA_CALLABLE T center(vec<T> p)
  229 + {
  230 + this->P = p;
186 } 231 }
187 232
  233 + ///Returns the maximum distance of the rectangle from a point p to the sides of the rectangle.
  234 + ///@param p: x, y, z point.
188 CUDA_CALLABLE T dist_max(vec<T> p) 235 CUDA_CALLABLE T dist_max(vec<T> p)
189 { 236 {
190 - vec<T> A = C - X * (T)0.5 - Y * (T)0.5;  
191 - T da = (A - p).len();  
192 - T db = (A+X - p).len();  
193 - T dc = (A+Y - p).len();  
194 - T dd = (A+X+Y - p).len(); 237 + vec<T> A = P - X * (T)0.5 - Y * (T)0.5;
  238 + T da = (A - p).len();
  239 + T db = (A+X - p).len();
  240 + T dc = (A+Y - p).len();
  241 + T dd = (A+X+Y - p).len();
195 242
196 - return std::max( da, std::max(db, std::max(dc, dd) ) ); 243 + return std::max( da, std::max(db, std::max(dc, dd) ) );
197 } 244 }
198 }; 245 };
199 246
stim/math/rect_old.h 0 → 100644
  1 +#ifndef RTS_RECT_H
  2 +#define RTS_RECT_H
  3 +
  4 +//enable CUDA_CALLABLE macro
  5 +#include <stim/cuda/cudatools/callable.h>
  6 +#include <stim/math/vector.h>
  7 +#include <stim/math/triangle.h>
  8 +#include <stim/math/quaternion.h>
  9 +#include <iostream>
  10 +#include <iomanip>
  11 +#include <algorithm>
  12 +
  13 +namespace stim{
  14 +
  15 +//template for a rectangle class in ND space
  16 +template <class T>
  17 +struct rect
  18 +{
  19 + /*
  20 + ^ O
  21 + |
  22 + |
  23 + Y C
  24 + |
  25 + |
  26 + O---------X--------->
  27 + */
  28 +
  29 +private:
  30 +
  31 + stim::vec<T> C;
  32 + stim::vec<T> X;
  33 + stim::vec<T> Y;
  34 +
  35 + CUDA_CALLABLE void scale(T factor){
  36 + X *= factor;
  37 + Y *= factor;
  38 + }
  39 +
  40 +
  41 +
  42 +public:
  43 +
  44 + ///base constructor.
  45 + CUDA_CALLABLE rect(){
  46 + init();
  47 + }
  48 +
  49 + ///create a rectangle given a size and position in Z space.
  50 + ///@param size: size of the rectangle in ND space.
  51 + ///@param z_pos z coordinate of the rectangle.
  52 + CUDA_CALLABLE rect(T size, T z_pos = (T)0){
  53 + init(); //use the default setup
  54 + scale(size); //scale the rectangle
  55 + C[2] = z_pos;
  56 + }
  57 +
  58 +
  59 + ///create a rectangle from a center point, normal
  60 + ///@param c: x,y,z location of the center.
  61 + ///@param n: x,y,z direction of the normal.
  62 + CUDA_CALLABLE rect(vec<T> c, vec<T> n = vec<T>(0, 0, 1)){
  63 + init(); //start with the default setting
  64 + C = c;
  65 + normal(n); //orient
  66 + }
  67 +
  68 + ///create a rectangle from a center point, normal, and size
  69 + ///@param c: x,y,z location of the center.
  70 + ///@param s: size of the rectangle.
  71 + ///@param n: x,y,z direction of the normal.
  72 + CUDA_CALLABLE rect(vec<T> c, T s, vec<T> n = vec<T>(0, 0, 1)){
  73 + init(); //start with the default setting
  74 + C = c;
  75 + scale(s);
  76 + normal(n); //orient
  77 + }
  78 +
  79 + ///creates a rectangle from a centerpoint and an X and Y direction vectors.
  80 + ///@param center: x,y,z location of the center.
  81 + ///@param directionX: u,v,w direction of the X vector.
  82 + ///@param directionY: u,v,w direction of the Y vector.
  83 + CUDA_CALLABLE rect(vec<T> center, vec<T> directionX, vec<T> directionY )
  84 + {
  85 + C = center;
  86 + X = directionX;
  87 + Y = directionY;
  88 + }
  89 +
  90 + ///creates a rectangle from a size, centerpoint, X, and Y direction vectors.
  91 + ///@param size of the rectangle in ND space.
  92 + ///@param center: x,y,z location of the center.
  93 + ///@param directionX: u,v,w direction of the X vector.
  94 + ///@param directionY: u,v,w direction of the Y vector.
  95 + CUDA_CALLABLE rect(T size, vec<T> center, vec<T> directionX, vec<T> directionY )
  96 + {
  97 + C = center;
  98 + X = directionX;
  99 + Y = directionY;
  100 + scale(size);
  101 + }
  102 +
  103 + ///creates a rectangle from a size, centerpoint, X, and Y direction vectors.
  104 + ///@param size of the rectangle in ND space, size[0] = size in X, size[1] = size in Y.
  105 + ///@param center: x,y,z location of the center.
  106 + ///@param directionX: u,v,w direction of the X vector.
  107 + ///@param directionY: u,v,w direction of the Y vector.
  108 + CUDA_CALLABLE rect(vec<T> size, vec<T> center, vec<T> directionX, vec<T> directionY )
  109 + {
  110 + C = center;
  111 + X = directionX;
  112 + Y = directionY;
  113 + scale(size[0], size[1]);
  114 + }
  115 +
  116 + ///scales a rectangle in ND space.
  117 + ///@param factor1: size of the scale in the X-direction.
  118 + ///@param factor2: size of the scale in the Y-direction.
  119 + CUDA_CALLABLE void scale(T factor1, T factor2){
  120 + X *= factor1;
  121 + Y *= factor2;
  122 + }
  123 +
  124 + ///@param n; vector with the normal.
  125 + ///Orients the rectangle along the normal n.
  126 + CUDA_CALLABLE void normal(vec<T> n){ //orient the rectangle along the specified normal
  127 +
  128 + n = n.norm(); //normalize, just in case
  129 + vec<T> n_current = X.cross(Y).norm(); //compute the current normal
  130 + quaternion<T> q; //create a quaternion
  131 + q.CreateRotation(n_current, n); //initialize a rotation from n_current to n
  132 +
  133 + //apply the quaternion to the vectors and position
  134 + X = q.toMatrix3() * X;
  135 + Y = q.toMatrix3() * Y;
  136 + }
  137 +
  138 + ///general init method that sets a general rectangle.
  139 + CUDA_CALLABLE void init(){
  140 + C = vec<T>(0, 0, 0);
  141 + X = vec<T>(1, 0, 0);
  142 + Y = vec<T>(0, 1, 0);
  143 + }
  144 +
  145 + //boolean comparison
  146 + bool operator==(const rect<T> & rhs)
  147 + {
  148 + if(C == rhs.C && X == rhs.X && Y == rhs.Y)
  149 + return true;
  150 + else
  151 + return false;
  152 + }
  153 +
  154 + /*******************************************
  155 + Return the normal for the rect
  156 + *******************************************/
  157 + CUDA_CALLABLE stim::vec<T> n()
  158 + {
  159 + return (X.cross(Y)).norm();
  160 + }
  161 +
  162 + //get the world space value given the planar coordinates a, b in [0, 1]
  163 + CUDA_CALLABLE stim::vec<T> p(T a, T b)
  164 + {
  165 + stim::vec<T> result;
  166 + //given the two parameters a, b = [0 1], returns the position in world space
  167 + vec<T> A = C - X * (T)0.5 - Y * (T)0.5;
  168 + result = A + X * a + Y * b;
  169 +
  170 + return result;
  171 + }
  172 +
  173 + //parenthesis operator returns the world space given rectangular coordinates a and b in [0 1]
  174 + CUDA_CALLABLE stim::vec<T> operator()(T a, T b)
  175 + {
  176 + return p(a, b);
  177 + }
  178 +
  179 + std::string str()
  180 + {
  181 + std::stringstream ss;
  182 + vec<T> A = C - X * (T)0.5 - Y * (T)0.5;
  183 + ss<<std::left<<"B="<<std::setfill('-')<<std::setw(20)<<A + Y<<">"<<"C="<<A + Y + X<<std::endl;
  184 + ss<<std::setfill(' ')<<std::setw(23)<<"|"<<"|"<<std::endl<<std::setw(23)<<"|"<<"|"<<std::endl;
  185 + ss<<std::left<<"A="<<std::setfill('-')<<std::setw(20)<<A<<">"<<"D="<<A + X;
  186 +
  187 + return ss.str();
  188 +
  189 + }
  190 +
  191 + ///multiplication operator scales the rectangle by a value rhs.
  192 + CUDA_CALLABLE rect<T> operator*(T rhs)
  193 + {
  194 + //scales the plane by a scalar value
  195 +
  196 + //create the new rectangle
  197 + rect<T> result = *this;
  198 + result.scale(rhs);
  199 +
  200 + return result;
  201 +
  202 + }
  203 +
  204 + ///computes the distance between the specified point and this rectangle.
  205 + ///@param p: x, y, z coordinates of the point to calculate distance to.
  206 + CUDA_CALLABLE T dist(vec<T> p)
  207 + {
  208 + //compute the distance between a point and this rect
  209 +
  210 + vec<T> A = C - X * (T)0.5 - Y * (T)0.5;
  211 +
  212 + //first break the rect up into two triangles
  213 + triangle<T> T0(A, A+X, A+Y);
  214 + triangle<T> T1(A+X+Y, A+X, A+Y);
  215 +
  216 +
  217 + T d0 = T0.dist(p);
  218 + T d1 = T1.dist(p);
  219 +
  220 + if(d0 < d1)
  221 + return d0;
  222 + else
  223 + return d1;
  224 + }
  225 +
  226 + CUDA_CALLABLE T center(vec<T> p)
  227 + {
  228 + C = p;
  229 + }
  230 +
  231 + ///Returns the maximum distance of the rectangle from a point p to the sides of the rectangle.
  232 + ///@param p: x, y, z point.
  233 + CUDA_CALLABLE T dist_max(vec<T> p)
  234 + {
  235 + vec<T> A = C - X * (T)0.5 - Y * (T)0.5;
  236 + T da = (A - p).len();
  237 + T db = (A+X - p).len();
  238 + T dc = (A+Y - p).len();
  239 + T dd = (A+X+Y - p).len();
  240 +
  241 + return std::max( da, std::max(db, std::max(dc, dd) ) );
  242 + }
  243 +};
  244 +
  245 +} //end namespace rts
  246 +
  247 +template <typename T, int N>
  248 +std::ostream& operator<<(std::ostream& os, stim::rect<T> R)
  249 +{
  250 + os<<R.str();
  251 + return os;
  252 +}
  253 +
  254 +
  255 +#endif
stim/math/vector.h
@@ -71,8 +71,9 @@ struct vec : public std::vector&lt;T&gt; @@ -71,8 +71,9 @@ struct vec : public std::vector&lt;T&gt;
71 vec( const vec<T>& other){ 71 vec( const vec<T>& other){
72 unsigned int N = other.size(); 72 unsigned int N = other.size();
73 resize(N); //resize the current vector to match the copy 73 resize(N); //resize the current vector to match the copy
74 - for(unsigned int i=0; i<N; i++) //copy each element  
75 - at(i) = other[i]; 74 + for(unsigned int i=0; i<N; i++){ //copy each element
  75 + at(i) = other[i];
  76 + }
76 } 77 }
77 78
78 //I'm not sure what these were doing here. 79 //I'm not sure what these were doing here.
stim/visualization/cylinder.h 0 → 100644
  1 +#ifndef STIM_CYLINDER_H
  2 +#define STIM_CYLINDER_H
  3 +#include <iostream>
  4 +#include <stim/math/circle.h>
  5 +#include <stim/math/vector.h>
  6 +
  7 +
  8 +namespace stim
  9 +{
  10 +template<typename T>
  11 +class cylinder
  12 +{
  13 + private:
  14 + stim::circle<T> s;
  15 + std::vector< stim::vec<T> > pos;
  16 + std::vector< stim::vec<T> > mags;
  17 + std::vector< T > L;
  18 +
  19 + void
  20 + init()
  21 + {
  22 +
  23 + }
  24 +
  25 + void
  26 + init(std::vector<stim::vec<T> > inP, std::vector<stim::vec<T> > inM)
  27 + {
  28 + pos = inP;
  29 + mags = inM;
  30 + L.resize(pos.size()-1);
  31 + T temp = (T)0;
  32 + for(int i = 0; i < L.size()-1; i++)
  33 + {
  34 + temp += (pos[i] - pos[i+1]).len();
  35 + L[i] = temp;
  36 + }
  37 + }
  38 +
  39 + stim::vec<T>
  40 + d(int idx)
  41 + {
  42 + return (pos[idx] - pos[idx+1]).norm();
  43 +
  44 + }
  45 +
  46 + T
  47 + getl(int j)
  48 + {
  49 + for(int i = 0; i < j-1; ++i)
  50 + {
  51 + temp += (pos[i] - pos[i+1]).len();
  52 + L[i] = temp;
  53 + }
  54 + }
  55 +
  56 + int
  57 + findIdx(T l)
  58 + {
  59 + int i = pos.size()/2;
  60 + while(i > 0 && i < pos.size())
  61 + {
  62 + if(L[i] < l)
  63 + {
  64 + i = i/2;
  65 + }
  66 + else if(L[i] < l && L[i+1] > l)
  67 + {
  68 + break;
  69 + }
  70 + else
  71 + {
  72 + i = i+i/2;
  73 + }
  74 + }
  75 + return i;
  76 + }
  77 +
  78 + public:
  79 + cylinder()
  80 + {
  81 +
  82 + }
  83 +
  84 + ///constructor to create a cylinder from a set of points, radii, and the number of sides for the cylinder.
  85 + ///The higher the number of sides, the more rectangeles compose the surface of the cylinder.
  86 + ///@param inP: Vector of stim vecs composing the points of the centerline.
  87 + ///@param inM: Vector of stim vecs composing the radii of the centerline.
  88 + cylinder(std::vector<stim::vec<T> > inP, std::vector<stim::vec<T> > inM)
  89 + {
  90 + init(inP, inM);
  91 + }
  92 +
  93 +
  94 + ///Returns a position vector at the given p-value (p value ranges from 0 to 1).
  95 + stim::vec<T>
  96 + p(T pvalue)
  97 + {
  98 + if(pvalue < 0.0 || pvalue > 1.0)
  99 + return;
  100 + T l = pvalue*L[L.size()-1];
  101 + int idx = findIdx(l);
  102 + return (pos[idx] + (pos[idx+1]-pos[idx])*((l-L[idx])/(L[idx+1]- L[idx])));
  103 + }
  104 +
  105 + stim::vec<T>
  106 + p(T l, int idx)
  107 + {
  108 + return (pos[idx] + (pos[idx+1]-pos[idx])*((l-L[idx])/(L[idx+1]- L[idx])));
  109 + }
  110 +
  111 + ///Returns a radius at the given p-value (p value ranges from 0 to 1).
  112 + T
  113 + r(T pvalue)
  114 + {
  115 + if(pvalue < 0.0 || pvalue > 1.0)
  116 + return;
  117 + T l = pvalue*L[L.size()-1];
  118 + int idx = findIdx(l);
  119 + return (mags[idx] + (mags[idx+1]-mags[idx])*((l-L[idx])/(L[idx+1]- L[idx])));
  120 + }
  121 +
  122 + T
  123 + r(T l, int idx)
  124 + {
  125 + return (mags[idx] + (mags[idx+1]-mags[idx])*((l-L[idx])/(L[idx+1]- L[idx])));
  126 + }
  127 +
  128 +
  129 + ///returns the position of the point with a given pvalue and theta on the surface
  130 + ///in x, y, z coordinates. Theta is in degrees from 0 to 360
  131 + stim::vec<T>
  132 + surf(T pvalue, T theta)
  133 + {
  134 + if(pvalue < 0.0 || pvalue > 1.0)
  135 + return;
  136 + T l = pvalue*L[L.size()-1];
  137 + int idx = findIdx(l);
  138 + stim::vec<T> ps = p(l, idx);
  139 + T m = r(l, idx);
  140 + stim::vec<T> dr = d(idx);
  141 + s = stim::circle<T>(ps, m, dr);
  142 + return(s.p(theta));
  143 + }
  144 +
  145 + std::vector<std::vector<vec<T> > >
  146 + getPoints(int sides)
  147 + {
  148 + if(pos.size() < 2)
  149 + {
  150 + return;
  151 + } else {
  152 + std::vector<std::vector <vec<T> > > points;
  153 + points.resize(pos.size());
  154 + stim::vec<T> d = (pos[0] - pos[1]).norm();
  155 + s = stim::circle<T>(pos[0], mags[0][0], d);
  156 + points[0] = s.getPoints(sides);
  157 + for(int i = 1; i < pos.size(); i++)
  158 + {
  159 + d = (pos[i] - pos[i-1]).norm();
  160 + s.center(pos[i]);
  161 + s.normal(d);
  162 + s.scale(mags[i][0]/mags[i-1][0], mags[i][0]/mags[i-1][0]);
  163 + points[i] = s.getPoints(sides);
  164 + }
  165 + return points;
  166 + }
  167 + }
  168 +
  169 +};
  170 +
  171 +}
  172 +#endif
stim/visualization/glObj.h
@@ -29,6 +29,8 @@ private: @@ -29,6 +29,8 @@ private:
29 void 29 void
30 init() 30 init()
31 { 31 {
  32 + if(glIsList(dList))
  33 + glDeleteLists(dList, 1);
32 dList = glGenLists(1); 34 dList = glGenLists(1);
33 glListBase(dList); 35 glListBase(dList);
34 36
@@ -40,16 +42,25 @@ private: @@ -40,16 +42,25 @@ private:
40 } 42 }
41 43
42 void 44 void
43 - Create() 45 + Create(GLenum mode)
44 { 46 {
  47 +// GLuint selectBuf[2048];
  48 +// GLint hits;
  49 +// glSelectBuffer(2048, selectBuf);
  50 +
45 int len = (int) stim::obj<T>::numL(); 51 int len = (int) stim::obj<T>::numL();
46 std::vector< stim::vec<float> > line; 52 std::vector< stim::vec<float> > line;
47 glNewList(dList, GL_COMPILE); 53 glNewList(dList, GL_COMPILE);
48 // glColor3f(0.0, 1.0, 0.0); 54 // glColor3f(0.0, 1.0, 0.0);
49 - glLineWidth(2.5); 55 + glLineWidth(3.5);
50 for(int i = 0; i < len; i++){ 56 for(int i = 0; i < len; i++){
51 line = stim::obj<T>::getL_V(i); 57 line = stim::obj<T>::getL_V(i);
52 - glColor3ub(rand()%255, rand()%255, rand()%255); 58 + if(mode == GL_SELECT)
  59 + {
  60 + glLoadName(i);
  61 + }
  62 + glColor3f(0.0, 1.0, 0.05);
  63 + //glColor3ub(rand()%255, rand()%255, rand()%255);
53 glBegin(GL_LINE_STRIP); 64 glBegin(GL_LINE_STRIP);
54 for(int j = 0; j < line.size(); j++){ 65 for(int j = 0; j < line.size(); j++){
55 glVertex3f( 66 glVertex3f(
@@ -71,21 +82,21 @@ public: @@ -71,21 +82,21 @@ public:
71 } 82 }
72 83
73 void 84 void
74 - createFromSelf() 85 + createFromSelf(GLenum mode = GL_RENDER)
75 { 86 {
76 // glPopMatrix(); 87 // glPopMatrix();
77 init(); 88 init();
78 - Create(); 89 + Create(mode);
79 // glPushMatrix(); 90 // glPushMatrix();
80 } 91 }
81 92
82 void 93 void
83 - createFromFile(std::string filename) 94 + createFromFile(std::string filename, GLenum mode = GL_RENDER)
84 { 95 {
85 stim::obj<T>::load(filename); 96 stim::obj<T>::load(filename);
86 glPushMatrix(); //Safety Operation to avoid changing the current matrix. 97 glPushMatrix(); //Safety Operation to avoid changing the current matrix.
87 init(); 98 init();
88 - Create(); 99 + Create(mode);
89 glPopMatrix(); 100 glPopMatrix();
90 CHECK_OPENGL_ERROR 101 CHECK_OPENGL_ERROR
91 } 102 }
stim/visualization/glnetwork.h 0 → 100644
  1 +#ifndef STIM_GLNETWORK_H
  2 +#define STIM_GLNETWORK_H
  3 +
  4 +#include <GL/glew.h>
  5 +#include <GL/glut.h>
  6 +#include "network.h"
  7 +#include <stim/visualization/cylinder.h>
  8 +#include <stim/math/vector.h>
  9 +#include <list>
  10 +#include <ANN/ANN.h>
  11 +#include "fiber.h"
  12 +
  13 +
  14 +namespace stim
  15 +{
  16 +template <typename T>
  17 +class glnetwork : public virtual network<T>
  18 +{
  19 +private:
  20 + using stim::network<T>::E;
  21 +
  22 + GLuint dList; ///displaylist for the lines.
  23 + GLuint cList; ///displaylist for the cylinders.
  24 +
  25 + void init()
  26 + {
  27 + ///clear lists if there is data in them.
  28 + ///adding points may create errors or uncessary duplicate points.
  29 + if(glIsList(dList))
  30 + glDeleteLists(dList, 1);
  31 + if(glIsList(cList))
  32 + glDeleteLists(cList, 1);
  33 + dList = glGenLists(1); ///create the lists
  34 + cList = glGenLists(1);
  35 +
  36 + ///set up the Line list.
  37 + glListBase(dList);
  38 + glMatrixMode(GL_PROJECTION);
  39 + glLoadIdentity;
  40 + glMatrixMode(GL_MODELVIEW);
  41 + glLoadIdentity;
  42 +
  43 + ///set up the cylinder List.
  44 + glListBase(cList);
  45 + glMatrixMode(GL_PROJECTION);
  46 + glLoadIdentity;
  47 + glMatrixMode(GL_MODELVIEW);
  48 + glLoadIdentity;
  49 + }
  50 +
  51 + void
  52 + Create(GLenum mode, int sides = 8)
  53 + {
  54 + glListBase(dList);
  55 + glNewList(dList, GL_COMPILE);
  56 + glLineWidth(3.5);
  57 + for(int i = 0; i < E.size(); i++)
  58 + {
  59 + if(mode == GL_SELECT)
  60 + {
  61 +// glLineWidth(3.5);
  62 + glLoadName(i);
  63 + }
  64 + else{
  65 +// glLineWidth(1.0+1.0*i);
  66 + }
  67 + glColor3f(0.0, 1.0-0.05*i, i*0.05);
  68 + std::vector<stim::vec<T> > line = getEdgeCenterLine(i);
  69 + glBegin(GL_LINE_STRIP);
  70 + for(int j = 0; j < line.size(); j++)
  71 + {
  72 + glVertex3f(line[j][0],
  73 + line[j][1],
  74 + line[j][2]);
  75 + }
  76 + glEnd();
  77 + }
  78 + glEndList();
  79 +
  80 + glListBase(cList);
  81 + glNewList(cList, GL_COMPILE);
  82 +
  83 + for(int i = 0; i < E.size(); i++)
  84 + {
  85 + if(mode == GL_SELECT)
  86 + {
  87 + glLoadName(i);
  88 + }
  89 + glColor3f(1.0, 1.0, 0.0);
  90 + std::vector<stim::vec<T> > line = getEdgeCenterLine(i);
  91 + std::vector<stim::vec<T> > linemag = getEdgeCenterLineMag(i);
  92 + stim::cylinder<T> cyl(line, linemag);
  93 + std::vector<std::vector<stim::vec<T > > > p = cyl.getPoints(sides);
  94 + for(int i = 0; i < p.size()-1; i++)
  95 + {
  96 + for(int j = 0; j < p[0].size()-1; j++)
  97 + {
  98 + glColor4f(1.0, 1.0, 0.0, 0.5);
  99 + glEnable(GL_BLEND);
  100 + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  101 + glBegin(GL_QUADS);
  102 + glVertex3f(p[i][j][0], p[i][j][1], p[i][j][2]);
  103 + glVertex3f(p[i][j+1][0], p[i][j+1][1], p[i][j+1][2]);
  104 + glVertex3f(p[i+1][j+1][0], p[i+1][j+1][1], p[i+1][j+1][2] );
  105 + glVertex3f(p[i+1][j][0], p[i+1][j][1], p[i+1][j][2]);
  106 + glEnd();
  107 + glDisable(GL_BLEND);
  108 +
  109 + glColor4f(1.0, 0.0, 1.0, 1.0);
  110 + glLineWidth(2.0);
  111 + glBegin(GL_LINES);
  112 + glVertex3f(p[i][j][0], p[i][j][1], p[i][j][2]);
  113 + glVertex3f(p[i][j+1][0], p[i][j+1][1], p[i][j+1][2]);
  114 + glVertex3f(p[i][j][0], p[i][j][1], p[i][j][2]);
  115 + glVertex3f(p[i+1][j][0], p[i+1][j][1], p[i+1][j][2] );
  116 + glEnd();
  117 + }
  118 +
  119 + }
  120 +
  121 +
  122 +
  123 + }
  124 + glEndList();
  125 +// CHECK_OPENGL_ERROR
  126 + }
  127 +
  128 +public:
  129 + using stim::network<T>::sizeE;
  130 + using stim::network<T>::getEdgeCenterLine;
  131 + using stim::network<T>::getEdgeCenterLineMag;
  132 + glnetwork()
  133 + {
  134 +
  135 + }
  136 +
  137 + void
  138 + createFromSelf(GLenum mode = GL_RENDER, int sides = 8)
  139 + {
  140 + init();
  141 + Create(mode, sides);
  142 + }
  143 +
  144 + void
  145 + Render()
  146 + {
  147 + glCallList(dList);
  148 +// CHECK_OPENGL_ERROR
  149 + }
  150 +
  151 + void
  152 + RenderCylinders()
  153 + {
  154 + glCallList(cList);
  155 +// CHECK_OPENGL_ERROR
  156 + }
  157 +
  158 + void
  159 + RenderLine(std::vector<stim::vec<T> > l)
  160 + {
  161 + glColor3f(0.5, 1.0, 0.5);
  162 + glLineWidth(3.0);
  163 + glBegin(GL_LINE_STRIP);
  164 + for(int j = 0; j < l.size(); j++){
  165 + glVertex3f(
  166 + l[j][0],
  167 + l[j][1],
  168 + l[j][2]
  169 + );
  170 + }
  171 + glEnd();
  172 + }
  173 +
  174 +};
  175 +}
  176 +
  177 +#endif
stim/visualization/obj.h
@@ -683,14 +683,14 @@ public: @@ -683,14 +683,14 @@ public:
683 l.resize(nP); 683 l.resize(nP);
684 684
685 //copy the points from the point list to the stim vector 685 //copy the points from the point list to the stim vector
686 - unsigned int pi; 686 + unsigned int pie;
687 for(unsigned int p = 0; p < nP; p++){ 687 for(unsigned int p = 0; p < nP; p++){
688 688
689 //get the index of the geometry point 689 //get the index of the geometry point
690 - pi = L[i][p][0] - 1; 690 + pie = L[i][p][0] - 1;
691 691
692 //get the coordinates of the current point 692 //get the coordinates of the current point
693 - stim::vec<T> newP = V[pi]; 693 + stim::vec<T> newP = V[pie];
694 694
695 //copy the point into the vector 695 //copy the point into the vector
696 l[p] = newP; 696 l[p] = newP;
@@ -737,14 +737,14 @@ public: @@ -737,14 +737,14 @@ public:
737 l.resize(nP); 737 l.resize(nP);
738 738
739 //copy the points from the point list to the stim vector 739 //copy the points from the point list to the stim vector
740 - unsigned int pi; 740 + unsigned int pie;
741 for(unsigned int p = 0; p < nP; p++){ 741 for(unsigned int p = 0; p < nP; p++){
742 742
743 //get the index of the geometry point 743 //get the index of the geometry point
744 - pi = L[i][p][1] - 1; 744 + pie = L[i][p][1] - 1;
745 745
746 //get the coordinates of the current point 746 //get the coordinates of the current point
747 - stim::vec<T> newP = VT[pi]; 747 + stim::vec<T> newP = VT[pie];
748 748
749 //copy the point into the vector 749 //copy the point into the vector
750 l[p] = newP; 750 l[p] = newP;