Commit 88088186b35fbdc00bb2b844c351a647b922ea6c

Authored by David Mayerich
2 parents 5bccf89d bf23ee36

Merge branch 'Glnetwork'

stim/cuda/arraymath/array_cart2polar.cuh
... ... @@ -4,7 +4,7 @@
4 4 namespace stim{
5 5 namespace cuda{
6 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 10 // calculate the 2D coordinates for this current thread.
... ... @@ -20,21 +20,21 @@ namespace stim{
20 20 float yl = a[i * 2 + 1];
21 21 float theta = atan2( yl, xl ) ;
22 22 float r = sqrt(xl * xl + yl * yl);
23   - a[i * 2 + 0] = theta;
  23 + a[i * 2 + 0] = theta + rotation;
24 24 a[i * 2 + 1] = r;
25 25  
26 26 }
27 27  
28 28  
29 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 32 unsigned int max_threads = stim::maxThreadsPerBlock();
33 33 dim3 threads(max_threads, 1);
34 34 dim3 blocks(x/threads.x + (x %threads.x == 0 ? 0:1) , y);
35 35  
36 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 67 }
68 68 }
69 69  
70   -#endif
71 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 4 #include <cuda.h>
5 5  
6 6 namespace stim{
7   -
  7 +extern "C"
8 8 int maxThreadsPerBlock()
9 9 {
10 10 int device;
... ... @@ -14,6 +14,7 @@ int maxThreadsPerBlock()
14 14 return props.maxThreadsPerBlock;
15 15 }
16 16  
  17 +extern "C"
17 18 int sharedMemPerBlock()
18 19 {
19 20 int device;
... ...
stim/cuda/ivote/update_dir.cuh
... ... @@ -164,6 +164,9 @@ namespace stim{
164 164 //free allocated memory
165 165 cudaFree(gpuDir);
166 166  
  167 + cudaDestroyTextureObject(texObj);
  168 + cudaFreeArray(cuArray);
  169 +
167 170 }
168 171  
169 172 template<typename T>
... ... @@ -211,4 +214,4 @@ namespace stim{
211 214 }
212 215 }
213 216  
214   -#endif
215 217 \ No newline at end of file
  218 +#endif
... ...
stim/cuda/ivote/vote.cuh
... ... @@ -124,6 +124,9 @@ namespace stim{
124 124  
125 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 172 }
170 173 }
171 174  
172   -#endif
173 175 \ No newline at end of file
  176 +#endif
... ...
stim/cuda/sharedmem.cuh
... ... @@ -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 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 102 dim3 blocks(w / threads + 1, h);
103 103  
104 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 111 template<typename T>
... ... @@ -139,4 +141,4 @@ namespace stim{
139 141 }
140 142  
141 143  
142   -#endif
143 144 \ No newline at end of file
  145 +#endif
... ...
stim/cuda/templates/conv2sep.cuh
... ... @@ -30,7 +30,7 @@ namespace stim{
30 30 int byi = blockIdx.y;
31 31  
32 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 35 //calculate the thread index
36 36 int ti = threadIdx.x;
... ... @@ -88,7 +88,7 @@ namespace stim{
88 88 int byi = blockIdx.y * blockDim.y;
89 89  
90 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 93 //calculate the thread index
94 94 int ti = threadIdx.y;
... ... @@ -213,6 +213,8 @@ namespace stim{
213 213 //free allocated memory
214 214 cudaFree(cuArray);
215 215  
  216 + cudaDestroyTextureObject(texObj);
  217 +
216 218 }
217 219  
218 220 /// Applies a Gaussian blur to a 2D image stored on the CPU
... ... @@ -257,4 +259,4 @@ namespace stim{
257 259 };
258 260 };
259 261  
260   -#endif
261 262 \ No newline at end of file
  263 +#endif
... ...
stim/cuda/templates/gaussian_blur.cuh
... ... @@ -7,7 +7,6 @@
7 7 #include <stim/cuda/sharedmem.cuh>
8 8 #include <stim/cuda/templates/conv2sep.cuh> //GPU-based separable convolution algorithm
9 9  
10   -#define pi 3.14159
11 10  
12 11 namespace stim{
13 12 namespace cuda{
... ... @@ -37,12 +36,14 @@ namespace stim{
37 36  
38 37 //copy the kernel to the GPU
39 38 T* gpuKernel0;
  39 + HANDLE_ERROR(cudaMalloc(&gpuKernel0, kwidth*sizeof(T)));
40 40 HANDLE_ERROR(cudaMemcpy(gpuKernel0, kernel0, kwidth * sizeof(T), cudaMemcpyHostToDevice));
41 41  
42 42 //perform the gaussian blur as a separable convolution
43 43 stim::cuda::tex_conv2sep(out, x, y, texObj, cuArray, gpuKernel0, kwidth, gpuKernel0, kwidth);
44 44  
45 45 HANDLE_ERROR(cudaFree(gpuKernel0));
  46 + free(kernel0);
46 47  
47 48 }
48 49  
... ... @@ -58,7 +59,7 @@ namespace stim{
58 59  
59 60 //copy the kernel to the GPU
60 61 T* gpuKernel0;
61   - HANDLE_ERROR(cudaMalloc(&gpuKernel0, kwidth * sizeof(T)));
  62 + HANDLE_ERROR(cudaMalloc(&gpuKernel0, kwidth*sizeof(T)));
62 63 HANDLE_ERROR(cudaMemcpy(gpuKernel0, kernel0, kwidth * sizeof(T), cudaMemcpyHostToDevice));
63 64  
64 65 //perform the gaussian blur as a separable convolution
... ... @@ -87,4 +88,4 @@ namespace stim{
87 88 };
88 89 };
89 90  
90   -#endif
91 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 13 #include "stim/math/vector.h"
14 14 #include "stim/math/rect.h"
15 15 #include "stim/math/matrix.h"
16   -#include "stim/cuda/cost.h"
  16 +#include "stim/cuda/spider_cost.cuh"
17 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 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 30 #include <iostream>
22 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 39 namespace stim
30 40 {
31 41  
32 42 template<typename T>
33   -class gl_spider
  43 +class gl_spider : public virtual gl_texture<T>
34 44 {
35 45 //doen't use gl_texture really, just needs the GLuint id.
36 46 //doesn't even need the texture iD really.
37 47 private:
  48 +
  49 + //
38 50 stim::vec<float> p; //vector designating the position of the spider.
39 51 stim::vec<float> d; //vector designating the orientation of the spider
40 52 //always a unit vector.
41 53 stim::vec<float> m; //magnitude of the spider vector.
42 54 //mag[0] = length.
43 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 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 112 /// Method for finding the best scale for the spider.
62 113 /// changes the x, y, z size of the spider to minimize the cost
... ... @@ -64,42 +115,43 @@ class gl_spider
64 115 void
65 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 122 dV[best][0]*S[0]*R[0],
72 123 dV[best][1]*S[1]*R[1],
73 124 dV[best][2]*S[2]*R[2],
74 125 0);
75   - next = (cT*next).norm();
76   - //next = (cT*next);
  126 + next = (cT*next).norm(); //find next vector.
77 127 setPosition( p[0]+next[0]*m[0]/stepsize,
78 128 p[1]+next[1]*m[0]/stepsize,
79 129 p[2]+next[2]*m[0]/stepsize);
80 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 136 /// will be at d * m.
86 137 void
87 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 150 setPosition(
99 151 next[0]*S[0]*R[0],
100 152 next[1]*S[1]*R[1],
101 153 next[2]*S[2]*R[2]
102   - );
  154 + ); //adjust position.
103 155 }
104 156  
105 157 /// Method for finding the best scale for the spider.
... ... @@ -108,33 +160,64 @@ class gl_spider
108 160 void
109 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 172 void
118 173 branchDetection()
119 174 {
120   - Bind();
121 175 setMatrix();
122 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 223 //---------------------TEMPLATE CREATION METHODS----------------------------//
... ... @@ -142,14 +225,15 @@ class gl_spider
142 225  
143 226 ///@param solidAngle, the size of the arc to sample.
144 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 231 ///uses the default d vector <0,0,1>
146 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 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 237 vec<float> pos(0.0,0.0,0.0);
154 238 vec<float> mag(1.0, 1.0, 1.0);
155 239 vec<float> dir(0.0, 0.0, 1.0);
... ... @@ -158,12 +242,12 @@ class gl_spider
158 242 vec<float> d_s = d.cart2sph().norm();
159 243 vec<float> temp(0,0,0);
160 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 251 int idx = 0;
168 252 for(int i = -dim; i <= dim; i++){
169 253 for(int j = -dim; j <= dim; j++){
... ... @@ -192,28 +276,30 @@ class gl_spider
192 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 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 284 ///uses the default vector <0,0,0>
198 285 void
199 286 genPositionVectors(float delta = 0.4)
200 287 {
201 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 290 vec<float> pos(0.0,0.0,0.0);
204 291 vec<float> mag(1.0, 1.0, 1.0);
205 292 vec<float> dir(0.0, 0.0, 1.0);
206 293  
207 294 //Set up the variable necessary for vector creation.
208 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 298 stim::rect<float>(p, d);
212 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 303 int idx;
218 304 glNewList(dList+1, GL_COMPILE);
219 305 for(int i = -dim; i <= dim; i++){
... ... @@ -240,30 +326,32 @@ class gl_spider
240 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 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 334 ///uses the default m <1,1,0>
246 335 void
247 336 genMagnitudeVectors(float delta = 0.70)
248   -// genMagnitudeVectors(float delta = 0.50)
249 337 {
250 338  
251 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 341 vec<float> pos(0.0,0.0,0.0);
254 342 vec<float> mag(1.0, 1.0, 1.0);
255 343 vec<float> dir(0.0, 0.0, 1.0);
256 344  
257 345 //Set up the variable necessary for vector creation.
258   - int dim = (sqrt(numSamples)-1)/2;
  346 + int dim = (sqrt(numSamplesMag)-1)/2;
259 347 float min = 1.0-delta;
260 348 float max = 1.0+delta;
261   - float step = (max-min)/(numSamples-1);
  349 + float step = (max-min)/(numSamplesMag-1);
262 350 float factor;
263 351 vec<float> temp(0.0,0.0,0.0);
264 352  
265 353 glNewList(dList+2, GL_COMPILE);
266   - for(int i = 0; i < numSamples; i++){
  354 + for(int i = 0; i < numSamplesMag; i++){
267 355 //Create linear index
268 356 factor = (min+step*i)*mag[0];
269 357 temp = factor;
... ... @@ -280,10 +368,11 @@ class gl_spider
280 368 }
281 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 376 void
288 377 UpdateBuffer(float v_x, float v_y)
289 378 {
... ... @@ -361,8 +450,37 @@ class gl_spider
361 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 484 ///Function for setting up the 2D buffer that stores the samples.
367 485 void
368 486 GenerateFBO(unsigned int width, unsigned int height)
... ... @@ -373,6 +491,8 @@ class gl_spider
373 491 unsigned char* texels = new unsigned char[width * height * numChannels];
374 492 glGenTextures(1, &texbufferID);
375 493 glBindTexture(GL_TEXTURE_2D, texbufferID);
  494 +
  495 + //Textures repeat and use linear interpolation, luminance format.
376 496 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
377 497 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
378 498 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
... ... @@ -382,39 +502,150 @@ class gl_spider
382 502 delete[] texels;
383 503 glBindFramebuffer(GL_FRAMEBUFFER, 0);
384 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 510 ///Template space (-0.5 0.5) to Texture space (0.0, 1.0),
390 511 ///Based on the p of the spider in real space (arbitrary).
  512 + ///All transformation happen in glMatrixMode(GL_TEXTURE).
391 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 517 glMatrixMode(GL_TEXTURE);
396 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 523 glTranslatef(p[0],
401 524 p[1],
402 525 p[2]);
403   -
  526 + //rotate to the current direction of the spider.
404 527 glRotatef(rot[0], rot[1], rot[2], rot[3]);
405   -
  528 + //scale to the magnitude of the spider.
406 529 glScalef(m[0],
407 530 m[0],
408 531 m[0]);
409   -
  532 + //get and store the current transformation matrix for later use.
410 533 glGetFloatv(GL_TEXTURE_MATRIX, curTrans);
411 534 cT.set(curTrans);
412   -// printTransform();
  535 + // printTransform();
413 536  
414 537 CHECK_OPENGL_ERROR
  538 + //revert back to default gl mode.
415 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 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 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 692 current_cost = cost[1];
460 693 return cost[0];
461 694 }
462 695  
463 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 709 stim::rect<float> hor;
  710 + //vectical rectangle forming the spider.
465 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 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 729 ///Default Constructor
475 730 gl_spider
476   - (int samples = 1089)
  731 + (int samples = 1089, int samplespos = 441,int samplesmag = 144)
477 732 {
478 733 p = vec<float>(0.0, 0.0, 0.0);
479 734 d = vec<float>(0.0, 0.0, 1.0);
480 735 m = vec<float>(1.0, 1.0);
481 736 S = vec<float>(1.0, 1.0, 1.0);
482 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 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 752 gl_spider
491 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 756 p = vec<float>(pos_x, pos_y, pos_z);
495 757 d = vec<float>(dir_x, dir_y, dir_z);
496 758 m = vec<float>(mag_x, mag_x, mag_x);
497 759 S = vec<float>(1.0,1.0,1.0);
498 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 785 ~gl_spider
506 786 (void)
507 787 {
508 788 Unbind();
509 789 glDeleteTextures(1, &texbufferID);
510 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 800 ///Attached the spider to the texture with the given GLuint ID.
515 801 ///Samples in the default d acting as the init method.
516 802 ///Also acts an init.
... ... @@ -518,16 +804,26 @@ class gl_spider
518 804 attachSpider(GLuint id)
519 805 {
520 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 812 setDims(0.6, 0.6, 1.0);
523 813 setSize(512.0, 512.0, 426.0);
524 814 setMatrix();
525 815 dList = glGenLists(3);
526 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 827 DrawCylinder();
532 828 Unbind();
533 829 }
... ... @@ -556,7 +852,7 @@ class gl_spider
556 852 return m;
557 853 }
558 854  
559   - ///@param vector pos, the new p.
  855 + ///@param stim::vec<float> pos, the new p.
560 856 ///Sets the p vector to input vector pos.
561 857 void
562 858 setPosition(vec<float> pos)
... ... @@ -564,9 +860,9 @@ class gl_spider
564 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 866 ///Sets the p vector to the input float coordinates x,y,z.
571 867 void
572 868 setPosition(float x, float y, float z)
... ... @@ -576,7 +872,7 @@ class gl_spider
576 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 876 ///Sets the d vector to input vector dir.
581 877 void
582 878 setDirection(vec<float> dir)
... ... @@ -584,9 +880,9 @@ class gl_spider
584 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 886 ///Sets the d vector to the input float coordinates x,y,z.
591 887 void
592 888 setDirection(float x, float y, float z)
... ... @@ -596,7 +892,7 @@ class gl_spider
596 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 896 ///Sets the m vector to the input vector mag.
601 897 void
602 898 setMagnitude(vec<float> mag)
... ... @@ -605,17 +901,19 @@ class gl_spider
605 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 905 ///Sets the m vector to the input mag for both templates.
610 906 void
611 907 setMagnitude(float mag)
612 908 {
613 909 m[0] = mag;
614 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 917 void
620 918 setDims(float x, float y, float z)
621 919 {
... ... @@ -624,6 +922,18 @@ class gl_spider
624 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 937 void
628 938 setSize(float x, float y, float z)
629 939 {
... ... @@ -631,10 +941,19 @@ class gl_spider
631 941 R[1] = y;
632 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 957 stim::vec<float>
639 958 getRotation(stim::vec<float> dir)
640 959 {
... ... @@ -655,56 +974,156 @@ class gl_spider
655 974 }
656 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 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 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 1128 //-----------------------------TEMPORARY METHODS----------------------------//
710 1129 //--------------------------------------------------------------------------//
... ... @@ -726,12 +1145,26 @@ class gl_spider
726 1145 int
727 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 1168 return current_cost;
736 1169 }
737 1170  
... ... @@ -742,16 +1175,6 @@ class gl_spider
742 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 1180 //-----------------------------EXPERIMENTAL METHODS-------------------------//
... ... @@ -760,36 +1183,410 @@ class gl_spider
760 1183 void
761 1184 DrawCylinder()
762 1185 {
763   - Bind();
764 1186 glNewList(dList+3, GL_COMPILE);
765 1187 float z0 = -0.5; float z1 = 0.5; float r0 = 0.5;
766 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 1192 glEnable(GL_TEXTURE_3D);
771 1193 glBindTexture(GL_TEXTURE_3D, texID);
772 1194 glBegin(GL_QUAD_STRIP);
  1195 + int j = 0;
773 1196 for(float i = step; i <= 360.0; i += step)
774 1197 {
775 1198 x=r0*cos(i*2.0*M_PI/360.0);
776 1199 y=r0*sin(i*2.0*M_PI/360.0);
777 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 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 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 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 1212 xold=x;
786 1213 yold=y;
787 1214 j++;
788 1215 }
789 1216 glEnd();
790 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 1592 #endif
... ...
stim/gl/gl_texture.h
... ... @@ -31,10 +31,9 @@ template&lt;typename T&gt;
31 31 class gl_texture : public virtual image_stack<T>
32 32 {
33 33 private:
34   - ///Method: setTextureType
35 34 /// Sets the internal texture_type, based on the data
36 35 /// size. Either 3D, 2D, 1D textures.
37   -
  36 +
38 37 void
39 38 setTextureType()
40 39 {
... ... @@ -60,16 +59,14 @@ class gl_texture : public virtual image_stack&lt;T&gt;
60 59  
61 60 public:
62 61  
63   - ///Method: Basic Constructor
64   - /// Creates an instance of the gl_texture object.
  62 + ///default constructor
65 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 71 gl_texture(std::string file_path)
75 72 {
... ... @@ -77,8 +74,8 @@ class gl_texture : public virtual image_stack&lt;T&gt;
77 74 image_stack<T>::load_images(path.append("/*.jpg"));
78 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 79 vec<int>
83 80 getSize()
84 81 {
... ... @@ -86,7 +83,6 @@ class gl_texture : public virtual image_stack&lt;T&gt;
86 83 return size;
87 84 }
88 85  
89   - ///Method:setTexParam
90 86 ///@param GLint interp --GL_LINEAR, GL_NEAREST...
91 87 ///@param GLint twrap --GL_REPEAR, GL_CLAMP_TO_EDGE...
92 88 ///@param GLenum dataType --GL_UNSIGNED_BYTE, GL_FLOAT16...
... ... @@ -103,7 +99,7 @@ class gl_texture : public virtual image_stack&lt;T&gt;
103 99 type = dataType;
104 100 format = dataFormat;
105 101 }
106   - ///Method:setDims
  102 +
107 103 ///@param x size of the voxel in x direction
108 104 ///@param y size of the voxel in y direction
109 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 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 116 vec<float>
123 117 getDims()
124 118 {
... ... @@ -126,11 +120,8 @@ class gl_texture : public virtual image_stack&lt;T&gt;
126 120 return dims;
127 121 }
128 122  
129   - ///Method:setPath
130 123 ///@param file_Path location of the directory with the files
131 124 /// Sets the path and calls the loader on that path.
132   -
133   -
134 125 void
135 126 setPath(std::string file_path)
136 127 {
... ... @@ -139,19 +130,14 @@ class gl_texture : public virtual image_stack&lt;T&gt;
139 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 134 std::string
147 135 getPath()
148 136 {
149 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 141 /// instance of the gl_texture class.
156 142  
157 143 GLuint
... ... @@ -160,7 +146,6 @@ class gl_texture : public virtual image_stack&lt;T&gt;
160 146 return texID;
161 147 }
162 148  
163   - ///Method: createTexture
164 149 /// Creates a texture and from the loaded data and
165 150 /// assigns that texture to texID
166 151 //TO DO :::: 1D textures
... ...
stim/math/plane.h
1   -#ifndef RTS_PLANE_H
2   -#define RTS_PLANE_H
  1 +#ifndef STIM_PLANE_H
  2 +#define STIM_PLANE_H
3 3  
4 4 #include <iostream>
5 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 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 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 46 vec<T> r = from.cross(to); //compute the rotation vector
47 47 T theta = asin(r.len()); //compute the angle of the rotation about r
48 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 50 return;
  51 + }
51 52  
52 53 //create a quaternion to capture the rotation
53 54 CreateRotation(theta, r.norm());
... ...
stim/math/rect.h
1   -#ifndef RTS_RECT_H
2   -#define RTS_RECT_H
  1 +#ifndef STIM_RECT_H
  2 +#define STIM_RECT_H
  3 +
3 4  
4 5 //enable CUDA_CALLABLE macro
5 6 #include <stim/cuda/cudatools/callable.h>
  7 +#include <stim/math/plane.h>
6 8 #include <stim/math/vector.h>
7 9 #include <stim/math/triangle.h>
8   -#include <stim/math/quaternion.h>
9 10 #include <iostream>
10 11 #include <iomanip>
11 12 #include <algorithm>
  13 +#include <assert.h>
12 14  
13 15 namespace stim{
14 16  
15 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 22 ^ O
21 23 |
22 24 |
23   - Y C
  25 + Y P
24 26 |
25 27 |
26 28 O---------X--------->
... ... @@ -28,106 +30,143 @@ struct rect
28 30  
29 31 private:
30 32  
31   - stim::vec<T> C;
32 33 stim::vec<T> X;
33 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 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 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 60 init(); //use the default setup
68 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 71 init(); //start with the default setting
76   - C = c;
77 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 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 95 X = directionX;
84 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 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 107 X = directionX;
91 108 Y = directionY;
92 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 120 X = directionX;
99 121 Y = directionY;
100 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 135 X *= factor1;
105 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 154 //boolean comparison
109 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 158 return true;
113 159 else
114 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 164 //get the world space value given the planar coordinates a, b in [0, 1]
126 165 CUDA_CALLABLE stim::vec<T> p(T a, T b)
127 166 {
128 167 stim::vec<T> result;
129 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 170 result = A + X * a + Y * b;
132 171  
133 172 return result;
... ... @@ -142,16 +181,16 @@ public:
142 181 std::string str()
143 182 {
144 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 185 ss<<std::left<<"B="<<std::setfill('-')<<std::setw(20)<<A + Y<<">"<<"C="<<A + Y + X<<std::endl;
147 186 ss<<std::setfill(' ')<<std::setw(23)<<"|"<<"|"<<std::endl<<std::setw(23)<<"|"<<"|"<<std::endl;
148 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 194 CUDA_CALLABLE rect<T> operator*(T rhs)
156 195 {
157 196 //scales the plane by a scalar value
... ... @@ -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 208 CUDA_CALLABLE T dist(vec<T> p)
169 209 {
170 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 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 71 vec( const vec<T>& other){
72 72 unsigned int N = other.size();
73 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 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 29 void
30 30 init()
31 31 {
  32 + if(glIsList(dList))
  33 + glDeleteLists(dList, 1);
32 34 dList = glGenLists(1);
33 35 glListBase(dList);
34 36  
... ... @@ -40,16 +42,25 @@ private:
40 42 }
41 43  
42 44 void
43   - Create()
  45 + Create(GLenum mode)
44 46 {
  47 +// GLuint selectBuf[2048];
  48 +// GLint hits;
  49 +// glSelectBuffer(2048, selectBuf);
  50 +
45 51 int len = (int) stim::obj<T>::numL();
46 52 std::vector< stim::vec<float> > line;
47 53 glNewList(dList, GL_COMPILE);
48 54 // glColor3f(0.0, 1.0, 0.0);
49   - glLineWidth(2.5);
  55 + glLineWidth(3.5);
50 56 for(int i = 0; i < len; i++){
51 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 64 glBegin(GL_LINE_STRIP);
54 65 for(int j = 0; j < line.size(); j++){
55 66 glVertex3f(
... ... @@ -71,21 +82,21 @@ public:
71 82 }
72 83  
73 84 void
74   - createFromSelf()
  85 + createFromSelf(GLenum mode = GL_RENDER)
75 86 {
76 87 // glPopMatrix();
77 88 init();
78   - Create();
  89 + Create(mode);
79 90 // glPushMatrix();
80 91 }
81 92  
82 93 void
83   - createFromFile(std::string filename)
  94 + createFromFile(std::string filename, GLenum mode = GL_RENDER)
84 95 {
85 96 stim::obj<T>::load(filename);
86 97 glPushMatrix(); //Safety Operation to avoid changing the current matrix.
87 98 init();
88   - Create();
  99 + Create(mode);
89 100 glPopMatrix();
90 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 683 l.resize(nP);
684 684  
685 685 //copy the points from the point list to the stim vector
686   - unsigned int pi;
  686 + unsigned int pie;
687 687 for(unsigned int p = 0; p < nP; p++){
688 688  
689 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 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 695 //copy the point into the vector
696 696 l[p] = newP;
... ... @@ -737,14 +737,14 @@ public:
737 737 l.resize(nP);
738 738  
739 739 //copy the points from the point list to the stim vector
740   - unsigned int pi;
  740 + unsigned int pie;
741 741 for(unsigned int p = 0; p < nP; p++){
742 742  
743 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 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 749 //copy the point into the vector
750 750 l[p] = newP;
... ...