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