SeExpr

ExprGrapher2d.cpp
Go to the documentation of this file.
1 /*
2 * Copyright Disney Enterprises, Inc. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License
6 * and the following modification to it: Section 6 Trademarks.
7 * deleted and replaced with:
8 *
9 * 6. Trademarks. This License does not grant permission to use the
10 * trade names, trademarks, service marks, or product names of the
11 * Licensor and its affiliates, except as required for reproducing
12 * the content of the NOTICE file.
13 *
14 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * @file ExprGrapher2d.cpp
18 * @brief A 2d image graph view for expression editing previewing
19 * @author jlacewel
20 */
21
22 #include "ExprGrapher2d.h"
23 #include <QGridLayout>
24 #include <QLineEdit>
25 #include <QDoubleValidator>
26 #include <QHBoxLayout>
27 #include <QLabel>
28
29 ExprGrapherWidget::ExprGrapherWidget(QWidget* parent, int width, int height)
30 : view(new ExprGrapherView(*this, this, width, height)), expr("", SeExpr2::ExprType().FP(1)) {
31 Q_UNUSED(parent);
32 setFixedSize(width, height + 30);
33 QVBoxLayout* vbox = new QVBoxLayout;
34 vbox->setMargin(0);
35 setLayout(vbox);
36 vbox->addWidget(view, 0, Qt::AlignLeft | Qt::AlignTop);
37 QHBoxLayout* hbox = new QHBoxLayout;
38 vbox->addLayout(hbox);
39 hbox->setMargin(0);
40
41 float xmin, xmax, ymin, ymax, z;
42 view->getWindow(xmin, xmax, ymin, ymax, z);
43 scale = new QLineEdit();
44 QDoubleValidator* valValidator = new QDoubleValidator(0.0, 10000000.0, 6, scale);
45 scale->setValidator(valValidator);
46 scale->setValidator(valValidator);
47 scaleValueManipulated();
48
49 connect(scale, SIGNAL(returnPressed()), this, SLOT(scaleValueEdited()));
50 connect(view, SIGNAL(scaleValueManipulated()), this, SLOT(scaleValueManipulated()));
51 connect(view, SIGNAL(clicked()), this, SLOT(forwardPreview()));
52
53 hbox->addWidget(new QLabel("Width"), 0);
54 hbox->addWidget(scale, 0);
55 }
56
57 void ExprGrapherWidget::scaleValueEdited() {
58 float xmin, xmax, ymin, ymax, z;
59 view->getWindow(xmin, xmax, ymin, ymax, z);
60 float xdiff = xmax - xmin, ydiff = ymax - ymin;
61 float xcenter = .5 * (xmax + xmin), ycenter = .5 * (ymin + ymax);
62 float newScale = atof(scale->text().toStdString().c_str());
63
64 float aspect = ydiff / xdiff;
65
66 xmin = xcenter - newScale;
67 xmax = xcenter + newScale;
68 ymin = ycenter - aspect * newScale;
69 ymax = ycenter + aspect * newScale;
70 view->setWindow(xmin, xmax, ymin, ymax, z);
71 }
72
73 void ExprGrapherWidget::scaleValueManipulated() {
74 float xmin, xmax, ymin, ymax, z;
75 view->getWindow(xmin, xmax, ymin, ymax, z);
76 scale->setText(QString("%1").arg(.5 * (xmax - xmin)));
77 }
78
79 void ExprGrapherWidget::update() {
80 expr.setDesiredReturnType(SeExpr2::ExprType().FP(3));
81
82 view->update();
83 }
84
85 void ExprGrapherWidget::forwardPreview() { emit preview(); }
86
87 ExprGrapherView::ExprGrapherView(ExprGrapherWidget& widget, QWidget* parent, int width, int height)
88 : QGLWidget(parent), widget(widget), _image(NULL), _width(width), _height(height), scaling(false),
89 translating(false) {
90 this->setFixedSize(width, height);
91
92 _image = new float[3 * _width * _height];
93 setWindow(-1, 1, -1, 1, 0);
94 clear();
95
96 setCursor(Qt::OpenHandCursor);
97 }
98
99 ExprGrapherView::~ExprGrapherView() { delete[] _image; }
100
101 void ExprGrapherView::setWindow(float xmin, float xmax, float ymin, float ymax, float z) {
102 this->z = z;
103 this->xmin = xmin;
104 this->xmax = xmax;
105 this->ymin = ymin;
106 this->ymax = ymax;
107
108 dx = (xmax - xmin) / _width;
109 dy = (ymax - ymin) / _height;
110 }
111
112 void ExprGrapherView::getWindow(float& xmin, float& xmax, float& ymin, float& ymax, float& z) {
113 z = this->z;
114 xmin = this->xmin;
115 xmax = this->xmax;
116 ymin = this->ymin;
117 ymax = this->ymax;
118 }
119
120 void ExprGrapherView::clear() {
121 for (int row = 0; row < _height; ++row) {
122 for (int col = 0; col < _width; ++col) {
123 int index = 3 * row * _width + 3 * col;
124 _image[index] = 1.0f;
125 _image[index + 1] = 0.0f;
126 _image[index + 2] = 0.0f;
127 }
128 }
129 }
130
131 void ExprGrapherView::mousePressEvent(QMouseEvent* event) {
132 if (event->button() == Qt::MidButton) {
133 setCursor(Qt::ClosedHandCursor);
134 translating = true;
135 }
136 if (event->button() == Qt::RightButton) {
137 setCursor(Qt::SizeAllCursor);
138 scaling = true;
139 }
140 event_oldx = event->x();
141 event_oldy = event->y();
142 }
143 void ExprGrapherView::mouseReleaseEvent(QMouseEvent* event) {
144 if (event->button() == Qt::LeftButton) emit clicked();
145 scaling = translating = false;
146 setCursor(Qt::OpenHandCursor);
147 }
148 void ExprGrapherView::mouseMoveEvent(QMouseEvent* event) {
149 int x = event->x(), y = event->y();
150 float offsetx = dx * (x - event_oldx);
151 float offsety = -dy * (y - event_oldy);
152
153 if (translating) {
154 xmin -= offsetx;
155 xmax -= offsetx;
156 ymin -= offsety;
157 ymax -= offsety;
158 update();
159 repaint();
160 } else if (scaling) {
161 float offset = (fabs(offsetx) > fabs(offsety)) ? offsetx : offsety;
162
163 float width = .5 * (xmax - xmin), height = .5 * (ymax - ymin);
164 float xcenter = .5 * (xmin + xmax), ycenter = .5 * (ymin + ymax);
165 // Use float args for pow() to fix Windows compile error
166 float scale_factor = pow(10.f, -offset / (xmax - xmin));
167 width *= scale_factor;
168 height *= scale_factor;
169 setWindow(xcenter - width, xcenter + width, ycenter - height, ycenter + height, z);
170 emit scaleValueManipulated();
171 update();
172 repaint();
173 }
174 event_oldx = x;
175 event_oldy = y;
176 }
177
178 void ExprGrapherView::update() {
179
180 if (!widget.expr.isValid()) {
181 clear();
182 updateGL();
183 return;
184 }
185
186 float dv = 1.0f / _height;
187 float du = 1.0f / _width;
188
189 float y = .5 * dy + ymin;
190 float v = .5 * dv;
191 int index = 0;
192 for (int row = 0; row < _height; row++, y += dy, v += dv) {
193 float x = .5 * dx + xmin;
194 float u = .5 * du;
195 widget.expr.v.value = v;
196 for (int col = 0; col < _width; col++, x += dy, u += du) {
197 widget.expr.u.value = u;
198 widget.expr.P.value = SeExpr2::Vec3d(x, y, z);
199 const double* value = widget.expr.evalFP();
200 _image[index] = value[0];
201 _image[index + 1] = value[1];
202 _image[index + 2] = value[2];
203 index += 3;
204 }
205 }
206
207 updateGL();
208 }
209
210 void ExprGrapherView::paintGL() {
211 glMatrixMode(GL_PROJECTION);
212 glLoadIdentity();
213 glOrtho(0.0f, (GLfloat)_width, 0.0, (GLfloat)_height, -1.0, 1.0);
214 glMatrixMode(GL_MODELVIEW);
215 glLoadIdentity();
216
217 glDisable(GL_DEPTH_TEST);
218 glDepthFunc(0);
219 glClearColor(1, 0, 0, 1);
220 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
221
222 glRasterPos2i(0, 0);
223 glDrawPixels(_width, _height, GL_RGB, GL_FLOAT, _image);
224 }
ExprGrapherWidget::expr
BasicExpression expr
Definition: ExprGrapher2d.h:75
SeExpr2::Expression::isValid
bool isValid() const
Definition: Expression.h:133
index
The result is computed int int< br >< div style="margin-left: 40px;"> Picks values randomly between loRange and hiRange based on supplied index(which is automatically hashed). &nbsp
f
with numParticles numAttributes A variable block contains variable names and types but doesn t care what the values are< pre > void f(const std::string &s, MyParticleData *p, int outputDim=3)
Definition: varblocks.txt:35
ExprGrapherView::ExprGrapherView
ExprGrapherView(ExprGrapherWidget &widget, QWidget *parent, int width, int height)
Definition: ExprGrapher2d.cpp:87
ExprGrapherView::clicked
void clicked()
ExprGrapherView::dy
float dy
Definition: ExprGrapher2d.h:64
ExprGrapherWidget::scaleValueEdited
void scaleValueEdited()
Definition: ExprGrapher2d.cpp:57
ExprGrapherView::translating
bool translating
Definition: ExprGrapher2d.h:66
ExprGrapherWidget
Definition: ExprGrapher2d.h:69
ExprGrapherView::paintGL
void paintGL()
Definition: ExprGrapher2d.cpp:210
ExprGrapherView::widget
ExprGrapherWidget & widget
Definition: ExprGrapher2d.h:35
ExprGrapherWidget::scale
QLineEdit * scale
Definition: ExprGrapher2d.h:71
ExprGrapherWidget::update
void update()
Definition: ExprGrapher2d.cpp:79
ExprGrapherWidget::ExprGrapherWidget
ExprGrapherWidget(QWidget *parent, int width, int height)
Definition: ExprGrapher2d.cpp:29
ExprGrapherView::clear
void clear()
Definition: ExprGrapher2d.cpp:120
ExprGrapherView::_width
int _width
Definition: ExprGrapher2d.h:60
ExprGrapherView::event_oldx
int event_oldx
Definition: ExprGrapher2d.h:52
SeExpr2::ExprType
Definition: ExprType.h:39
ExprGrapherView::dx
float dx
Definition: ExprGrapher2d.h:64
ExprGrapherView::mouseReleaseEvent
void mouseReleaseEvent(QMouseEvent *event)
Definition: ExprGrapher2d.cpp:143
y
This is the same as the prman cellnoise function< br ></div >< br > float< b > float y< br > float< b > float y
Definition: userdoc.txt:218
BasicExpression::VectorRef::value
SeExpr2::Vec3d value
Definition: BasicExpression.h:40
ExprGrapherView::_image
float * _image
Definition: ExprGrapher2d.h:59
ExprGrapherView::z
float z
Definition: ExprGrapher2d.h:63
SeExpr2
Definition: Context.h:22
BasicExpression::ScalarRef::value
double value
Definition: BasicExpression.h:33
ExprGrapherView::scaling
bool scaling
Definition: ExprGrapher2d.h:66
ExprGrapherView::_height
int _height
Definition: ExprGrapher2d.h:61
ExprGrapherWidget::preview
void preview()
BasicExpression::P
VectorRef P
Definition: BasicExpression.h:77
ExprGrapherView::ymax
float ymax
Definition: ExprGrapher2d.h:63
ExprGrapherView::xmax
float xmax
Definition: ExprGrapher2d.h:63
ExprGrapherWidget::forwardPreview
void forwardPreview()
Definition: ExprGrapher2d.cpp:85
value
For any rgb or hsl value(except for negative s values)
ExprGrapherWidget::view
ExprGrapherView * view
Definition: ExprGrapher2d.h:74
ExprGrapherView
Definition: ExprGrapher2d.h:34
ExprGrapherView::xmin
float xmin
Definition: ExprGrapher2d.h:63
ExprGrapherView::event_oldy
int event_oldy
Definition: ExprGrapher2d.h:52
SeExpr2::Vec3d
Vec< double, 3, false > Vec3d
Definition: Vec.h:384
ExprGrapherView::~ExprGrapherView
virtual ~ExprGrapherView()
Definition: ExprGrapher2d.cpp:99
SeExpr2::Expression::setDesiredReturnType
void setDesiredReturnType(const ExprType &type)
Definition: Expression.cpp:159
ExprGrapher2d.h
BasicExpression::v
ScalarRef v
Definition: BasicExpression.h:76
ExprGrapherView::update
void update()
Definition: ExprGrapher2d.cpp:178
ExprGrapherView::setWindow
void setWindow(float xmin, float xmax, float ymin, float ymax, float z)
Definition: ExprGrapher2d.cpp:101
ExprGrapherView::ymin
float ymin
Definition: ExprGrapher2d.h:63
SeExpr2::Expression::evalFP
const double * evalFP(VarBlock *varBlock=nullptr) const
Definition: Expression.cpp:304
BasicExpression::u
ScalarRef u
Definition: BasicExpression.h:75
ExprGrapherView::mousePressEvent
void mousePressEvent(QMouseEvent *event)
Definition: ExprGrapher2d.cpp:131
ExprGrapherView::getWindow
void getWindow(float &xmin, float &xmax, float &ymin, float &ymax, float &z)
Definition: ExprGrapher2d.cpp:112
ExprGrapherWidget::scaleValueManipulated
void scaleValueManipulated()
Definition: ExprGrapher2d.cpp:73
ExprGrapherView::scaleValueManipulated
void scaleValueManipulated()
z
This is the same as the prman cellnoise function< br ></div >< br > float< b > float y< br > float< b > float float z
Definition: userdoc.txt:218
expr
</pre >< h3 > Binding our variable reference</h3 > If we now tried to use the variable would still not be found by our expressions To make it bindable we need to override the resolveVar() function as follows</pre >< h3 > Variable setting</h3 > Next we need to make a way of setting the variable As the controlling code will use the expression it will repeatedly alternate between setting the independent variables that are used and calling evaluate(). What it has to do depends very much on the application. In this case we only need to set the independent variable x as</pre >< h2 > Evaluating expressions</h2 > Evaluating an expression is pretty easy But before we can do that we need to make an instance< pre > GrapherExpr expr("x+x^2")
x
</pre >< h3 > A simple variable reference</h3 > This is not a very interesting subclass of expression until we add some additional variables Variables on some applications may be very dynamic In this we only need x
Definition: tutorial.txt:108
pow
< br > pow($a, 0.5)+ $b< br >< br ></div > External variables can also be overridden by local assignment. &nbsp
ExprGrapherView::mouseMoveEvent
void mouseMoveEvent(QMouseEvent *event)
Definition: ExprGrapher2d.cpp:148