Commit 8f6c2057eeb0eb428641e9cd53a7f437139dbdfb
1 parent
4bb615eb
fixed index marking bugs after network subdivided
Showing
2 changed files
with
110 additions
and
24 deletions
Show diff stats
... | ... | @@ -67,7 +67,7 @@ namespace stim { |
67 | 67 | #ifdef __CUDACC__ |
68 | 68 | // for sphere |
69 | 69 | template <typename T> |
70 | - __global__ void inside_sphere(const stim::sphere<T> *V, size_t num, T Z,size_t *R, T *S, unsigned char *ptr, int x, int y, int z) { | |
70 | + __global__ void inside_sphere(const stim::sphere<T> *V, size_t num, T Z,size_t *R, T *S, unsigned char *ptr, int x, int y, int z, T std = 1.0f) { | |
71 | 71 | |
72 | 72 | unsigned ix = blockDim.x * blockIdx.x + threadIdx.x; |
73 | 73 | unsigned iy = blockDim.y * blockIdx.y + threadIdx.y; |
... | ... | @@ -93,11 +93,16 @@ namespace stim { |
93 | 93 | } |
94 | 94 | if (distance <= V[idx].r) |
95 | 95 | ptr[(R[2] - 1 - iy) * R[0] * R[1] + ix * R[0]] = 255; |
96 | + else { | |
97 | + T g = gaussianFunction(std::pow(distance - V[idx].r, 2), std); | |
98 | + if(g > 0.1f) | |
99 | + ptr[(R[2] - 1 - iy) * R[0] * R[1] + ix * R[0]] = 255; | |
100 | + } | |
96 | 101 | } |
97 | 102 | |
98 | 103 | // for cone |
99 | 104 | template <typename T> |
100 | - __global__ void inside_cone(const stim::cone<T> *E, size_t num, T Z, size_t *R, T *S, unsigned char *ptr, int x, int y, int z) { | |
105 | + __global__ void inside_cone(const stim::cone<T> *E, size_t num, T Z, size_t *R, T *S, unsigned char *ptr, int x, int y, int z, T std = 1.0f) { | |
101 | 106 | |
102 | 107 | unsigned ix = blockDim.x * blockIdx.x + threadIdx.x; |
103 | 108 | unsigned iy = blockDim.y * blockIdx.y + threadIdx.y; |
... | ... | @@ -129,6 +134,11 @@ namespace stim { |
129 | 134 | } |
130 | 135 | if (distance <= rr) |
131 | 136 | ptr[(R[2] - 1 - iy) * R[0] * R[1] + ix * R[0]] = 255; |
137 | + else { | |
138 | + T g = gaussianFunction(std::pow(distance - rr, 2), std); | |
139 | + if (g > 0.1f) | |
140 | + ptr[(R[2] - 1 - iy) * R[0] * R[1] + ix * R[0]] = 255; | |
141 | + } | |
132 | 142 | } |
133 | 143 | |
134 | 144 | // for source bus |
... | ... | @@ -252,7 +262,7 @@ namespace stim { |
252 | 262 | |
253 | 263 | bool set = false; // flag indicates the pressure has been set |
254 | 264 | std::vector<T> P; // initial pressure |
255 | - std::vector<T> v; // velocity | |
265 | + std::vector<T> v; // average velocity along each edge | |
256 | 266 | std::vector<typename stim::vec3<T> > main_feeder; // inlet/outlet main feeder |
257 | 267 | std::vector<unsigned> pendant_vertex; |
258 | 268 | std::vector<typename stim::triple<unsigned, unsigned, T> > input; // first one store which vertex, second one stores which edge, third one stores in/out volume flow rate of that vertex |
... | ... | @@ -350,12 +360,22 @@ namespace stim { |
350 | 360 | return E[tmp_e].r(tmp_v); |
351 | 361 | } |
352 | 362 | |
353 | - // get the radius of index j of edge i | |
363 | + // get the radius of point j on edge i | |
354 | 364 | T get_radius(unsigned i, unsigned j) { |
355 | 365 | return E[i].r(j); |
356 | 366 | } |
357 | 367 | |
358 | - // get the pendant vertices | |
368 | + // back up vertices | |
369 | + std::vector<stim::vec3<T> > back_vertex() { | |
370 | + std::vector<stim::vec3<T> > result; | |
371 | + | |
372 | + for (unsigned i = 0; i < num_vertex; i++) | |
373 | + result.push_back(stim::vec3<T>(V[i][0], V[i][1], V[i][2])); | |
374 | + | |
375 | + return result; | |
376 | + } | |
377 | + | |
378 | + // get pendant vertices | |
359 | 379 | std::vector<unsigned> get_pendant_vertex() { |
360 | 380 | std::vector<unsigned> result; |
361 | 381 | int count = 0; |
... | ... | @@ -851,7 +871,7 @@ namespace stim { |
851 | 871 | } |
852 | 872 | else |
853 | 873 | glColor3f((float)color[i * 3 + 0] / 255, (float)color[i * 3 + 1] / 255, (float)color[i * 3 + 2] / 255); |
854 | - | |
874 | + | |
855 | 875 | for (unsigned j = 0; j < E[i].size() - 1; j++) { // for every point on the edge |
856 | 876 | center1 = E[i][j]; |
857 | 877 | center2 = E[i][j + 1]; |
... | ... | @@ -1532,13 +1552,13 @@ namespace stim { |
1532 | 1552 | } |
1533 | 1553 | |
1534 | 1554 | // mark the vertex |
1535 | - void mark_vertex(T scale = 1.0f) { | |
1555 | + void mark_vertex(std::vector<stim::vec3<T> > vertex, T scale = 1.0f) { | |
1536 | 1556 | |
1537 | 1557 | glColor3f(0.0f, 0.0f, 0.0f); |
1538 | - for (unsigned i = 0; i < num_vertex; i++) { | |
1539 | - glRasterPos3f(V[i][0], V[i][1] + get_radius(i) * scale, V[i][2]); | |
1558 | + for (unsigned i = 0; i < vertex.size(); i++) { | |
1559 | + glRasterPos3f(vertex[i][0], vertex[i][1] + get_radius(i) * scale, vertex[i][2]); // place position | |
1540 | 1560 | std::stringstream ss; |
1541 | - ss << i; | |
1561 | + ss << i; // store index value | |
1542 | 1562 | glutBitmapString(GLUT_BITMAP_HELVETICA_18, (const unsigned char*)(ss.str().c_str())); |
1543 | 1563 | } |
1544 | 1564 | } |
... | ... | @@ -2877,7 +2897,18 @@ namespace stim { |
2877 | 2897 | f_file.close(); |
2878 | 2898 | } |
2879 | 2899 | |
2880 | - /// Calculate the inverse of A and store the result in C | |
2900 | + /// check whether current network needs to be subdivided | |
2901 | + bool check_subdivision() { | |
2902 | + | |
2903 | + for (size_t i = 0; i < num_edge; i++) { | |
2904 | + if (E[i].size() > 2) { | |
2905 | + return true; | |
2906 | + } | |
2907 | + } | |
2908 | + return false; | |
2909 | + } | |
2910 | + | |
2911 | + /// calculate the inverse of A and store the result in C | |
2881 | 2912 | void inversion(T** A, int order, T* C) { |
2882 | 2913 | |
2883 | 2914 | #ifdef __CUDACC__ |
... | ... | @@ -2970,6 +3001,15 @@ namespace stim { |
2970 | 3001 | free(minor); |
2971 | 3002 | #endif |
2972 | 3003 | } |
3004 | + | |
3005 | + /// arithmetic | |
3006 | + // assignment | |
3007 | + flow<T> & operator= (flow<T> rhs) { | |
3008 | + E = rhs.E; | |
3009 | + V = rhs.V; | |
3010 | + | |
3011 | + return *this; | |
3012 | + } | |
2973 | 3013 | }; |
2974 | 3014 | } |
2975 | 3015 | ... | ... |
main.cu
... | ... | @@ -40,6 +40,7 @@ unsigned num_vertex; // number of vertex in the network |
40 | 40 | std::vector<unsigned> pendant_vertex; // list of pendant vertex index in GT |
41 | 41 | std::vector<std::string> menu_option = { "simulation", "build inlet/outlet", "manufacture", "adjustment" }; |
42 | 42 | stim::flow<float> flow; // flow object |
43 | +stim::flow<float> backup; // flow backup | |
43 | 44 | float move_pace; // camera moving parameter |
44 | 45 | float u; // viscosity |
45 | 46 | float rou; // density |
... | ... | @@ -79,7 +80,7 @@ int mouse_x; // window x-coordinate |
79 | 80 | int mouse_y; // window y-coordinate |
80 | 81 | int picked_x; // picked window x-coordinate |
81 | 82 | int picked_y; // picked window y-coordinate |
82 | -bool LTbutton = false; // true means down while false means up | |
83 | +bool LTbutton = false; // true means down while false means up | |
83 | 84 | |
84 | 85 | // simulation parameters |
85 | 86 | bool render_direction = false; // flag indicates rendering flow direction for one edge |
... | ... | @@ -89,8 +90,10 @@ bool to_select_pressure = false; // flag indicates having selected a vertex to m |
89 | 90 | bool mark_index = true; // flag indicates marking the index near the vertex |
90 | 91 | bool glyph_mode = false; // flag indicates rendering glyph for flow velocity field |
91 | 92 | bool frame_mode = false; // flag indicates rendering filament framing structrues |
93 | +bool subdivided = false; // flag indicates subdivision status | |
92 | 94 | unsigned pressure_index; // the index of vertex that is clicked |
93 | 95 | unsigned direction_index = UINT_MAX;// the index of edge that is pointed at |
96 | +std::vector<stim::vec3<float> > back_vertex; // vertex back up for marking indices | |
94 | 97 | |
95 | 98 | // build inlet/outlet parameters |
96 | 99 | bool build_inlet_outlet = false; // flag indicates building inlets and outlets |
... | ... | @@ -169,6 +172,8 @@ void flow_initialize() { |
169 | 172 | |
170 | 173 | flow.set = true; |
171 | 174 | stim::vec3<float> center = bb.center(); |
175 | + flow.P.clear(); | |
176 | + flow.P.resize(num_vertex, 0); // clear up initialized pressure | |
172 | 177 | |
173 | 178 | for (unsigned i = 0; i < pendant_vertex.size(); i++) { |
174 | 179 | if (flow.get_vertex(pendant_vertex[i])[0] <= center[0]) |
... | ... | @@ -271,7 +276,7 @@ void glut_render() { |
271 | 276 | if (!glyph_mode) { |
272 | 277 | flow.glSolidSphere(max_pressure, subdivision, scale); |
273 | 278 | if (mark_index) |
274 | - flow.mark_vertex(scale); | |
279 | + flow.mark_vertex(back_vertex, scale); | |
275 | 280 | //flow.glSolidCone(subdivision); |
276 | 281 | flow.glSolidCylinder(direction_index, color, subdivision, scale); |
277 | 282 | } |
... | ... | @@ -288,7 +293,7 @@ void glut_render() { |
288 | 293 | if (!glyph_mode) { |
289 | 294 | flow.glSolidSphere(max_pressure, subdivision, scale); |
290 | 295 | if (mark_index) { |
291 | - flow.mark_vertex(scale); | |
296 | + flow.mark_vertex(back_vertex, scale); | |
292 | 297 | //flow.mark_edge(); |
293 | 298 | } |
294 | 299 | //flow.glSolidCone(subdivision); |
... | ... | @@ -299,7 +304,7 @@ void glut_render() { |
299 | 304 | flow.glyph(color, subdivision, scale, frame_mode); |
300 | 305 | } |
301 | 306 | flow.glSolidCuboid(subdivision, manufacture, length); // render bus source |
302 | - if (render_direction) // render the flow direction of the vertex pointed | |
307 | + if (render_direction && !glyph_mode) // render the flow direction of the vertex pointed | |
303 | 308 | flow.glSolidCone(direction_index, subdivision, scale); |
304 | 309 | } |
305 | 310 | |
... | ... | @@ -495,6 +500,7 @@ void glut_menu(int value) { |
495 | 500 | // first time |
496 | 501 | if (!flow.set) { // only first time simulation called "simulation", ^_^ |
497 | 502 | get_background(); // get the graph information |
503 | + back_vertex = flow.back_vertex(); // vertex back up for marking indices | |
498 | 504 | flow_initialize(); // initialize flow condition |
499 | 505 | menu_option[0] = "resimulation"; |
500 | 506 | } |
... | ... | @@ -584,6 +590,7 @@ void glut_passive_motion(int x, int y) { |
584 | 590 | render_direction = false; |
585 | 591 | direction_index = -1; |
586 | 592 | } |
593 | + undo = true; | |
587 | 594 | } |
588 | 595 | |
589 | 596 | if (mods == GLUT_ACTIVE_SHIFT && picked_connection) { |
... | ... | @@ -888,7 +895,7 @@ void glut_keyboard(unsigned char key, int x, int y) { |
888 | 895 | |
889 | 896 | // register different keyboard operation |
890 | 897 | switch (key) { |
891 | - | |
898 | + | |
892 | 899 | // saving network flow profile |
893 | 900 | case 's': |
894 | 901 | flow.save_network(); |
... | ... | @@ -903,7 +910,39 @@ void glut_keyboard(unsigned char key, int x, int y) { |
903 | 910 | flow.saveNwt(filename); |
904 | 911 | break; |
905 | 912 | } |
906 | - | |
913 | + | |
914 | + // subdivide current network for more detailed calculation | |
915 | + case 'd': { | |
916 | + // subdivide current network due to the limitation of current computation if needed | |
917 | + if (!subdivided && simulation && !glyph_mode) { | |
918 | + subdivided = true; | |
919 | + | |
920 | + // check whether current network can be subdivided | |
921 | + if (flow.check_subdivision()) { | |
922 | + flow.subdivision(); | |
923 | + get_background(); | |
924 | + } | |
925 | + | |
926 | + flow_initialize(); // initialize flow condition | |
927 | + // resimulation | |
928 | + flow_stable_state(); // main function of solving the linear system | |
929 | + flow.print_flow(); | |
930 | + undo = true; | |
931 | + } | |
932 | + else if (subdivided && simulation && !glyph_mode) { | |
933 | + subdivided = false; | |
934 | + flow = backup; // load back up | |
935 | + | |
936 | + get_background(); | |
937 | + flow_initialize(); | |
938 | + // resimulation | |
939 | + flow_stable_state(); // main function of solving the linear system | |
940 | + flow.print_flow(); | |
941 | + undo = true; | |
942 | + } | |
943 | + break; | |
944 | + } | |
945 | + | |
907 | 946 | // flow vector field visualization, Glyphs |
908 | 947 | case 'f': |
909 | 948 | if (glyph_mode && !manufacture && (simulation || build_inlet_outlet)) { |
... | ... | @@ -923,7 +962,7 @@ void glut_keyboard(unsigned char key, int x, int y) { |
923 | 962 | } |
924 | 963 | undo = true; |
925 | 964 | break; |
926 | - | |
965 | + | |
927 | 966 | // filaments around arrows |
928 | 967 | case 'g': |
929 | 968 | if (glyph_mode) { |
... | ... | @@ -932,8 +971,9 @@ void glut_keyboard(unsigned char key, int x, int y) { |
932 | 971 | else |
933 | 972 | frame_mode = true; |
934 | 973 | } |
974 | + undo = true; | |
935 | 975 | break; |
936 | - | |
976 | + | |
937 | 977 | // open/close index marks |
938 | 978 | case 'e': |
939 | 979 | if (mark_index) |
... | ... | @@ -1047,12 +1087,18 @@ int main(int argc, char* argv[]) { |
1047 | 1087 | } |
1048 | 1088 | else { // load network from user |
1049 | 1089 | std::vector<std::string> tmp = stim::parser::split(args.arg(0), '.'); |
1050 | - if ("obj" == tmp[1]) | |
1090 | + if ("obj" == tmp[1]) { | |
1051 | 1091 | flow.load_obj(args.arg(0)); |
1052 | - else if ("nwt" == tmp[1]) // stim network binary format | |
1053 | - flow.loadNwt(args.arg(0)); | |
1054 | - else if ("swc" == tmp[1]) | |
1055 | - flow.load_swc(args.arg(0)); | |
1092 | + backup.load_obj(args.arg(0)); | |
1093 | + } | |
1094 | + else if ("nwt" == tmp[1]) { // stim network binary format | |
1095 | + flow.loadNwt(args.arg(0)); | |
1096 | + backup.loadNwt(args.arg(0)); | |
1097 | + } | |
1098 | + else if ("swc" == tmp[1]) { | |
1099 | + flow.load_swc(args.arg(0)); | |
1100 | + backup.load_swc(args.arg(0)); | |
1101 | + } | |
1056 | 1102 | else { |
1057 | 1103 | std::cout << "Invalid file type" << std::endl; |
1058 | 1104 | std::exit(1); | ... | ... |