Commit 8f6c2057eeb0eb428641e9cd53a7f437139dbdfb

Authored by Jiaming Guo
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  
... ...
... ... @@ -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);
... ...