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
29ExprGrapherWidget::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);
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
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
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
80 expr.setDesiredReturnType(SeExpr2::ExprType().FP(3));
81
82 view->update();
83}
84
86
87ExprGrapherView::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
100
101void 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
112void 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
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
131void 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}
143void ExprGrapherView::mouseReleaseEvent(QMouseEvent* event) {
144 if (event->button() == Qt::LeftButton) emit clicked();
145 scaling = translating = false;
146 setCursor(Qt::OpenHandCursor);
147}
148void 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);
171 update();
172 repaint();
173 }
174 event_oldx = x;
175 event_oldy = y;
176}
177
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
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}
ExprGrapherView(ExprGrapherWidget &widget, QWidget *parent, int width, int height)
void getWindow(float &xmin, float &xmax, float &ymin, float &ymax, float &z)
void scaleValueManipulated()
virtual ~ExprGrapherView()
void setWindow(float xmin, float xmax, float ymin, float ymax, float z)
void mouseReleaseEvent(QMouseEvent *event)
void mousePressEvent(QMouseEvent *event)
ExprGrapherWidget & widget
void mouseMoveEvent(QMouseEvent *event)
ExprGrapherView * view
BasicExpression expr
QLineEdit * scale
ExprGrapherWidget(QWidget *parent, int width, int height)
Vec< double, 3, false > Vec3d
Definition Vec.h:384
</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
< br > pow($a, 0.5)+ $b< br >< br ></div > External variables can also be overridden by local assignment. &nbsp
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
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
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
For any rgb or hsl value(except for negative s values)