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