Commit 9e60c6a754f8cefc11dfc2cb509b6274405c4f17
1 parent
8334680a
fixed minor bug in edge detection
Showing
2 changed files
with
328 additions
and
61 deletions
Show diff stats
... | ... | @@ -331,6 +331,11 @@ namespace stim { |
331 | 331 | return E[tmp_e].r(tmp_v); |
332 | 332 | } |
333 | 333 | |
334 | + // get the radius of index j of edge i | |
335 | + T get_radius(unsigned i, unsigned j) { | |
336 | + return E[i].r(j); | |
337 | + } | |
338 | + | |
334 | 339 | // get the velocity of pendant vertex i |
335 | 340 | T get_velocity(unsigned i) { |
336 | 341 | |
... | ... | @@ -495,6 +500,7 @@ namespace stim { |
495 | 500 | order = o; |
496 | 501 | } |
497 | 502 | |
503 | + // move hilbert curves | |
498 | 504 | void move(unsigned i, T *c, direction dir, T dl, int feeder, bool invert) { |
499 | 505 | |
500 | 506 | int cof = (invert) ? -1 : 1; |
... | ... | @@ -524,6 +530,7 @@ namespace stim { |
524 | 530 | outlet[i].V.push_back(tmp); |
525 | 531 | } |
526 | 532 | |
533 | + // form hilbert curves | |
527 | 534 | void hilbert_curve(unsigned i, T *c, int order, T dl, int feeder, bool invert, direction dir = DOWN) { |
528 | 535 | |
529 | 536 | if (order == 1) { |
... | ... | @@ -727,51 +734,84 @@ namespace stim { |
727 | 734 | |
728 | 735 | // waste? |
729 | 736 | for (unsigned i = 0; i < num_edge; i++) { |
730 | - for (unsigned j = 0; j < E[i].size(); j++) { | |
731 | - if (j == 0) { // for start vertex | |
732 | - if (P[E[i].v[0]] != 0) { | |
733 | - stim::vec3<float> new_color; | |
734 | - new_color[0] = (P[E[i].v[0]] / max_pressure) > 0.5f ? 1.0f : 2.0f * P[E[i].v[0]] / max_pressure; // red | |
735 | - new_color[1] = 0.0f; // green | |
736 | - 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 | |
737 | - glColor3f(new_color[0], new_color[1], new_color[2]); | |
738 | - } | |
739 | - } | |
740 | - else if (j == E[i].size() - 1) { // for end vertex | |
741 | - if (P[E[i].v[1]] != 0) { | |
742 | - stim::vec3<float> new_color; | |
743 | - new_color[0] = (P[E[i].v[1]] / max_pressure) > 0.5f ? 1.0f : 2.0f * P[E[i].v[1]] / max_pressure; // red | |
744 | - new_color[1] = 0.0f; // green | |
745 | - 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 | |
746 | - glColor3f(new_color[0], new_color[1], new_color[2]); | |
747 | - } | |
748 | - } | |
749 | - else | |
750 | - glColor3f(0.5f, 0.5f, 0.5f); // gray point | |
737 | + // draw the starting vertex | |
738 | + if (P[E[i].v[0]] != 0) { | |
739 | + stim::vec3<float> new_color; | |
740 | + new_color[0] = (P[E[i].v[0]] / max_pressure) > 0.5f ? 1.0f : 2.0f * P[E[i].v[0]] / max_pressure; // red | |
741 | + new_color[1] = 0.0f; // green | |
742 | + 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 | |
743 | + glColor3f(new_color[0], new_color[1], new_color[2]); | |
751 | 744 | |
752 | 745 | glPushMatrix(); |
753 | - glTranslatef(E[i][j][0], E[i][j][1], E[i][j][2]); | |
754 | - glutSolidSphere(get_r(i, j), subdivision, subdivision); | |
746 | + glTranslatef(E[i][0][0], E[i][0][1], E[i][0][2]); | |
747 | + glutSolidSphere(get_r(i, 0), subdivision, subdivision); | |
755 | 748 | glPopMatrix(); |
756 | 749 | } |
750 | + | |
751 | + // draw the ending vertex | |
752 | + if (P[E[i].v[1]] != 0) { | |
753 | + stim::vec3<float> new_color; | |
754 | + new_color[0] = (P[E[i].v[1]] / max_pressure) > 0.5f ? 1.0f : 2.0f * P[E[i].v[1]] / max_pressure; // red | |
755 | + new_color[1] = 0.0f; // green | |
756 | + 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 | |
757 | + glColor3f(new_color[0], new_color[1], new_color[2]); | |
758 | + | |
759 | + glPushMatrix(); | |
760 | + glTranslatef(E[i][E[i].size() - 1][0], E[i][E[i].size() - 1][1], E[i][E[i].size() - 1][2]); | |
761 | + glutSolidSphere(get_r(i, E[i].size() - 1), subdivision, subdivision); | |
762 | + glPopMatrix(); | |
763 | + } | |
764 | + //for (unsigned j = 0; j < E[i].size(); j++) { | |
765 | + // if (j == 0) { // for start vertex | |
766 | + // if (P[E[i].v[0]] != 0) { | |
767 | + // stim::vec3<float> new_color; | |
768 | + // new_color[0] = (P[E[i].v[0]] / max_pressure) > 0.5f ? 1.0f : 2.0f * P[E[i].v[0]] / max_pressure; // red | |
769 | + // new_color[1] = 0.0f; // green | |
770 | + // 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 | |
771 | + // glColor3f(new_color[0], new_color[1], new_color[2]); | |
772 | + // } | |
773 | + // } | |
774 | + // else if (j == E[i].size() - 1) { // for end vertex | |
775 | + // if (P[E[i].v[1]] != 0) { | |
776 | + // stim::vec3<float> new_color; | |
777 | + // new_color[0] = (P[E[i].v[1]] / max_pressure) > 0.5f ? 1.0f : 2.0f * P[E[i].v[1]] / max_pressure; // red | |
778 | + // new_color[1] = 0.0f; // green | |
779 | + // 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 | |
780 | + // glColor3f(new_color[0], new_color[1], new_color[2]); | |
781 | + // } | |
782 | + // } | |
783 | + // else | |
784 | + // glColor3f(0.5f, 0.5f, 0.5f); // gray point | |
785 | + | |
786 | + // glPushMatrix(); | |
787 | + // glTranslatef(E[i][j][0], E[i][j][1], E[i][j][2]); | |
788 | + // glutSolidSphere(get_r(i, j), subdivision, subdivision); | |
789 | + // glPopMatrix(); | |
790 | + //} | |
757 | 791 | } |
758 | 792 | } |
759 | 793 | |
760 | 794 | // draw edges as series of cylinders |
761 | - void glSolidCylinder(GLint subdivision, std::vector<unsigned char> color) { | |
795 | + void glSolidCylinder(unsigned index, std::vector<unsigned char> color, GLint subdivision) { | |
762 | 796 | |
763 | 797 | stim::vec3<float> tmp_d; |
764 | 798 | stim::vec3<float> center1; |
765 | 799 | stim::vec3<float> center2; |
800 | + stim::circle<float> tmp_c; | |
766 | 801 | float r1; |
767 | 802 | float r2; |
768 | 803 | std::vector<typename stim::vec3<float> > cp1(subdivision + 1); |
769 | 804 | std::vector<typename stim::vec3<float> > cp2(subdivision + 1); |
770 | 805 | for (unsigned i = 0; i < num_edge; i++) { // for every edge |
771 | - glEnable(GL_BLEND); // enable color blend | |
772 | - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // set blend function | |
773 | - glDisable(GL_DEPTH_TEST); | |
774 | - glColor4f((float)color[i * 3 + 0] / 255, (float)color[i * 3 + 1] / 255, (float)color[i * 3 + 2] / 255, 0.5f); | |
806 | + if (i == index) { // render in tranparency for direction indication | |
807 | + glEnable(GL_BLEND); // enable color blend | |
808 | + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // set blend function | |
809 | + glDisable(GL_DEPTH_TEST); | |
810 | + glColor4f((float)color[i * 3 + 0] / 255, (float)color[i * 3 + 1] / 255, (float)color[i * 3 + 2] / 255, 0.5f); | |
811 | + } | |
812 | + else | |
813 | + glColor3f((float)color[i * 3 + 0] / 255, (float)color[i * 3 + 1] / 255, (float)color[i * 3 + 2] / 255); | |
814 | + | |
775 | 815 | for (unsigned j = 0; j < E[i].size() - 1; j++) { // for every point on the edge |
776 | 816 | center1 = E[i][j]; |
777 | 817 | center2 = E[i][j + 1]; |
... | ... | @@ -779,8 +819,48 @@ namespace stim { |
779 | 819 | r1 = get_r(i, j); |
780 | 820 | r2 = get_r(i, j + 1); |
781 | 821 | |
782 | - // calculate the envelope caps | |
783 | - find_envelope(cp1, cp2, center1, center2, r1, r2, subdivision); | |
822 | + //// calculate the envelope caps | |
823 | + //find_envelope(cp1, cp2, center1, center2, r1, r2, subdivision); | |
824 | + if (j == 0) { | |
825 | + if (E[i].size() == 2) | |
826 | + find_envelope(cp1, cp2, center1, center2, r1, r2, subdivision); | |
827 | + else { | |
828 | + tmp_d = center2 - center1; | |
829 | + tmp_d = tmp_d.norm(); | |
830 | + tmp_c.rotate(tmp_d); | |
831 | + stim::circle<float> c1(center1, r1, tmp_d, tmp_c.U); | |
832 | + cp1 = c1.glpoints(subdivision); | |
833 | + tmp_d = (E[i][j + 2] - center2) + (center2 - center1); | |
834 | + tmp_d = tmp_d.norm(); | |
835 | + tmp_c.rotate(tmp_d); | |
836 | + stim::circle<float> c2(center2, r2, tmp_d, tmp_c.U); | |
837 | + cp2 = c2.glpoints(subdivision); | |
838 | + } | |
839 | + } | |
840 | + else if (j == E[i].size() - 2) { | |
841 | + tmp_d = (center2 - center1) + (center1 - E[i][j - 1]); | |
842 | + tmp_d = tmp_d.norm(); | |
843 | + tmp_c.rotate(tmp_d); | |
844 | + stim::circle<float> c1(center1, r1, tmp_d, tmp_c.U); | |
845 | + cp1 = c1.glpoints(subdivision); | |
846 | + tmp_d = center2 - center1; | |
847 | + tmp_d = tmp_d.norm(); | |
848 | + tmp_c.rotate(tmp_d); | |
849 | + stim::circle<float> c2(center2, r2, tmp_d, tmp_c.U); | |
850 | + cp2 = c2.glpoints(subdivision); | |
851 | + } | |
852 | + else { | |
853 | + tmp_d = (center2 - center1) + (center1 - E[i][j - 1]); | |
854 | + tmp_d = tmp_d.norm(); | |
855 | + tmp_c.rotate(tmp_d); | |
856 | + stim::circle<float> c1(center1, r1, tmp_d, tmp_c.U); | |
857 | + cp1 = c1.glpoints(subdivision); | |
858 | + tmp_d = (E[i][j + 2] - center2) + (center2 - center1); | |
859 | + tmp_d = tmp_d.norm(); | |
860 | + tmp_c.rotate(tmp_d); | |
861 | + stim::circle<float> c2(center2, r2, tmp_d, tmp_c.U); | |
862 | + cp2 = c2.glpoints(subdivision); | |
863 | + } | |
784 | 864 | |
785 | 865 | glBegin(GL_QUAD_STRIP); |
786 | 866 | for (unsigned j = 0; j < cp1.size(); j++) { |
... | ... | @@ -789,12 +869,71 @@ namespace stim { |
789 | 869 | } |
790 | 870 | glEnd(); |
791 | 871 | } |
872 | + if (i == index) { | |
873 | + glDisable(GL_BLEND); | |
874 | + glEnable(GL_DEPTH_TEST); | |
875 | + } | |
876 | + | |
792 | 877 | } |
793 | 878 | glFlush(); |
794 | - glDisable(GL_BLEND); | |
795 | 879 | } |
796 | 880 | |
797 | 881 | // draw the flow direction as cone |
882 | + void glSolidCone(unsigned i, GLint subdivision) { | |
883 | + | |
884 | + stim::vec3<T> tmp_d; // direction | |
885 | + stim::vec3<T> center; // cone hat center | |
886 | + stim::vec3<T> head; // cone hat top | |
887 | + stim::circle<T> tmp_c; | |
888 | + std::vector<typename stim::vec3<T> > cp; | |
889 | + T radius; | |
890 | + | |
891 | + glColor3f(0.0f, 0.0f, 0.0f); | |
892 | + | |
893 | + unsigned index = E[i].size() / 2 - 1; | |
894 | + tmp_d = E[i][index + 1] - E[i][index]; | |
895 | + tmp_d = tmp_d.norm(); | |
896 | + center = (E[i][index + 1] + E[i][index]) / 2; | |
897 | + tmp_c.rotate(tmp_d); | |
898 | + radius = (E[i].r(index + 1) + E[i].r(index)) / 2; | |
899 | + if (v[i] > 0) | |
900 | + head = center + tmp_d * 2 * sqrt(3) * radius; | |
901 | + else | |
902 | + head = center - tmp_d * 2 * sqrt(3) * radius; | |
903 | + | |
904 | + stim::circle<float> c(center, radius, tmp_d, tmp_c.U); | |
905 | + cp = c.glpoints(subdivision); | |
906 | + | |
907 | + glBegin(GL_TRIANGLE_FAN); | |
908 | + glVertex3f(head[0], head[1], head[2]); | |
909 | + for (unsigned k = 0; k < cp.size(); k++) | |
910 | + glVertex3f(cp[k][0], cp[k][1], cp[k][2]); | |
911 | + glEnd(); | |
912 | + glFlush(); | |
913 | + | |
914 | + // draw a cone for every edge to indicate | |
915 | + //for (unsigned j = 0; j < E[i].size() - 1; j++) { // for every point on current edge | |
916 | + // tmp_d = E[i][j + 1] - E[i][j]; | |
917 | + // tmp_d = tmp_d.norm(); | |
918 | + // center = (E[i][j + 1] + E[i][j]) / 2; | |
919 | + // tmp_c.rotate(tmp_d); | |
920 | + // radius = (E[i].r(j + 1) + E[i].r(j)) / 2; | |
921 | + // if (v[i] > 0) // if flow flows from j to j+1 | |
922 | + // head = center + tmp_d * 2 * sqrt(3) * radius; | |
923 | + // else | |
924 | + // head = center - tmp_d * 2 * sqrt(3) * radius; | |
925 | + | |
926 | + // stim::circle<float> c(center, radius, tmp_d, tmp_c.U); | |
927 | + // cp = c.glpoints(subdivision); | |
928 | + | |
929 | + // glBegin(GL_TRIANGLE_FAN); | |
930 | + // glVertex3f(head[0], head[1], head[2]); | |
931 | + // for (unsigned k = 0; k < cp.size(); k++) | |
932 | + // glVertex3f(cp[k][0], cp[k][1], cp[k][2]); | |
933 | + // glEnd(); | |
934 | + //} | |
935 | + //glFlush(); | |
936 | + } | |
798 | 937 | void glSolidCone(GLint subdivision) { |
799 | 938 | |
800 | 939 | stim::vec3<T> tmp_d; // direction |
... | ... | @@ -805,27 +944,48 @@ namespace stim { |
805 | 944 | T radius; |
806 | 945 | |
807 | 946 | glColor3f(0.0f, 0.0f, 0.0f); |
947 | + // draw a cone for every edge to indicate | |
808 | 948 | for (unsigned i = 0; i < num_edge; i++) { // for every edge |
809 | - for (unsigned j = 0; j < E[i].size() - 1; j++) { // for every point on current edge | |
810 | - tmp_d = E[i][j + 1] - E[i][j]; | |
811 | - tmp_d = tmp_d.norm(); | |
812 | - center = (E[i][j + 1] + E[i][j]) / 2; | |
813 | - tmp_c.rotate(tmp_d); | |
814 | - radius = (E[i].r(j + 1) + E[i].r(j)) / 2; | |
815 | - if (v[i] > 0) // if flow flows from j to j+1 | |
816 | - head = center + tmp_d * 2 * sqrt(3) * radius; | |
817 | - else | |
818 | - head = center - tmp_d * 2 * sqrt(3) * radius; | |
819 | - | |
820 | - stim::circle<float> c(center, radius, tmp_d, tmp_c.U); | |
821 | - cp = c.glpoints(subdivision); | |
949 | + unsigned k1 = E[i].size() / 2 - 1; // start and end index | |
950 | + unsigned k2 = E[i].size() / 2; | |
951 | + tmp_d = E[i][k2] - E[i][k1]; | |
952 | + tmp_d = tmp_d.norm(); | |
953 | + center = (E[i][k2] + E[i][k1]) / 2; | |
954 | + tmp_c.rotate(tmp_d); | |
955 | + radius = (E[i].r(k2) + E[i].r(k1)) / 2; | |
956 | + if (v[i] > 0) // if flow flows from k1 to k2 | |
957 | + head = center + tmp_d * 2 * sqrt(3) * radius; | |
958 | + else | |
959 | + head = center - tmp_d * 2 * sqrt(3) * radius; | |
960 | + stim::circle<float> c(center, radius, tmp_d, tmp_c.U); | |
961 | + cp = c.glpoints(subdivision); | |
962 | + | |
963 | + glBegin(GL_TRIANGLE_FAN); | |
964 | + glVertex3f(head[0], head[1], head[2]); | |
965 | + for (unsigned k = 0; k < cp.size(); k++) | |
966 | + glVertex3f(cp[k][0], cp[k][1], cp[k][2]); | |
967 | + glEnd(); | |
822 | 968 | |
823 | - glBegin(GL_TRIANGLE_FAN); | |
824 | - glVertex3f(head[0], head[1], head[2]); | |
825 | - for (unsigned k = 0; k < cp.size(); k++) | |
826 | - glVertex3f(cp[k][0], cp[k][1], cp[k][2]); | |
827 | - glEnd(); | |
828 | - } | |
969 | + //for (unsigned j = 0; j < E[i].size() - 1; j++) { // for every point on current edge | |
970 | + // tmp_d = E[i][j + 1] - E[i][j]; | |
971 | + // tmp_d = tmp_d.norm(); | |
972 | + // center = (E[i][j + 1] + E[i][j]) / 2; | |
973 | + // tmp_c.rotate(tmp_d); | |
974 | + // radius = (E[i].r(j + 1) + E[i].r(j)) / 2; | |
975 | + // if (v[i] > 0) // if flow flows from j to j+1 | |
976 | + // head = center + tmp_d * 2 * sqrt(3) * radius; | |
977 | + // else | |
978 | + // head = center - tmp_d * 2 * sqrt(3) * radius; | |
979 | + | |
980 | + // stim::circle<float> c(center, radius, tmp_d, tmp_c.U); | |
981 | + // cp = c.glpoints(subdivision); | |
982 | + | |
983 | + // glBegin(GL_TRIANGLE_FAN); | |
984 | + // glVertex3f(head[0], head[1], head[2]); | |
985 | + // for (unsigned k = 0; k < cp.size(); k++) | |
986 | + // glVertex3f(cp[k][0], cp[k][1], cp[k][2]); | |
987 | + // glEnd(); | |
988 | + //} | |
829 | 989 | } |
830 | 990 | glFlush(); |
831 | 991 | } |
... | ... | @@ -1054,14 +1214,14 @@ namespace stim { |
1054 | 1214 | // return true and a value if found |
1055 | 1215 | inline bool epsilon_vertex(T x, T y, T z, T eps, unsigned& v) { |
1056 | 1216 | |
1057 | - float d = FLT_MAX; // minimum distance between 2 vertices | |
1058 | - float tmp_d = 0.0f; // temporary stores distance for loop | |
1217 | + T d = FLT_MAX; // minimum distance between 2 vertices | |
1218 | + T tmp_d = 0.0f; // temporary stores distance for loop | |
1059 | 1219 | unsigned tmp_i = 0; // temporary stores connection index for loop |
1060 | - stim::vec3<float> tmp_v; // temporary stores current loop point | |
1220 | + stim::vec3<T> tmp_v; // temporary stores current loop point | |
1061 | 1221 | d = FLT_MAX; // set to max of float number |
1062 | 1222 | |
1063 | 1223 | for (unsigned i = 0; i < V.size(); i++) { |
1064 | - tmp_v = stim::vec3<float>(x, y, z); | |
1224 | + tmp_v = stim::vec3<T>(x, y, z); | |
1065 | 1225 | |
1066 | 1226 | tmp_v = tmp_v - V[i]; // calculate a vector between two vertices |
1067 | 1227 | tmp_d = tmp_v.len(); // calculate length of that vector |
... | ... | @@ -1079,6 +1239,61 @@ namespace stim { |
1079 | 1239 | return false; |
1080 | 1240 | } |
1081 | 1241 | |
1242 | + // find the nearest inlet/outlet connection line of current click position | |
1243 | + // ab -> line segment, v -> point | |
1244 | + // return true and a value if found | |
1245 | + inline bool epsilon_edge(T x, T y, T z, T eps, unsigned &idx) { | |
1246 | + | |
1247 | + T d = FLT_MAX; | |
1248 | + T tmp_d; | |
1249 | + unsigned tmp_i = 0; | |
1250 | + unsigned tmp_j = 0; | |
1251 | + stim::vec3<T> v1; | |
1252 | + stim::vec3<T> v2; | |
1253 | + stim::vec3<T> v3; | |
1254 | + stim::vec3<T> v0 = stim::vec3<float>(x, y, z); | |
1255 | + bool online = false; // flag indicates the point is on the line-segment | |
1256 | + float a, b; | |
1257 | + | |
1258 | + for (unsigned i = 0; i < E.size(); i++) { | |
1259 | + for (unsigned j = 0; j < E[i].size() - 1; j++) { | |
1260 | + v1 = E[i][j + 1] - E[i][j]; // a -> b = ab | |
1261 | + v2 = v0 - E[i][j]; // a -> v = av | |
1262 | + v3 = v0 - E[i][j + 1]; // b -> v = bv | |
1263 | + | |
1264 | + tmp_d = v2.dot(v1); // avยทab | |
1265 | + | |
1266 | + // check the line relative position | |
1267 | + a = v2.dot(v1.norm()); | |
1268 | + b = v3.dot(v1.norm()); | |
1269 | + if (a < v1.len() && b < v1.len()) // if the length of projection fragment is longer than the line-segment | |
1270 | + online = true; | |
1271 | + else | |
1272 | + online = false; | |
1273 | + | |
1274 | + if (tmp_d <= 0.0 || tmp_d > std::pow(v1.len(), 2) && !online) // projection lies outside the line-segment | |
1275 | + continue; | |
1276 | + else { | |
1277 | + tmp_d = v1.cross(v2).len() / v1.len(); // perpendicular distance of point to segment: |v1 x v2| / |v1| | |
1278 | + if (tmp_d < d) { | |
1279 | + d = tmp_d; | |
1280 | + tmp_i = i; | |
1281 | + tmp_j = j; | |
1282 | + } | |
1283 | + } | |
1284 | + } | |
1285 | + } | |
1286 | + | |
1287 | + eps += get_radius(tmp_i, tmp_j); | |
1288 | + | |
1289 | + if (d < eps) { | |
1290 | + idx = tmp_i; | |
1291 | + return true; | |
1292 | + } | |
1293 | + | |
1294 | + return false; | |
1295 | + } | |
1296 | + | |
1082 | 1297 | /// build main feeder connection |
1083 | 1298 | // set up main feeder and main port of both input and output |
1084 | 1299 | void set_main_feeder(T border = 400.0f) { | ... | ... |
main.cu
... | ... | @@ -54,7 +54,7 @@ float zoom_factor = 10.0f; // zooming factor |
54 | 54 | float border_factor = 20.0f; // border |
55 | 55 | float radii_factor = 1.0f; // radii changing factor |
56 | 56 | GLint subdivision = 20; // slices and stacks |
57 | -float default_radius = 5.0f; // default radii of network vertex | |
57 | +float default_radius = 5.0f; // default radii of network vertex | |
58 | 58 | float delta = 0.01f; // small discrepancy |
59 | 59 | float eps = 20.0f; // epsilon threshold |
60 | 60 | float max_pressure = 0.0f; // maximum pressure that the channel can bear |
... | ... | @@ -67,10 +67,12 @@ int mouse_y; // window y-coordinate |
67 | 67 | bool LTbutton = false; // true means down while false means up |
68 | 68 | |
69 | 69 | // simulation parameters |
70 | +bool render_direction = false; // flag indicates rendering flow direction for one edge | |
70 | 71 | bool simulation = false; // flag indicates simulation mode |
71 | 72 | bool color_bound = false; // flag indicates velocity color map bound |
72 | 73 | bool to_select_pressure = false; // flag indicates having selected a vertex to modify pressure |
73 | 74 | unsigned pressure_index; // the index of vertex that is clicked |
75 | +unsigned direction_index = -1; // the index of edge that is pointed at | |
74 | 76 | |
75 | 77 | // build inlet/outlet parameters |
76 | 78 | bool build_inlet_outlet = false; // flag indicates building inlets and outlets |
... | ... | @@ -92,8 +94,11 @@ inline void get_background() { |
92 | 94 | |
93 | 95 | // set the initial radii |
94 | 96 | flow.init(num_edge, num_vertex); // initialize flow object |
95 | - for (unsigned i = 0; i < num_edge; i++) | |
96 | - flow.set_r(i, default_radius); | |
97 | + | |
98 | + // if no radius information laoded | |
99 | + if (!flow.get_radius(0, 0)) | |
100 | + for (unsigned i = 0; i < num_edge; i++) | |
101 | + flow.set_r(i, default_radius); | |
97 | 102 | } |
98 | 103 | |
99 | 104 | // convert from window coordinates to world coordinates |
... | ... | @@ -197,15 +202,18 @@ void glut_render() { |
197 | 202 | glut_modelview(); |
198 | 203 | |
199 | 204 | if (!simulation && !build_inlet_outlet || manufacture) { |
205 | + glColor3f(0.0f, 0.0f, 0.0f); | |
200 | 206 | flow.glCylinder0(); |
201 | 207 | } |
202 | 208 | else { |
203 | 209 | flow.bounding_box(); |
204 | 210 | flow.glSolidSphere(max_pressure, subdivision); |
205 | 211 | flow.mark_vertex(); |
206 | - flow.glSolidCone(subdivision); | |
207 | - flow.glSolidCylinder(subdivision, color); | |
212 | + //flow.glSolidCone(subdivision); | |
213 | + flow.glSolidCylinder(direction_index, color, subdivision); | |
208 | 214 | flow.glSolidCuboid(); |
215 | + if (render_direction) | |
216 | + flow.glSolidCone(direction_index, subdivision); | |
209 | 217 | } |
210 | 218 | |
211 | 219 | if (build_inlet_outlet) { |
... | ... | @@ -217,7 +225,6 @@ void glut_render() { |
217 | 225 | flow.tube_bridge(subdivision); |
218 | 226 | } |
219 | 227 | |
220 | - | |
221 | 228 | // render bars |
222 | 229 | // bring up a pressure bar on left |
223 | 230 | if (to_select_pressure) { |
... | ... | @@ -416,6 +423,31 @@ void glut_motion(int x, int y) { |
416 | 423 | glutPostRedisplay(); // re-draw the visualization |
417 | 424 | } |
418 | 425 | |
426 | +// defines passive mouse motion function | |
427 | +void glut_passive_motion(int x, int y) { | |
428 | + | |
429 | + mouse_x = x; | |
430 | + mouse_y = y; | |
431 | + | |
432 | + // check whether the mouse point near to an edge | |
433 | + GLdouble posX, posY, posZ; | |
434 | + window_to_world(posX, posY, posZ); // get the world coordinates | |
435 | + | |
436 | + if (simulation || build_inlet_outlet) { | |
437 | + bool flag = flow.epsilon_edge((float)posX, (float)posY, (float)posZ, eps, direction_index); | |
438 | + if (flag) | |
439 | + render_direction = true; | |
440 | + else { | |
441 | + if (render_direction) // if the direction is displaying currently, do a short delay | |
442 | + Sleep(1000); | |
443 | + render_direction = false; | |
444 | + direction_index = -1; | |
445 | + } | |
446 | + } | |
447 | + | |
448 | + glutPostRedisplay(); // re-draw the visualization | |
449 | +} | |
450 | + | |
419 | 451 | // get click window coordinates |
420 | 452 | void glut_mouse(int button, int state, int x, int y) { |
421 | 453 | |
... | ... | @@ -552,6 +584,7 @@ void glut_initialize() { |
552 | 584 | glutDisplayFunc(glut_render); |
553 | 585 | glutMouseFunc(glut_mouse); |
554 | 586 | glutMotionFunc(glut_motion); |
587 | + glutPassiveMotionFunc(glut_passive_motion); | |
555 | 588 | glutMouseWheelFunc(glut_wheel); |
556 | 589 | glutKeyboardFunc(glut_keyboard); |
557 | 590 | |
... | ... | @@ -565,6 +598,20 @@ void glut_initialize() { |
565 | 598 | cam.LookAt(c[0], c[1], c[2]); |
566 | 599 | } |
567 | 600 | |
601 | +// output an advertisement for the lab, authors and usage information | |
602 | +void advertise() { | |
603 | + std::cout << std::endl << std::endl; | |
604 | + std::cout << " =======================================================================================" << std::endl; | |
605 | + std::cout << "|Thank you for using the synthetic microvascular model generator for microfluidics tool!|" << std::endl; | |
606 | + std::cout << "|Scalable Tissue Imaging and Modeling (STIM) Lab, University of Houston |" << std::endl; | |
607 | + std::cout << "|Developers: Jiaming Guo, David Mayerich |" << std::endl; | |
608 | + std::cout << "|Source: https://git.stim.ee.uh.edu/Jack/flow3.git |" << std::endl; | |
609 | + std::cout << " =======================================================================================" << std::endl << std::endl; | |
610 | + | |
611 | + std::cout << args.str(); | |
612 | +} | |
613 | + | |
614 | +// main function: parse arguments and initialize GLUT | |
568 | 615 | int main(int argc, char* argv[]) { |
569 | 616 | |
570 | 617 | // add arguments |
... | ... | @@ -573,12 +620,17 @@ int main(int argc, char* argv[]) { |
573 | 620 | args.add("maxpress", "maximum allowed pressure in g / units / s^2, default 2 is for blood when units = um", "2", "real value > 0"); |
574 | 621 | args.add("viscosity", "set the viscosity of the fluid (in g / units / s), default .00001 is for blood when units = um", ".00001", "real value > 0"); |
575 | 622 | args.add("rou", "set the desity of the fluid (in g / units^3), default 1.06*10^-12 is for blood when units = um", ".00000000000106", "real value > 0"); |
576 | - args.add("hilbert", "enable hilbert curves connections", "0", "value 1 for enablement"); | |
623 | + args.add("hilbert", "activate hilbert curves connections", "0", "value 1 for enablement"); | |
577 | 624 | args.add("stackres", "spacing between pixel samples in each dimension(in units/pixel)", "1 1 1", "real value > 0"); |
578 | 625 | args.add("stackdir", "set the directory of the output image stack", "", "any existing directory (ex. /home/name/network)"); |
579 | 626 | |
580 | 627 | args.parse(argc, argv); // parse the command line |
581 | 628 | |
629 | + if (args["help"].is_set()) { | |
630 | + advertise(); | |
631 | + std::exit(1); | |
632 | + } | |
633 | + | |
582 | 634 | // load network |
583 | 635 | if (args["network"].is_set()) { // load network from user |
584 | 636 | std::vector<std::string> tmp = stim::parser::split(args["network"].as_string(), '.'); | ... | ... |