123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- #include "qt/input/view.hpp"
- QtInputView::QtInputView(QtInputData* m){
- data=m;
- selected=p_none;
- status=Other;
- }
- void
- QtInputView::initializeGL(){
- glClearColor(1,1,1,1);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHT0);
- glEnable(GL_LIGHTING);
- glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
- glEnable(GL_COLOR_MATERIAL);
- }
- void
- QtInputView::resizeGL(int w,int h){
- glViewport(0,0,w,h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluOrtho2D(0,1,0,1);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- }
- void
- QtInputView::paintGL(){
- if(status==Geom or status==Init){
- glBegin(GL_QUADS);
- double xs=double(pointSize)/width();
- double ys=double(pointSize)/height();
- glColor3f(0,0,0);
- size_t imin=(status==Geom)?0:2*QtInputData::np;
- size_t imax=(status==Geom)?2*QtInputData::np:3*QtInputData::np;
- for(size_t i=imin;i<imax;++i){
- Point& P=data->point[i];
- double x=P.x;
- double y=P.y;
- glVertex3f(x-xs,y-ys,1);
- glVertex3f(x+xs,y-ys,1);
- glVertex3f(x+xs,y+ys,1);
- glVertex3f(x-xs,y+ys,1);
- }
- if(status==Init){
- glColor3f(0.3,0.3,1);
- for(size_t i=3*QtInputData::np;i<3*QtInputData::np+QtInputData::np_ov;++i){
- Point& P=data->point[i];
- double x=P.x;
- double y=P.y;
- glVertex3f(x-xs,y-ys,1);
- glVertex3f(x+xs,y-ys,1);
- glVertex3f(x+xs,y+ys,1);
- glVertex3f(x-xs,y+ys,1);
- }
- }
- glEnd();
- }
- for(auto it=data->initial_state->tanks.begin();it!=data->initial_state->tanks.end();++it){
- paintTank(*it);
- }
- for(auto it=data->source.pumps.begin();it!=data->source.pumps.end();++it){
- paintPump(*it);
- }
- for(auto it=data->source.clouds.begin();it!=data->source.clouds.end();++it){
- paintCloud(*it);
- }
- glColor3f(0.6,0.6,0.6);
- drawSpline(data->spline_bot);
- glColor3f(0.6,0.3,0);
- drawSpline(data->spline_soil);
- glColor3f(0,1,1);
- drawSpline(data->spline_sat);
- Geometry& G=data->geometry;
- glBegin(GL_TRIANGLES);
- for(size_t i=0;i<G.nX-1;++i){
- size_t max_left=G.nZ[i];
- size_t max_right=G.nZ[i+1];
- size_t left=0;
- size_t right=0;
- while(left<max_left-1 and right<max_right-1){
- if(G.Z[i][left+1]<G.Z[i+1][right+1]){
- drawTriangle(i,left,i+1,right,i,left+1);
- ++left;
- }
- else{
- drawTriangle(i,left,i+1,right,i+1,right+1);
- ++right;
- }
- }
- if(left==max_left-1){
- while(right<max_right-1){
- drawTriangle(i,left,i+1,right,i+1,right+1);
- ++right;
- }
- }
- if(right==max_right-1){
- while(left<max_left-1){
- drawTriangle(i,left,i+1,right,i,left+1);
- ++left;
- }
- }
- }
- glEnd();
- drawOverland();
- }
- void
- QtInputView::paintTank(Tank* tank){
- double factor_inv=1.0/data->factor;
- double l=tank->left;
- double r=tank->right;
- double b=tank->bottom*factor_inv;
- double t=tank->top*factor_inv;
- glLineWidth(2);
- glColor3f(1,0,1);
- glBegin(GL_LINE_LOOP);
- glVertex2f(l,b);
- glVertex2f(r,b);
- glVertex2f(r,t);
- glVertex2f(l,t);
- glEnd();
- }
- void
- QtInputView::paintPump(Pump* pump){
- double factor_inv=1.0/data->factor;
- double a=pump->get_amplitude(time);
- if(a==0) return;
- double l=pump->get_left(time);
- double r=pump->get_right(time);
- double b=pump->get_bottom(time)*factor_inv;
- double t=pump->get_top(time)*factor_inv;
- double dl=pump->get_left_delta(time);
- double dr=pump->get_right_delta(time);
- double db=pump->get_bottom_delta(time)*factor_inv;
- double dt=pump->get_top_delta(time)*factor_inv;
- glLineWidth(2);
- if(a>0) glColor3f(0,0.6,1);
- else glColor3f(1,0.2,0);
- glLineStipple(3, 0xAAAA);
- glBegin(GL_LINE_LOOP);
- glVertex2f(l,b);
- glVertex2f(r,b);
- glVertex2f(r,t);
- glVertex2f(l,t);
- glEnd();
- glLineWidth(1);
- glEnable(GL_LINE_STIPPLE);
- glBegin(GL_LINE_LOOP);
- glVertex2f(l-dl,b-db);
- glVertex2f(r+dr,b-db);
- glVertex2f(r+dr,t+dt);
- glVertex2f(l-dl,t+dt);
- glEnd();
- glDisable(GL_LINE_STIPPLE);
- }
- void
- QtInputView::paintCloud(Cloud* cloud){
- double a=cloud->get_amplitude(time);
- double amax=cloud->get_amplitude_max();
- if(a==0) return;
- double l=cloud->get_left(time);
- double r=cloud->get_right(time);
- double dl=cloud->get_left_delta(time);
- double dr=cloud->get_right_delta(time);
- double middle=0.97;
- double thick=0.03*a/amax;
- double top=middle+thick;
- double bottom=middle-thick;
- glLineWidth(1);
- glColor3f(0.5,0.5,0.5);
- glLineWidth(1);
- glBegin(GL_POLYGON);
- glVertex2f(l-dl,middle);
- glVertex2f(l,top);
- glVertex2f(r,top);
- glVertex2f(r+dr,middle);
- glVertex2f(r,bottom);
- glVertex2f(l,bottom);
- glEnd();
- }
- void
- QtInputView::setColor(size_t ix,size_t iz){
- double p=getP(ix,iz);
- double s=Physics::s(p);
- double r=(1-s);
- double g=0.7*(1-s);
- double b=0.8*s+0.4*(1-s);
- glColor3f(r,g,b);
- }
- void
- QtInputView::drawTriangle(size_t ix1,size_t iz1,size_t ix2,size_t iz2,size_t ix3,size_t iz3){
- Geometry& G=data->geometry;
- double factor_inv=1/data->factor;
- double dX=1/double(G.nX-1);
- double x1=ix1*dX;
- double x2=ix2*dX;
- double x3=ix3*dX;
- double y1=G.Z[ix1][iz1]*factor_inv;
- double y2=G.Z[ix2][iz2]*factor_inv;
- double y3=G.Z[ix3][iz3]*factor_inv;
- setColor(ix1,iz1);
- glVertex3f(x1,y1,0);
- setColor(ix2,iz2);
- glVertex3f(x2,y2,0);
- setColor(ix3,iz3);
- glVertex3f(x3,y3,0);
- }
- void
- QtInputView::drawOverland(){
- Geometry& G=data->geometry;
- double dX=1/double(G.nX-1);
- double factor_inv=1/data->factor;
- glColor3f(0.5,0.5,1);
- glBegin(GL_QUADS);
- for(size_t i=0;i<G.nX-1;++i){
- glVertex3f(i*dX,G.hsoil[i]*factor_inv,0);
- glVertex3f(i*dX,data->initial_state->hov[i]*factor_inv,0);
- glVertex3f(i*dX+dX,data->initial_state->hov[i+1]*factor_inv,0);
- glVertex3f(i*dX+dX,G.hsoil[i+1]*factor_inv,0);
- }
- glEnd();
- }
- void
- QtInputView::mousePressEvent(QMouseEvent* event){
- if(status==Geom or status==Init){
- size_t p=findPoint(event->x(),height()-event->y());
- if(status==Geom){
- selected=(p<2*QtInputData::np)?p:p_none;
- }
- else{
- selected=(p>=2*QtInputData::np)?p:p_none;
- }
- }
- }
- void
- QtInputView::mouseMoveEvent(QMouseEvent* event){
- if(selected!=p_none){
- double mx=double(event->x())/width();
- double my=1-double(event->y())/height();
- moveSelected(mx,my);
- }
- }
- size_t
- QtInputView::findPoint(int x,int y){
- double w=width();
- double h=height();
- for(size_t i=0;i<3*QtInputData::np+QtInputData::np_ov;++i){
- int px=data->point[i].x*w;
- int py=data->point[i].y*h;
- if(abs(x-px)<pointSize and abs(y-py)<pointSize) return i;
- }
- return p_none;
- }
- void
- QtInputView::drawSpline(Spline& S){
- double w=width();
- glLineWidth(3);
- glBegin(GL_LINE_STRIP);
- for(int i=0;i<=w;i+=2){
- double x=i/w;
- glVertex2f(x,S(x));
- }
- glEnd();
- }
- void
- QtInputView::moveSelected(double x,double y){
- double xp=data->point[selected].x;
- double yp=data->point[selected].y;
- if((selected%QtInputData::np)!=0 and (selected%QtInputData::np)!=QtInputData::np-1){
- float xmin=data->point[selected-1].x+min_d;
- float xmax=data->point[selected+1].x-min_d;
- if(xmin<=x and x<=xmax){
- data->point[selected].x=x;
- }
- }
- if(0<=y and y<=1){
- data->point[selected].y=y;
- }
- if(selected<QtInputData::np) data->updateSplineBot();
- else if(selected<2*QtInputData::np) data->updateSplineSoil();
- else if(selected<3*QtInputData::np) data->updateSplineSat();
- else data->updateOverland();
- if(selected<2*QtInputData::np){
- double w=width();
- bool ok=true;
- for(int i=0;i<=w;++i){
- double x=i/w;
- double ybot=data->evalSplineBot(x);
- double ysoil=data->evalSplineSoil(x);
- if(ybot<min_d or ybot>1-min_d or ysoil<min_d or ysoil>1-min_d or ybot>ysoil-min_d){
- data->point[selected].x=xp;
- data->point[selected].y=yp;
- if(selected<QtInputData::np) data->updateSplineBot();
- else data->updateSplineSoil();
- update();
- return;
- }
- }
- }
- update();
- }
- void
- QtInputView::mouseReleaseEvent(QMouseEvent* event){
- if(selected<3*QtInputData::np) emit geometryChanged();
- }
|