From 6ea69c93b241f27c03b91f54792cf670b3d722bb Mon Sep 17 00:00:00 2001 From: Jiaming Guo Date: Fri, 30 Jun 2017 15:12:55 -0500 Subject: [PATCH] change bus size --- flow.h | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------- main.cu | 61 ++++++++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 107 insertions(+), 69 deletions(-) diff --git a/flow.h b/flow.h index e42c193..9e1ea78 100644 --- a/flow.h +++ b/flow.h @@ -463,7 +463,7 @@ namespace stim { // get the color map based on velocity range along the network color.clear(); if (pendant_vertex.size() == 2 && num_edge - num_vertex + 1 <= 0) // only one inlet and one outlet - color.resize(num_edge * 3, (unsigned char)255); + color.resize(num_edge * 3, (unsigned char)128); else { color.resize(num_edge * 3); stim::cpu2cpu(&abs_V[0], &color[0], num_edge, min_v, max_v, stim::cmBrewer); @@ -736,7 +736,7 @@ namespace stim { } // draw solid sphere at every vertex - void glSolidSphere(T max_pressure, GLint subdivision) { + void glSolidSphere(T max_pressure, T scale, GLint subdivision) { // waste? for (unsigned i = 0; i < num_edge; i++) { @@ -750,9 +750,21 @@ namespace stim { glPushMatrix(); glTranslatef(E[i][0][0], E[i][0][1], E[i][0][2]); - glutSolidSphere(get_r(i, 0), subdivision, subdivision); + glutSolidSphere(get_r(i, 0) * scale, subdivision, subdivision); glPopMatrix(); } + else { + glEnable(GL_BLEND); // enable color blend + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // set blend function + glDisable(GL_DEPTH_TEST); + glColor4f(0.7f, 0.7f, 0.7f, 0.7f); // gray color + glPushMatrix(); + glTranslatef(E[i][0][0], E[i][0][1], E[i][0][2]); + glutSolidSphere(get_r(i, 0) * scale, subdivision, subdivision); + glPopMatrix(); + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + } // draw the ending vertex if (P[E[i].v[1]] != 0) { @@ -764,41 +776,26 @@ namespace stim { glPushMatrix(); glTranslatef(E[i][E[i].size() - 1][0], E[i][E[i].size() - 1][1], E[i][E[i].size() - 1][2]); - glutSolidSphere(get_r(i, E[i].size() - 1), subdivision, subdivision); + glutSolidSphere(get_r(i, E[i].size() - 1) * scale, subdivision, subdivision); glPopMatrix(); } - //for (unsigned j = 0; j < E[i].size(); j++) { - // if (j == 0) { // for start vertex - // if (P[E[i].v[0]] != 0) { - // stim::vec3 new_color; - // new_color[0] = (P[E[i].v[0]] / max_pressure) > 0.5f ? 1.0f : 2.0f * P[E[i].v[0]] / max_pressure; // red - // new_color[1] = 0.0f; // green - // new_color[2] = (P[E[i].v[0]] / max_pressure) > 0.5f ? 1.0f - 2.0f * (P[E[i].v[0]] / max_pressure - 0.5f) : 1.0f; // blue - // glColor3f(new_color[0], new_color[1], new_color[2]); - // } - // } - // else if (j == E[i].size() - 1) { // for end vertex - // if (P[E[i].v[1]] != 0) { - // stim::vec3 new_color; - // new_color[0] = (P[E[i].v[1]] / max_pressure) > 0.5f ? 1.0f : 2.0f * P[E[i].v[1]] / max_pressure; // red - // new_color[1] = 0.0f; // green - // new_color[2] = (P[E[i].v[1]] / max_pressure) > 0.5f ? 1.0f - 2.0f * (P[E[i].v[1]] / max_pressure - 0.5f) : 1.0f; // blue - // glColor3f(new_color[0], new_color[1], new_color[2]); - // } - // } - // else - // glColor3f(0.5f, 0.5f, 0.5f); // gray point - - // glPushMatrix(); - // glTranslatef(E[i][j][0], E[i][j][1], E[i][j][2]); - // glutSolidSphere(get_r(i, j), subdivision, subdivision); - // glPopMatrix(); - //} + else { + glEnable(GL_BLEND); // enable color blend + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // set blend function + glDisable(GL_DEPTH_TEST); + glColor4f(0.7f, 0.7f, 0.7f, 0.7f); // gray color + glPushMatrix(); + glTranslatef(E[i][E[i].size() - 1][0], E[i][E[i].size() - 1][1], E[i][E[i].size() - 1][2]); + glutSolidSphere(get_r(i, E[i].size() - 1) * scale, subdivision, subdivision); + glPopMatrix(); + glDisable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + } } } // draw edges as series of cylinders - void glSolidCylinder(unsigned index, std::vector color, GLint subdivision) { + void glSolidCylinder(unsigned index, std::vector color, T scale, GLint subdivision) { stim::vec3 tmp_d; stim::vec3 center1; @@ -813,7 +810,7 @@ namespace stim { glEnable(GL_BLEND); // enable color blend glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // set blend function glDisable(GL_DEPTH_TEST); - glColor4f((float)color[i * 3 + 0] / 255, (float)color[i * 3 + 1] / 255, (float)color[i * 3 + 2] / 255, 0.5f); + glColor4f((float)color[i * 3 + 0] / 255, (float)color[i * 3 + 1] / 255, (float)color[i * 3 + 2] / 255, 0.3f); } else glColor3f((float)color[i * 3 + 0] / 255, (float)color[i * 3 + 1] / 255, (float)color[i * 3 + 2] / 255); @@ -822,8 +819,8 @@ namespace stim { center1 = E[i][j]; center2 = E[i][j + 1]; - r1 = get_r(i, j); - r2 = get_r(i, j + 1); + r1 = get_r(i, j) * scale; + r2 = get_r(i, j + 1) * scale; //// calculate the envelope caps //find_envelope(cp1, cp2, center1, center2, r1, r2, subdivision); @@ -884,28 +881,31 @@ namespace stim { glFlush(); } - // draw the flow direction as cone - void glSolidCone(unsigned i, GLint subdivision) { + // draw the flow direction as cone, the size of the cone depends on the length of that edge + void glSolidCone(unsigned i, T scale, GLint subdivision) { stim::vec3 tmp_d; // direction stim::vec3 center; // cone hat center stim::vec3 head; // cone hat top stim::circle tmp_c; + T h; // height base of the cone std::vector > cp; T radius; - glColor3f(0.0f, 0.0f, 0.0f); + glColor3f(0.0f, 0.0f, 0.0f); // lime color unsigned index = E[i].size() / 2 - 1; tmp_d = E[i][index + 1] - E[i][index]; + h = tmp_d.len() / 3.0f; // get the height base by factor 3 tmp_d = tmp_d.norm(); center = (E[i][index + 1] + E[i][index]) / 2; tmp_c.rotate(tmp_d); - radius = (E[i].r(index + 1) + E[i].r(index)) / 2; + radius = (E[i].r(index + 1) + E[i].r(index)) / 2 * scale; + radius = (h / sqrt(3) < radius) ? h / sqrt(3) : radius; // update radius if (v[i] > 0) - head = center + tmp_d * 2 * sqrt(3) * radius; + head = center + tmp_d * h; else - head = center - tmp_d * 2 * sqrt(3) * radius; + head = center - tmp_d * h; stim::circle c(center, radius, tmp_d, tmp_c.U); cp = c.glpoints(subdivision); @@ -947,22 +947,25 @@ namespace stim { stim::vec3 head; // cone hat top stim::circle tmp_c; std::vector > cp; + T h; T radius; - glColor3f(0.0f, 0.0f, 0.0f); + glColor3f(0.600f, 0.847f, 0.788f); // draw a cone for every edge to indicate for (unsigned i = 0; i < num_edge; i++) { // for every edge unsigned k1 = E[i].size() / 2 - 1; // start and end index unsigned k2 = E[i].size() / 2; tmp_d = E[i][k2] - E[i][k1]; + h = tmp_d.len() / 3.0f; // get the height base by factor 3 tmp_d = tmp_d.norm(); center = (E[i][k2] + E[i][k1]) / 2; tmp_c.rotate(tmp_d); radius = (E[i].r(k2) + E[i].r(k1)) / 2; + radius = (h / sqrt(3) < radius) ? h / sqrt(3) : radius; // update radius by height base if necessary if (v[i] > 0) // if flow flows from k1 to k2 - head = center + tmp_d * 2 * sqrt(3) * radius; + head = center + tmp_d * h; else - head = center - tmp_d * 2 * sqrt(3) * radius; + head = center - tmp_d * h; stim::circle c(center, radius, tmp_d, tmp_c.U); cp = c.glpoints(subdivision); @@ -997,7 +1000,7 @@ namespace stim { } // draw main feeder as solid cube - void glSolidCuboid(T length = 210.0f, T height = 10.0f) { + void glSolidCuboid(T length = 40.0f, T height = 10.0f) { T width; stim::vec3 L = bb.A; // get the bottom left corner @@ -1219,11 +1222,11 @@ namespace stim { } // mark the vertex - void mark_vertex() { + void mark_vertex(T scale) { glColor3f(0.0f, 0.0f, 0.0f); for (unsigned i = 0; i < num_vertex; i++) { - glRasterPos3f(V[i][0], V[i][1] + get_radius(i), V[i][2]); + glRasterPos3f(V[i][0], V[i][1] + get_radius(i) * scale, V[i][2]); std::stringstream ss; ss << i; glutBitmapString(GLUT_BITMAP_HELVETICA_18, (const unsigned char*)(ss.str().c_str())); @@ -1232,7 +1235,7 @@ namespace stim { // find the nearest vertex of current click position // return true and a value if found - inline bool epsilon_vertex(T x, T y, T z, T eps, unsigned& v) { + inline bool epsilon_vertex(T x, T y, T z, T eps, T scale, unsigned& v) { T d = FLT_MAX; // minimum distance between 2 vertices T tmp_d = 0.0f; // temporary stores distance for loop @@ -1250,7 +1253,7 @@ namespace stim { tmp_i = i; // get the index of that vertex } } - eps += get_radius(tmp_i); // increase epsilon accordingly + eps += get_radius(tmp_i) * scale; // increase epsilon accordingly if (d < eps) { // if current click is close to any vertex v = tmp_i; // copy the extant vertex's index to v return true; @@ -1292,7 +1295,7 @@ namespace stim { else online = false; - if (tmp_d <= 0.0 || tmp_d > std::pow(v1.len(), 2) && !online) // projection lies outside the line-segment + if (tmp_d <= 0.0 || tmp_d >= std::pow(v1.len(), 2) && !online) // projection lies outside the line-segment continue; else { tmp_d = v1.cross(v2).len() / v1.len(); // perpendicular distance of point to segment: |v1 x v2| / |v1| @@ -1397,7 +1400,7 @@ namespace stim { /// build main feeder connection // set up main feeder and main port of both input and output - void set_main_feeder(T border = 400.0f) { + void set_main_feeder(T border = 100.0f) { // 0 means outgoing while 1 means incoming stim::vec3 inlet_main_feeder; @@ -1466,11 +1469,11 @@ namespace stim { stim::vec3 tmp_v; // start vertex stim::vec3 mid_v; // middle point of the bridge stim::vec3 bus_v; // point on the bus - x0 = main_feeder[0][0] + 100.0f; // assume bus length is 210.0f + x0 = main_feeder[0][0] + 15.0f; // assume bus length is 40.0f for (unsigned i = 0; i < input.size(); i++) { tmp_v = V[input[i].first]; - dx = 200.0f * ((tmp_v[0] - L[0]) / box_length); // the socket position depends on proximity + dx = 30.0f * ((tmp_v[0] - L[0]) / box_length); // the socket position depends on proximity bus_v = stim::vec3(x0 - dx, main_feeder[0][1], tmp_v[2]); mid_v = stim::vec3(x0 - dx, tmp_v[1], tmp_v[2]); @@ -1486,11 +1489,11 @@ namespace stim { inlet.push_back(tmp_b); } - x0 = main_feeder[1][0] - 100.0f; + x0 = main_feeder[1][0] - 15.0f; for (unsigned i = 0; i < output.size(); i++) { tmp_v = V[output[i].first]; - dx = 200.0f * ((U[0] - tmp_v[0]) / box_length); // the socket position depends on proximity + dx = 30.0f * ((U[0] - tmp_v[0]) / box_length); // the socket position depends on proximity bus_v = stim::vec3(x0 + dx, main_feeder[1][1], tmp_v[2]); mid_v = stim::vec3(x0 + dx, tmp_v[1], tmp_v[2]); @@ -2196,7 +2199,7 @@ namespace stim { /// make binary image stack // prepare for image stack - void preparation(T &Xl, T &Xr, T &Yt, T &Yb, T &Z, T length = 210.0f, T height = 10.0f) { + void preparation(T &Xl, T &Xr, T &Yt, T &Yb, T &Z, T length = 40.0f, T height = 10.0f) { T max_radius = 0.0f; T top = FLT_MIN; diff --git a/main.cu b/main.cu index ca232f7..e8da3cd 100644 --- a/main.cu +++ b/main.cu @@ -46,7 +46,8 @@ float min_v; int mods; // special keyboard input std::vector color; // velocity color map std::vector velocity_bar; // velocity bar -float length = 210.0f; // cuboid length +float length = 40.0f; // cuboid length +float scale = 1.0f; // render scale factor // hard-coded parameters float camera_factor = 1.2f; // start point of the camera as a function of X and Y size @@ -74,8 +75,10 @@ bool render_direction = false; // flag indicates rendering flow direction for o bool simulation = false; // flag indicates simulation mode bool color_bound = false; // flag indicates velocity color map bound bool to_select_pressure = false; // flag indicates having selected a vertex to modify pressure +bool mark_index = true; // flag indicates marking the index near the vertex unsigned pressure_index; // the index of vertex that is clicked unsigned direction_index = -1; // the index of edge that is pointed at +unsigned index_index = -1; // the index of the vertex // build inlet/outlet parameters bool build_inlet_outlet = false; // flag indicates building inlets and outlets @@ -218,13 +221,14 @@ void glut_render() { } else { flow.bounding_box(); - flow.glSolidSphere(max_pressure, subdivision); - flow.mark_vertex(); + flow.glSolidSphere(max_pressure, scale, subdivision); + if (mark_index) + flow.mark_vertex(scale); //flow.glSolidCone(subdivision); - flow.glSolidCylinder(direction_index, color, subdivision); + flow.glSolidCylinder(direction_index, color, scale, subdivision); flow.glSolidCuboid(length); if (render_direction) - flow.glSolidCone(direction_index, subdivision); + flow.glSolidCone(direction_index, scale, subdivision); } if (build_inlet_outlet) { @@ -411,8 +415,13 @@ void glut_menu(int value) { manufacture = false; modified_bridge = false; connection_done = false; - if (!flow.set) + // first time + if (!flow.set) { flow_initialize(); + menu_option[0] = "resimulation"; + } + + // simulation / resimulation flow_stable_state(); // main function of solving the linear system flow.print_flow(); @@ -563,7 +572,7 @@ void glut_mouse(int button, int state, int x, int y) { GLdouble posX, posY, posZ; window_to_world(posX, posY, posZ); // get the world coordinates - bool flag = flow.epsilon_vertex((float)posX, (float)posY, (float)posZ, eps, pressure_index); + bool flag = flow.epsilon_vertex((float)posX, (float)posY, (float)posZ, eps, scale, pressure_index); if (flag) { std::vector::iterator it = std::find(pendant_vertex.begin(), pendant_vertex.end(), pressure_index); if (it != pendant_vertex.end()) // if it is dangle vertex @@ -576,8 +585,8 @@ void glut_mouse(int button, int state, int x, int y) { float tmp_pressure = (float)(vY - y - border_factor) / ((float)vY - border_factor) * max_pressure; flow.set_pressure(pressure_index, tmp_pressure); - flow_stable_state(); // main function of solving the linear system - flow.print_flow(); + //flow_stable_state(); // main function of solving the linear system + //flow.print_flow(); } } else if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN && !mods && modified_bridge && change_fragment) { @@ -720,6 +729,8 @@ void glut_mouse(int button, int state, int x, int y) { // define camera move based on mouse wheel move void glut_wheel(int wheel, int direction, int x, int y) { + mods = glutGetModifiers(); + mouse_x = x; mouse_y = y; @@ -727,7 +738,7 @@ void glut_wheel(int wheel, int direction, int x, int y) { window_to_world(posX, posY, posZ); // get the world coordinates if (!to_select_pressure) { - bool flag = flow.epsilon_vertex((float)posX, (float)posY, (float)posZ, eps, pressure_index); + bool flag = flow.epsilon_vertex((float)posX, (float)posY, (float)posZ, eps, scale, pressure_index); if (flag && simulation) { float tmp_r; if (direction > 0) { // increase radii @@ -741,10 +752,8 @@ void glut_wheel(int wheel, int direction, int x, int y) { tmp_r = default_radius; } flow.set_radius(pressure_index, tmp_r); - flow_stable_state(); - flow.print_flow(); } - else { + else if (!mods) { if (direction > 0) // if it is button 3(up), move closer move_pace = zoom_factor; else // if it is button 4(down), leave farther @@ -753,6 +762,24 @@ void glut_wheel(int wheel, int direction, int x, int y) { cam.Push(move_pace); } } + + // rescale + if (mods == GLUT_ACTIVE_CTRL) { + if (direction > 0) { + if (scale >= 1) + scale += 1.0f; + else + scale += 0.1f; + } + else { + if (scale > 1) + scale -= 1.0f; + else if (scale <= 1 && scale > 0.1f) + scale -= 0.1f; + else + scale = 1.0f; + } + } glutPostRedisplay(); } @@ -773,6 +800,14 @@ void glut_keyboard(unsigned char key, int x, int y) { cam.Push(move_pace); break; + // open/close index marks + case 'e': + if (mark_index) + mark_index = false; + else + mark_index = true; + break; + // output image stack case 'm': if (manufacture) { -- libgit2 0.21.4