00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "SeExprEdGrapher2d.h"
00016 #include <QtGui/QGridLayout>
00017 #include <QtGui/QLineEdit>
00018 #include <QtGui/QDoubleValidator>
00019 #include <QtGui/QHBoxLayout>
00020 #include <QtGui/QLabel>
00021
00022
00023 SeExprEdGrapherWidget::SeExprEdGrapherWidget(QWidget* parent,int width,int height)
00024 :view(new SeExprEdGrapherView(*this,this,width,height)),expr("",false)
00025 {
00026 Q_UNUSED(parent);
00027 setFixedSize(width, height+30);
00028 QVBoxLayout* vbox=new QVBoxLayout;
00029 vbox->setMargin(0);
00030 setLayout(vbox);
00031 vbox->addWidget(view,0,Qt::AlignLeft | Qt::AlignTop);
00032 QHBoxLayout* hbox=new QHBoxLayout;
00033 vbox->addLayout(hbox);
00034 hbox->setMargin(0);
00035
00036 float xmin,xmax,ymin,ymax,z;
00037 view->getWindow(xmin,xmax,ymin,ymax,z);
00038 scale=new QLineEdit();
00039 QDoubleValidator *valValidator = new QDoubleValidator(0.0,10000000.0,6,scale);
00040 scale->setValidator(valValidator);
00041 scale->setValidator(valValidator);
00042 scaleValueManipulated();
00043
00044
00045 connect(scale, SIGNAL(returnPressed()), this, SLOT(scaleValueEdited()));
00046 connect(view, SIGNAL(scaleValueManipulated()), this, SLOT(scaleValueManipulated()));
00047 connect(view, SIGNAL(clicked()), this, SLOT(forwardPreview()));
00048
00049 hbox->addWidget(new QLabel("Width"),0);
00050 hbox->addWidget(scale,0);
00051 }
00052
00053 void SeExprEdGrapherWidget::scaleValueEdited()
00054 {
00055 float xmin,xmax,ymin,ymax,z;
00056 view->getWindow(xmin,xmax,ymin,ymax,z);
00057 float xdiff=xmax-xmin,ydiff=ymax-ymin;
00058 float xcenter=.5*(xmax+xmin),ycenter=.5*(ymin+ymax);
00059 float newScale=atof(scale->text().toStdString().c_str());
00060
00061 float aspect=ydiff/xdiff;
00062
00063 xmin=xcenter-newScale;
00064 xmax=xcenter+newScale;
00065 ymin=ycenter-aspect*newScale;
00066 ymax=ycenter+aspect*newScale;
00067 view->setWindow(xmin,xmax,ymin,ymax,z);
00068 }
00069
00070 void SeExprEdGrapherWidget::scaleValueManipulated()
00071 {
00072 float xmin,xmax,ymin,ymax,z;
00073 view->getWindow(xmin,xmax,ymin,ymax,z);
00074 scale->setText(QString("%1").arg(.5*(xmax-xmin)));
00075 }
00076
00077 void SeExprEdGrapherWidget::update()
00078 {
00079 expr.setWantVec(true);
00080
00081 view->update();
00082 }
00083
00084 void SeExprEdGrapherWidget::forwardPreview()
00085 {
00086 emit preview();
00087 }
00088
00089
00090 SeExprEdGrapherView::SeExprEdGrapherView(SeExprEdGrapherWidget& widget,QWidget* parent, int width, int height)
00091 : QGLWidget(parent), widget(widget), _image(NULL), _width(width), _height(height),
00092 scaling(false),translating(false)
00093 {
00094 this->setFixedSize(width, height);
00095
00096 _image = new float[3*_width*_height];
00097 setWindow(-1,1,-1,1,0);
00098 clear();
00099
00100 setCursor(Qt::OpenHandCursor);
00101
00102 }
00103
00104 SeExprEdGrapherView::~SeExprEdGrapherView()
00105 {
00106 delete [] _image;
00107 }
00108
00109 void SeExprEdGrapherView::setWindow(float xmin,float xmax,float ymin,float ymax,float z)
00110 {
00111 this->z=z;
00112 this->xmin=xmin;
00113 this->xmax=xmax;
00114 this->ymin=ymin;
00115 this->ymax=ymax;
00116
00117 dx=(xmax-xmin)/_width;
00118 dy=(ymax-ymin)/_height;
00119 }
00120
00121 void SeExprEdGrapherView::getWindow(float& xmin,float& xmax,float& ymin,float& ymax,float& z)
00122 {
00123 z=this->z;
00124 xmin=this->xmin;
00125 xmax=this->xmax;
00126 ymin=this->ymin;
00127 ymax=this->ymax;
00128 }
00129
00130 void SeExprEdGrapherView::clear()
00131 {
00132 for (int row = 0; row < _height; ++row) {
00133 for (int col = 0; col < _width; ++col) {
00134 int index = 3*row*_width + 3*col;
00135 _image[index] = 1.0f;
00136 _image[index+1] = 0.0f;
00137 _image[index+2] = 0.0f;
00138 }
00139 }
00140 }
00141
00142 void SeExprEdGrapherView::mousePressEvent(QMouseEvent* event)
00143 {
00144 if(event->button()==Qt::MidButton){
00145 setCursor(Qt::ClosedHandCursor);
00146 translating=true;
00147 }
00148 if(event->button()==Qt::RightButton){
00149 setCursor(Qt::SizeAllCursor);
00150 scaling=true;
00151 }
00152 event_oldx=event->x();
00153 event_oldy=event->y();
00154
00155 }
00156 void SeExprEdGrapherView::mouseReleaseEvent(QMouseEvent* event)
00157 {
00158 if(event->button()==Qt::LeftButton)
00159 emit clicked();
00160 scaling=translating=false;
00161 setCursor(Qt::OpenHandCursor);
00162 }
00163 void SeExprEdGrapherView::mouseMoveEvent(QMouseEvent* event)
00164 {
00165 int x=event->x(),y=event->y();
00166 float offsetx=dx*(x-event_oldx);
00167 float offsety=-dy*(y-event_oldy);
00168
00169 if(translating){
00170 xmin-=offsetx;
00171 xmax-=offsetx;
00172 ymin-=offsety;
00173 ymax-=offsety;
00174 update();
00175 repaint();
00176 }else if(scaling){
00177 float offset=(fabs(offsetx)>fabs(offsety))?offsetx:offsety;
00178
00179 float width=.5*(xmax-xmin),height=.5*(ymax-ymin);
00180 float xcenter=.5*(xmin+xmax),ycenter=.5*(ymin+ymax);
00181 float scale_factor=pow(10.,-offset/(xmax-xmin));
00182 width*=scale_factor;
00183 height*=scale_factor;
00184 setWindow(xcenter-width,xcenter+width,ycenter-height,ycenter+height,z);
00185 emit scaleValueManipulated();
00186 update();
00187 repaint();
00188 }
00189 event_oldx=x;
00190 event_oldy=y;
00191 }
00192
00193
00194 void SeExprEdGrapherView::update()
00195 {
00196
00197 if (!widget.expr.isValid()) {
00198 clear();
00199 updateGL();
00200 return;
00201 }
00202
00203
00204 float dv = 1.0f / _height;
00205 float du = 1.0f / _width;
00206
00207 float y=.5*dy+ymin;
00208 float v=.5*dv;
00209 int index=0;
00210 for(int row=0;row<_height;row++,y+=dy,v+=dv){
00211 float x=.5*dx+xmin;
00212 float u=.5*du;
00213 widget.expr.v.value=v;
00214 for(int col=0;col<_width;col++,x+=dy,u+=du){
00215 widget.expr.u.value=u;
00216 widget.expr.P.value=SeVec3d(x,y,z);
00217 double* value=widget.expr.evaluate();
00218 _image[index] = value[0];
00219 _image[index+1] = value[1];
00220 _image[index+2] = value[2];
00221 index+=3;
00222 }
00223 }
00224
00225 updateGL();
00226 }
00227
00228 void SeExprEdGrapherView::paintGL()
00229 {
00230 glMatrixMode(GL_PROJECTION);
00231 glLoadIdentity();
00232 glOrtho(0.0f, (GLfloat)_width, 0.0, (GLfloat)_height, -1.0, 1.0);
00233 glMatrixMode(GL_MODELVIEW);
00234 glLoadIdentity();
00235
00236 glDisable(GL_DEPTH_TEST);
00237 glDepthFunc(0);
00238 glClearColor(1,0,0,1);
00239 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
00240
00241 glRasterPos2i(0,0);
00242 glDrawPixels(_width, _height, GL_RGB, GL_FLOAT, _image);
00243
00244 }
00245