Commit 057ea93beacf593c79e03b5179a94e2889f714c2
1 parent
b61addd8
add flow velocity vector field visualization feature replacing the former flow d…
…irection indicating method
Showing
2 changed files
with
84 additions
and
9 deletions
Show diff stats
@@ -1076,6 +1076,64 @@ namespace stim { | @@ -1076,6 +1076,64 @@ namespace stim { | ||
1076 | glFlush(); | 1076 | glFlush(); |
1077 | } | 1077 | } |
1078 | 1078 | ||
1079 | + // draw flow velocity field, glyph | ||
1080 | + void glyph(std::vector<unsigned char> color, GLint subdivision, T r = 4.0f) { | ||
1081 | + | ||
1082 | + // v1----v2-->v3 | ||
1083 | + T k = 4.0f; // quartering | ||
1084 | + stim::vec3<T> v1, v2, v3; // three point | ||
1085 | + stim::vec3<T> d; // direction vector | ||
1086 | + stim::circle<float> tmp_c; | ||
1087 | + std::vector<typename stim::vec3<float> > cp1(subdivision + 1); | ||
1088 | + std::vector<typename stim::vec3<float> > cp2(subdivision + 1); | ||
1089 | + | ||
1090 | + for (unsigned i = 0; i < num_edge; i++) { // for every edge | ||
1091 | + glColor3f((float)color[i * 3 + 0] / 255.0f, (float)color[i * 3 + 1] / 255.0f, (float)color[i * 3 + 2] / 255.0f); | ||
1092 | + for (unsigned j = 0; j < E[i].size() - 1; j++) { // for every point on that edge | ||
1093 | + | ||
1094 | + // consider the velocity valuence | ||
1095 | + if (v[i] > 0) { // positive, from start point to end point | ||
1096 | + v1 = E[i][j]; | ||
1097 | + v3 = E[i][j + 1]; | ||
1098 | + } | ||
1099 | + else { // negative, from end point to start point | ||
1100 | + v1 = E[i][j + 1]; | ||
1101 | + v3 = E[i][j]; | ||
1102 | + } | ||
1103 | + d = v3 - v1; | ||
1104 | + // place the arrow in the middel of one edge | ||
1105 | + v2 = v1 + (1.0f / k * 2.0f) * d; // looks like =->= | ||
1106 | + v1 = v1 + (1.0f / k) * d; | ||
1107 | + v3 = v3 - (1.0f / k) * d; | ||
1108 | + d = d.norm(); | ||
1109 | + tmp_c.rotate(d); | ||
1110 | + | ||
1111 | + // render the cylinder part | ||
1112 | + stim::circle<T> c1(v1, r / 2, d, tmp_c.U); | ||
1113 | + cp1 = c1.glpoints(subdivision); | ||
1114 | + stim::circle<T> c2(v2, r / 2, d, tmp_c.U); | ||
1115 | + cp2 = c2.glpoints(subdivision); | ||
1116 | + | ||
1117 | + glBegin(GL_QUAD_STRIP); | ||
1118 | + for (unsigned k = 0; k < cp1.size(); k++) { | ||
1119 | + glVertex3f(cp1[k][0], cp1[k][1], cp1[k][2]); | ||
1120 | + glVertex3f(cp2[k][0], cp2[k][1], cp2[k][2]); | ||
1121 | + } | ||
1122 | + glEnd(); | ||
1123 | + | ||
1124 | + // render the cone part | ||
1125 | + stim::circle<T> c3(v2, r, d, tmp_c.U); | ||
1126 | + cp2 = c3.glpoints(subdivision); | ||
1127 | + glBegin(GL_TRIANGLE_FAN); | ||
1128 | + glVertex3f(v3[0], v3[1], v3[2]); | ||
1129 | + for (unsigned k = 0; k < cp2.size(); k++) | ||
1130 | + glVertex3f(cp2[k][0], cp2[k][1], cp2[k][2]); | ||
1131 | + glEnd(); | ||
1132 | + } | ||
1133 | + } | ||
1134 | + glFlush(); | ||
1135 | + } | ||
1136 | + | ||
1079 | // display the total volume flow rate | 1137 | // display the total volume flow rate |
1080 | void display_flow_rate(T in, T out) { | 1138 | void display_flow_rate(T in, T out) { |
1081 | 1139 | ||
@@ -1609,7 +1667,8 @@ namespace stim { | @@ -1609,7 +1667,8 @@ namespace stim { | ||
1609 | width = (T)origin_l / (2 * n); // updates | 1667 | width = (T)origin_l / (2 * n); // updates |
1610 | height = (desire_l - origin_l) / (2 * n); | 1668 | height = (desire_l - origin_l) / (2 * n); |
1611 | 1669 | ||
1612 | - if (width < times * radius) { // check feasibility | 1670 | + // there are cases that the fragment can not satisfy the requirement for width |
1671 | + if (width < times * radius || n == 0) { // check feasibility | ||
1613 | ratio = 0.0f; // load | 1672 | ratio = 0.0f; // load |
1614 | desire_l = tmp_d; | 1673 | desire_l = tmp_d; |
1615 | origin_l = tmp_l; | 1674 | origin_l = tmp_l; |
main.cu
@@ -84,7 +84,8 @@ bool render_direction = false; // flag indicates rendering flow direction for o | @@ -84,7 +84,8 @@ bool render_direction = false; // flag indicates rendering flow direction for o | ||
84 | bool simulation = false; // flag indicates simulation mode | 84 | bool simulation = false; // flag indicates simulation mode |
85 | bool color_bound = false; // flag indicates velocity color map bound | 85 | bool color_bound = false; // flag indicates velocity color map bound |
86 | bool to_select_pressure = false; // flag indicates having selected a vertex to modify pressure | 86 | bool to_select_pressure = false; // flag indicates having selected a vertex to modify pressure |
87 | -bool mark_index = true; // flag indicates marking the index near the vertex | 87 | +bool mark_index = true; // flag indicates marking the index near the vertex |
88 | +bool flow_direction = false; // flag indicates rendering glyph for flow velocity field | ||
88 | unsigned pressure_index; // the index of vertex that is clicked | 89 | unsigned pressure_index; // the index of vertex that is clicked |
89 | unsigned direction_index = -1; // the index of edge that is pointed at | 90 | unsigned direction_index = -1; // the index of edge that is pointed at |
90 | unsigned index_index = -1; // the index of the vertex | 91 | unsigned index_index = -1; // the index of the vertex |
@@ -255,11 +256,18 @@ void glut_render() { | @@ -255,11 +256,18 @@ void glut_render() { | ||
255 | } | 256 | } |
256 | else { | 257 | else { |
257 | flow.bounding_box(); | 258 | flow.bounding_box(); |
258 | - flow.glSolidSphere(max_pressure, scale, subdivision); | ||
259 | - if (mark_index) | ||
260 | - flow.mark_vertex(scale); | ||
261 | - //flow.glSolidCone(subdivision); | ||
262 | - flow.glSolidCylinder(direction_index, color, scale, subdivision); | 259 | + // render network |
260 | + if (!flow_direction) { | ||
261 | + flow.glSolidSphere(max_pressure, scale, subdivision); | ||
262 | + if (mark_index) | ||
263 | + flow.mark_vertex(scale); | ||
264 | + //flow.glSolidCone(subdivision); | ||
265 | + flow.glSolidCylinder(direction_index, color, scale, subdivision); | ||
266 | + } | ||
267 | + // render glyphs | ||
268 | + else | ||
269 | + flow.glyph(color, subdivision); | ||
270 | + | ||
263 | flow.glSolidCuboid(manufacture, length); | 271 | flow.glSolidCuboid(manufacture, length); |
264 | if (render_direction) | 272 | if (render_direction) |
265 | flow.glSolidCone(direction_index, scale, subdivision); | 273 | flow.glSolidCone(direction_index, scale, subdivision); |
@@ -531,9 +539,9 @@ void glut_passive_motion(int x, int y) { | @@ -531,9 +539,9 @@ void glut_passive_motion(int x, int y) { | ||
531 | 539 | ||
532 | if (simulation || build_inlet_outlet && !mods) { | 540 | if (simulation || build_inlet_outlet && !mods) { |
533 | bool flag = flow.epsilon_edge((float)posX, (float)posY, (float)posZ, eps, direction_index); | 541 | bool flag = flow.epsilon_edge((float)posX, (float)posY, (float)posZ, eps, direction_index); |
534 | - if (flag) | 542 | + if (flag && !flow_direction) |
535 | render_direction = true; | 543 | render_direction = true; |
536 | - else { | 544 | + else if (!flag && !flow_direction) { |
537 | if (render_direction) // if the direction is displaying currently, do a short delay | 545 | if (render_direction) // if the direction is displaying currently, do a short delay |
538 | Sleep(300); | 546 | Sleep(300); |
539 | render_direction = false; | 547 | render_direction = false; |
@@ -844,6 +852,14 @@ void glut_keyboard(unsigned char key, int x, int y) { | @@ -844,6 +852,14 @@ void glut_keyboard(unsigned char key, int x, int y) { | ||
844 | case 's': | 852 | case 's': |
845 | flow.save_network(); | 853 | flow.save_network(); |
846 | break; | 854 | break; |
855 | + | ||
856 | + // flow vector field visualization, Glyphs | ||
857 | + case 'f': | ||
858 | + if (flow_direction && !manufacture && (simulation || build_inlet_outlet)) | ||
859 | + flow_direction = false; | ||
860 | + else if(!flow_direction && !manufacture && (simulation || build_inlet_outlet)) | ||
861 | + flow_direction = true; | ||
862 | + break; | ||
847 | 863 | ||
848 | // open/close index marks | 864 | // open/close index marks |
849 | case 'e': | 865 | case 'e': |