view.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. #include "qt/input/view.hpp"
  2. QtInputView::QtInputView(QtInputData* m){
  3. data=m;
  4. selected=p_none;
  5. status=Other;
  6. }
  7. void
  8. QtInputView::initializeGL(){
  9. glClearColor(1,1,1,1);
  10. glEnable(GL_DEPTH_TEST);
  11. glEnable(GL_LIGHT0);
  12. glEnable(GL_LIGHTING);
  13. glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
  14. glEnable(GL_COLOR_MATERIAL);
  15. }
  16. void
  17. QtInputView::resizeGL(int w,int h){
  18. glViewport(0,0,w,h);
  19. glMatrixMode(GL_PROJECTION);
  20. glLoadIdentity();
  21. gluOrtho2D(0,1,0,1);
  22. glMatrixMode(GL_MODELVIEW);
  23. glLoadIdentity();
  24. }
  25. void
  26. QtInputView::paintGL(){
  27. if(status==Geom or status==Init){
  28. glBegin(GL_QUADS);
  29. double xs=double(pointSize)/width();
  30. double ys=double(pointSize)/height();
  31. glColor3f(0,0,0);
  32. size_t imin=(status==Geom)?0:2*QtInputData::np;
  33. size_t imax=(status==Geom)?2*QtInputData::np:3*QtInputData::np;
  34. for(size_t i=imin;i<imax;++i){
  35. Point& P=data->point[i];
  36. double x=P.x;
  37. double y=P.y;
  38. glVertex3f(x-xs,y-ys,1);
  39. glVertex3f(x+xs,y-ys,1);
  40. glVertex3f(x+xs,y+ys,1);
  41. glVertex3f(x-xs,y+ys,1);
  42. }
  43. if(status==Init){
  44. glColor3f(0.3,0.3,1);
  45. for(size_t i=3*QtInputData::np;i<3*QtInputData::np+QtInputData::np_ov;++i){
  46. Point& P=data->point[i];
  47. double x=P.x;
  48. double y=P.y;
  49. glVertex3f(x-xs,y-ys,1);
  50. glVertex3f(x+xs,y-ys,1);
  51. glVertex3f(x+xs,y+ys,1);
  52. glVertex3f(x-xs,y+ys,1);
  53. }
  54. }
  55. glEnd();
  56. }
  57. for(auto it=data->initial_state->tanks.begin();it!=data->initial_state->tanks.end();++it){
  58. paintTank(*it);
  59. }
  60. for(auto it=data->source.pumps.begin();it!=data->source.pumps.end();++it){
  61. paintPump(*it);
  62. }
  63. for(auto it=data->source.clouds.begin();it!=data->source.clouds.end();++it){
  64. paintCloud(*it);
  65. }
  66. glColor3f(0.6,0.6,0.6);
  67. drawSpline(data->spline_bot);
  68. glColor3f(0.6,0.3,0);
  69. drawSpline(data->spline_soil);
  70. glColor3f(0,1,1);
  71. drawSpline(data->spline_sat);
  72. Geometry& G=data->geometry;
  73. glBegin(GL_TRIANGLES);
  74. for(size_t i=0;i<G.nX-1;++i){
  75. size_t max_left=G.nZ[i];
  76. size_t max_right=G.nZ[i+1];
  77. size_t left=0;
  78. size_t right=0;
  79. while(left<max_left-1 and right<max_right-1){
  80. if(G.Z[i][left+1]<G.Z[i+1][right+1]){
  81. drawTriangle(i,left,i+1,right,i,left+1);
  82. ++left;
  83. }
  84. else{
  85. drawTriangle(i,left,i+1,right,i+1,right+1);
  86. ++right;
  87. }
  88. }
  89. if(left==max_left-1){
  90. while(right<max_right-1){
  91. drawTriangle(i,left,i+1,right,i+1,right+1);
  92. ++right;
  93. }
  94. }
  95. if(right==max_right-1){
  96. while(left<max_left-1){
  97. drawTriangle(i,left,i+1,right,i,left+1);
  98. ++left;
  99. }
  100. }
  101. }
  102. glEnd();
  103. drawOverland();
  104. }
  105. void
  106. QtInputView::paintTank(Tank* tank){
  107. double factor_inv=1.0/data->factor;
  108. double l=tank->left;
  109. double r=tank->right;
  110. double b=tank->bottom*factor_inv;
  111. double t=tank->top*factor_inv;
  112. glLineWidth(2);
  113. glColor3f(1,0,1);
  114. glBegin(GL_LINE_LOOP);
  115. glVertex2f(l,b);
  116. glVertex2f(r,b);
  117. glVertex2f(r,t);
  118. glVertex2f(l,t);
  119. glEnd();
  120. }
  121. void
  122. QtInputView::paintPump(Pump* pump){
  123. double factor_inv=1.0/data->factor;
  124. double a=pump->get_amplitude(time);
  125. if(a==0) return;
  126. double l=pump->get_left(time);
  127. double r=pump->get_right(time);
  128. double b=pump->get_bottom(time)*factor_inv;
  129. double t=pump->get_top(time)*factor_inv;
  130. double dl=pump->get_left_delta(time);
  131. double dr=pump->get_right_delta(time);
  132. double db=pump->get_bottom_delta(time)*factor_inv;
  133. double dt=pump->get_top_delta(time)*factor_inv;
  134. glLineWidth(2);
  135. if(a>0) glColor3f(0,0.6,1);
  136. else glColor3f(1,0.2,0);
  137. glLineStipple(3, 0xAAAA);
  138. glBegin(GL_LINE_LOOP);
  139. glVertex2f(l,b);
  140. glVertex2f(r,b);
  141. glVertex2f(r,t);
  142. glVertex2f(l,t);
  143. glEnd();
  144. glLineWidth(1);
  145. glEnable(GL_LINE_STIPPLE);
  146. glBegin(GL_LINE_LOOP);
  147. glVertex2f(l-dl,b-db);
  148. glVertex2f(r+dr,b-db);
  149. glVertex2f(r+dr,t+dt);
  150. glVertex2f(l-dl,t+dt);
  151. glEnd();
  152. glDisable(GL_LINE_STIPPLE);
  153. }
  154. void
  155. QtInputView::paintCloud(Cloud* cloud){
  156. double a=cloud->get_amplitude(time);
  157. double amax=cloud->get_amplitude_max();
  158. if(a==0) return;
  159. double l=cloud->get_left(time);
  160. double r=cloud->get_right(time);
  161. double dl=cloud->get_left_delta(time);
  162. double dr=cloud->get_right_delta(time);
  163. double middle=0.97;
  164. double thick=0.03*a/amax;
  165. double top=middle+thick;
  166. double bottom=middle-thick;
  167. glLineWidth(1);
  168. glColor3f(0.5,0.5,0.5);
  169. glLineWidth(1);
  170. glBegin(GL_POLYGON);
  171. glVertex2f(l-dl,middle);
  172. glVertex2f(l,top);
  173. glVertex2f(r,top);
  174. glVertex2f(r+dr,middle);
  175. glVertex2f(r,bottom);
  176. glVertex2f(l,bottom);
  177. glEnd();
  178. }
  179. void
  180. QtInputView::setColor(size_t ix,size_t iz){
  181. double p=getP(ix,iz);
  182. double s=Physics::s(p);
  183. double r=(1-s);
  184. double g=0.7*(1-s);
  185. double b=0.8*s+0.4*(1-s);
  186. glColor3f(r,g,b);
  187. }
  188. void
  189. QtInputView::drawTriangle(size_t ix1,size_t iz1,size_t ix2,size_t iz2,size_t ix3,size_t iz3){
  190. Geometry& G=data->geometry;
  191. double factor_inv=1/data->factor;
  192. double dX=1/double(G.nX-1);
  193. double x1=ix1*dX;
  194. double x2=ix2*dX;
  195. double x3=ix3*dX;
  196. double y1=G.Z[ix1][iz1]*factor_inv;
  197. double y2=G.Z[ix2][iz2]*factor_inv;
  198. double y3=G.Z[ix3][iz3]*factor_inv;
  199. setColor(ix1,iz1);
  200. glVertex3f(x1,y1,0);
  201. setColor(ix2,iz2);
  202. glVertex3f(x2,y2,0);
  203. setColor(ix3,iz3);
  204. glVertex3f(x3,y3,0);
  205. }
  206. void
  207. QtInputView::drawOverland(){
  208. Geometry& G=data->geometry;
  209. double dX=1/double(G.nX-1);
  210. double factor_inv=1/data->factor;
  211. glColor3f(0.5,0.5,1);
  212. glBegin(GL_QUADS);
  213. for(size_t i=0;i<G.nX-1;++i){
  214. glVertex3f(i*dX,G.hsoil[i]*factor_inv,0);
  215. glVertex3f(i*dX,data->initial_state->hov[i]*factor_inv,0);
  216. glVertex3f(i*dX+dX,data->initial_state->hov[i+1]*factor_inv,0);
  217. glVertex3f(i*dX+dX,G.hsoil[i+1]*factor_inv,0);
  218. }
  219. glEnd();
  220. }
  221. void
  222. QtInputView::mousePressEvent(QMouseEvent* event){
  223. if(status==Geom or status==Init){
  224. size_t p=findPoint(event->x(),height()-event->y());
  225. if(status==Geom){
  226. selected=(p<2*QtInputData::np)?p:p_none;
  227. }
  228. else{
  229. selected=(p>=2*QtInputData::np)?p:p_none;
  230. }
  231. }
  232. }
  233. void
  234. QtInputView::mouseMoveEvent(QMouseEvent* event){
  235. if(selected!=p_none){
  236. double mx=double(event->x())/width();
  237. double my=1-double(event->y())/height();
  238. moveSelected(mx,my);
  239. }
  240. }
  241. size_t
  242. QtInputView::findPoint(int x,int y){
  243. double w=width();
  244. double h=height();
  245. for(size_t i=0;i<3*QtInputData::np+QtInputData::np_ov;++i){
  246. int px=data->point[i].x*w;
  247. int py=data->point[i].y*h;
  248. if(abs(x-px)<pointSize and abs(y-py)<pointSize) return i;
  249. }
  250. return p_none;
  251. }
  252. void
  253. QtInputView::drawSpline(Spline& S){
  254. double w=width();
  255. glLineWidth(3);
  256. glBegin(GL_LINE_STRIP);
  257. for(int i=0;i<=w;i+=2){
  258. double x=i/w;
  259. glVertex2f(x,S(x));
  260. }
  261. glEnd();
  262. }
  263. void
  264. QtInputView::moveSelected(double x,double y){
  265. double xp=data->point[selected].x;
  266. double yp=data->point[selected].y;
  267. if((selected%QtInputData::np)!=0 and (selected%QtInputData::np)!=QtInputData::np-1){
  268. float xmin=data->point[selected-1].x+min_d;
  269. float xmax=data->point[selected+1].x-min_d;
  270. if(xmin<=x and x<=xmax){
  271. data->point[selected].x=x;
  272. }
  273. }
  274. if(0<=y and y<=1){
  275. data->point[selected].y=y;
  276. }
  277. if(selected<QtInputData::np) data->updateSplineBot();
  278. else if(selected<2*QtInputData::np) data->updateSplineSoil();
  279. else if(selected<3*QtInputData::np) data->updateSplineSat();
  280. else data->updateOverland();
  281. if(selected<2*QtInputData::np){
  282. double w=width();
  283. bool ok=true;
  284. for(int i=0;i<=w;++i){
  285. double x=i/w;
  286. double ybot=data->evalSplineBot(x);
  287. double ysoil=data->evalSplineSoil(x);
  288. if(ybot<min_d or ybot>1-min_d or ysoil<min_d or ysoil>1-min_d or ybot>ysoil-min_d){
  289. data->point[selected].x=xp;
  290. data->point[selected].y=yp;
  291. if(selected<QtInputData::np) data->updateSplineBot();
  292. else data->updateSplineSoil();
  293. update();
  294. return;
  295. }
  296. }
  297. }
  298. update();
  299. }
  300. void
  301. QtInputView::mouseReleaseEvent(QMouseEvent* event){
  302. if(selected<3*QtInputData::np) emit geometryChanged();
  303. }