SeExpr

imageSynthForPaint3d.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 */
20 #include <map>
21 #include <cstdlib>
22 #include <cstdio>
23 #include <cstring>
24 #include <png.h>
25 #include <fstream>
26
27 #include <SeExpr2/Expression.h>
28 #include <SeExpr2/Vec.h>
29 #include <SeExpr2/Interpreter.h>
30 #include <SeExpr2/ExprFunc.h>
31 #include <SeExpr2/ExprFuncX.h>
32 #include <SeExpr2/Platform.h>
33
34 namespace SeExpr2 {
35 class RandFuncX : public ExprFuncSimple {
36
37 struct Data : public ExprFuncNode::Data {
38 std::vector<std::pair<int, int> > ranges;
39 std::string format;
40 };
41
42 virtual ExprType prep(ExprFuncNode* node, bool wantScalar, ExprVarEnvBuilder& envBuilder) const {
43 bool valid = true;
44 for (int i = 0; i < node->numChildren(); i++)
45 valid &= node->checkArg(i, ExprType().FP(1).Varying(), envBuilder);
46 return valid ? ExprType().FP(1).Varying() : ExprType().Error();
47 }
48
49 virtual ExprFuncNode::Data* evalConstant(const ExprFuncNode* node, ArgHandle args) const { return new Data; }
50
51 virtual void eval(ArgHandle args) {
52 if (args.nargs() >= 2) {
53 args.outFp = (args.inFp<1>(0)[0] - args.inFp<1>(1)[0]) / 2.0;
54 } else
55 args.outFp = 0.5;
56 }
57
58 public:
59 RandFuncX() : ExprFuncSimple(true) {} // Thread Safe
60 virtual ~RandFuncX() {}
61 } rand;
62
63 // map(string name, [float format-arg], [float u], [float v], [int channel])
64 class MapFuncX : public ExprFuncSimple {
65 struct Data : public ExprFuncNode::Data {
66 std::vector<std::pair<int, int> > ranges;
67 std::string format;
68 };
69
70 virtual ExprType prep(ExprFuncNode* node, bool wantScalar, ExprVarEnvBuilder& envBuilder) const {
71 bool valid = true;
72 valid &= node->checkArg(0, ExprType().String().Constant(), envBuilder);
73 for (int i = 1; i < node->numChildren(); i++)
74 valid &= node->checkArg(i, ExprType().FP(1).Varying(), envBuilder);
75 return valid ? ExprType().FP(3).Varying() : ExprType().Error();
76 }
77
78 virtual ExprFuncNode::Data* evalConstant(const ExprFuncNode* node, ArgHandle args) const { return new Data; }
79
80 virtual void eval(ArgHandle args) {
81 double* out = &args.outFp;
82
83 double val = 0.5;
84 int num = args.nargs();
85 if (num > 2)
86 for (int k = 2; k < num; k++) val += args.inFp<1>(k)[0];
87
88 for (int k = 0; k < 3; k++) out[k] = val;
89 }
90
91 public:
92 MapFuncX() : ExprFuncSimple(true) {} // Thread Safe
93 virtual ~MapFuncX() {}
94 } map;
95
96 // triplanar(string name, [vector scale], [float blend], [vector rotation], [vector translation])
97 class TriplanarFuncX : public ExprFuncSimple {
98 struct Data : public ExprFuncNode::Data {
99 std::vector<std::pair<int, int> > ranges;
100 std::string format;
101 };
102
103 virtual ExprType prep(ExprFuncNode* node, bool wantScalar, ExprVarEnvBuilder& envBuilder) const {
104 bool valid = true;
105 valid &= node->checkArg(0, ExprType().String().Constant(), envBuilder);
106 for (int i = 1; i < node->numChildren(); i++)
107 valid &= node->checkArg(i, ExprType().FP(1).Varying(), envBuilder);
108 return valid ? ExprType().FP(3).Varying() : ExprType().Error();
109 }
110
111 virtual ExprFuncNode::Data* evalConstant(const ExprFuncNode* node, ArgHandle args) const { return new Data; }
112
113 virtual void eval(ArgHandle args) {
114 double* out = &args.outFp;
115
116 double val = 0.5;
117 int num = args.nargs();
118 if (num > 1)
119 for (int k = 1; k < num; k++) val += (args.inFp<3>(k)[0] + args.inFp<3>(k)[1] + args.inFp<3>(k)[2]);
120
121 for (int k = 0; k < 3; k++) out[k] = val;
122 }
123
124 public:
125 TriplanarFuncX() : ExprFuncSimple(true) {} // Thread Safe
126 virtual ~TriplanarFuncX() {}
127 } triplanar;
128 }
129
130 static const char* rand_docstring = "rand\n";
131 static const char* map_docstring = "map\n";
132 static const char* triplanar_docstring = "triplanar\n";
133
134 using namespace SeExpr2;
135
137 class ImageSynthExpr : public Expression {
138 public:
140 ImageSynthExpr(const std::string& expr) : Expression(expr, ExprType().FP(3)) {}
141
143 struct Var : public ExprVarRef {
144 Var(const double val) : ExprVarRef(ExprType().FP(1).Varying()), val(val) {}
145
146 Var() : ExprVarRef(ExprType().FP(1).Varying()), val(0.0) {}
147
148 double val; // independent variable
149 void eval(double* result) { result[0] = val; }
150
151 void eval(const char** result) { assert(false); }
152 };
153
154 struct VecVar : public ExprVarRef {
155 VecVar() : ExprVarRef(ExprType().FP(3).Varying()), val(0.0) {}
156
157 Vec<double, 3, false> val; // independent variable
158
159 void eval(double* result) {
160 for (int k = 0; k < 3; k++) result[k] = val[k];
161 }
162
163 void eval(const char** reuslt) {}
164 };
165
167 mutable std::map<std::string, Var> vars;
168 mutable std::map<std::string, VecVar> vecvars;
169
171 ExprVarRef* resolveVar(const std::string& name) const {
172 {
173 std::map<std::string, Var>::iterator i = vars.find(name);
174 if (i != vars.end()) return &i->second;
175 }
176 {
177 std::map<std::string, VecVar>::iterator i = vecvars.find(name);
178 if (i != vecvars.end()) return &i->second;
179 }
180 return 0;
181 }
182 };
183
184 double clamp(double x) { return std::max(0., std::min(255., x)); }
185
186 int main(int argc, char* argv[]) {
187 if (argc != 5) {
188 std::cerr << "Usage: " << argv[0] << " <image file> <width> <height> <exprFile>" << std::endl;
189 return 1;
190 }
191
192 ExprFunc::define("rand", ExprFunc(SeExpr2::rand, 0, 3), rand_docstring);
193 ExprFunc::define("map", ExprFunc(SeExpr2::map, 1, 4), map_docstring);
194 ExprFunc::define("triplanar", ExprFunc(SeExpr2::triplanar, 1, 5), triplanar_docstring);
195
196 // parse arguments
197 const char* imageFile = argv[1];
198 const char* exprFile = argv[4];
199 int width = atoi(argv[2]), height = atoi(argv[3]);
200 if (width < 0 || height < 0) {
201 std::cerr << "invalid width/height" << std::endl;
202 return 1;
203 }
204
205 std::ifstream istream(exprFile);
206 if (!istream) {
207 std::cerr << "Cannot read file " << exprFile << std::endl;
208 return 1;
209 }
210 std::string exprStr((std::istreambuf_iterator<char>(istream)), std::istreambuf_iterator<char>());
211 ImageSynthExpr expr(exprStr);
212
213 // make variables
214 expr.vars["u"] = ImageSynthExpr::Var(0.);
215 expr.vars["v"] = ImageSynthExpr::Var(0.);
216 expr.vars["w"] = ImageSynthExpr::Var(width);
217 expr.vars["h"] = ImageSynthExpr::Var(height);
218
219 expr.vars["faceId"] = ImageSynthExpr::Var(0.);
220 expr.vecvars["P"] = ImageSynthExpr::VecVar();
221 expr.vecvars["Cs"] = ImageSynthExpr::VecVar();
222 expr.vecvars["Ci"] = ImageSynthExpr::VecVar();
223
224 // check if expression is valid
225 bool valid = expr.isValid();
226 if (!valid) {
227 std::cerr << "Invalid expression " << std::endl;
228 std::cerr << expr.parseError() << std::endl;
229 return 1;
230 }
231 // if(!expr.returnType().isFP(3)){
232 // std::cerr<<"Expected color FP[3] got type "<<expr.returnType().toString()<<std::endl;
233 // return 1;
234 // }
235
236 // evaluate expression
237 std::cerr << "Evaluating expresion...from " << exprFile << std::endl;
238 unsigned char* image = new unsigned char[width * height * 4];
239 double one_over_width = 1. / width, one_over_height = 1. / height;
240 double& u = expr.vars["u"].val;
241 double& v = expr.vars["v"].val;
242
243 double& faceId = expr.vars["faceId"].val;
244 Vec<double, 3, false>& P = expr.vecvars["P"].val;
245 Vec<double, 3, false>& Cs = expr.vecvars["Cs"].val;
246 Vec<double, 3, false>& Ci = expr.vecvars["Ci"].val;
247
248 unsigned char* pixel = image;
249
250 {
251 PrintTiming timer("eval time: ");
252 for (int row = 0; row < height; row++) {
253 for (int col = 0; col < width; col++) {
254 u = one_over_width * (col + .5);
255 v = one_over_height * (row + .5);
256
257 faceId = floor(u * 5);
258 P[0] = u * 10;
259 P[1] = v * 10;
260 P[2] = 0.5 * 10;
261 Cs[0] = 0.;
262 Cs[1] = 0.4;
263 Cs[2] = 0.6;
264 Ci[0] = 0.;
265 Ci[1] = 0.4;
266 Ci[2] = 0.6;
267
268 const double* result = expr.evalFP();
269
270 // expr._interpreter->print();
271 pixel[0] = clamp(result[0] * 256.);
272 pixel[1] = clamp(result[1] * 256.);
273 pixel[2] = clamp(result[2] * 256.);
274 pixel[3] = 255;
275 pixel += 4;
276 }
277 }
278 }
279
280 // write image as png
281 std::cerr << "Writing image..." << imageFile << std::endl;
282 FILE* fp = fopen(imageFile, "wb");
283 if (!fp) {
284 perror("fopen");
285 return 1;
286 }
287 png_structp png_ptr;
288 png_infop info_ptr;
289 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
290 info_ptr = png_create_info_struct(png_ptr);
291 png_init_io(png_ptr, fp);
292 int color_type = PNG_COLOR_TYPE_RGBA;
293 png_set_IHDR(png_ptr,
294 info_ptr,
295 width,
296 height,
297 8,
298 color_type,
299 PNG_INTERLACE_NONE,
300 PNG_COMPRESSION_TYPE_DEFAULT,
301 PNG_FILTER_TYPE_DEFAULT);
302 const unsigned char* ptrs[height];
303 for (int i = 0; i < height; i++) {
304 ptrs[i] = &image[width * i * 4];
305 }
306 png_set_rows(png_ptr, info_ptr, (png_byte**)ptrs);
307 png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, 0);
308
309 fclose(fp);
310 }
SeExpr2::TriplanarFuncX::TriplanarFuncX
TriplanarFuncX()
Definition: imageSynthForPaint3d.cpp:125
SeExpr2::RandFuncX::RandFuncX
RandFuncX()
Definition: imageSynthForPaint3d.cpp:59
SeExpr2::ExprType::FP
ExprType & FP(int d)
Mutate this into a floating point type of dimension d.
Definition: ExprType.h:90
SeExpr2::triplanar
SeExpr2::TriplanarFuncX triplanar
SeExpr2::ExprNode::numChildren
int numChildren() const
Number of children.
Definition: ExprNode.h:114
SeExpr2::TriplanarFuncX::Data::format
std::string format
Definition: imageSynthForPaint3d.cpp:100
SeExpr2::map
SeExpr2::MapFuncX map
rand_docstring
static const char * rand_docstring
Definition: imageSynthForPaint3d.cpp:130
SeExpr2::Vec< double, 3, false >
SeExpr2::TriplanarFuncX::prep
virtual ExprType prep(ExprFuncNode *node, bool wantScalar, ExprVarEnvBuilder &envBuilder) const
Definition: imageSynthForPaint3d.cpp:103
SeExpr2::MapFuncX::evalConstant
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
Definition: imageSynthForPaint3d.cpp:78
SeExpr2::ExprFuncSimple::ArgHandle::nargs
int nargs() const
Definition: ExprFuncX.h:89
SeExpr2::RandFuncX::Data::format
std::string format
Definition: imageSynthForPaint3d.cpp:39
SeExpr2::PrintTiming
Definition: Platform.h:150
Interpreter.h
SeExpr2::ExprType::Varying
ExprType & Varying()
Mutate this into a varying lifetime.
Definition: ExprType.h:122
SeExpr2::rand
SeExpr2::RandFuncX rand
SeExpr2::RandFuncX::prep
virtual ExprType prep(ExprFuncNode *node, bool wantScalar, ExprVarEnvBuilder &envBuilder) const
Definition: imageSynthForPaint3d.cpp:42
map_docstring
static const char * map_docstring
Definition: imageSynthForPaint3d.cpp:131
SeExpr2::ExprFuncSimple
Definition: ExprFuncX.h:72
SeExpr2::MapFuncX
Definition: imageSynthForPaint3d.cpp:64
SeExpr2::ExprFuncSimple::ArgHandle
Definition: ExprFuncX.h:76
SeExpr2::ExprFuncSimple::ArgHandle::inFp
Vec< double, d, true > inFp(int i)
Definition: ExprFuncX.h:85
SeExpr2::MapFuncX::Data::format
std::string format
Definition: imageSynthForPaint3d.cpp:67
ExprFunc.h
SeExpr2::ExprType
Definition: ExprType.h:39
SeExpr2::TriplanarFuncX::Data::ranges
std::vector< std::pair< int, int > > ranges
Definition: imageSynthForPaint3d.cpp:99
SeExpr2::RandFuncX::eval
virtual void eval(ArgHandle args)
Definition: imageSynthForPaint3d.cpp:51
SeExpr2::ExprFuncNode
Node that calls a function.
Definition: ExprNode.h:517
Platform.h
Platform-specific classes, functions, and includes.
SeExpr2::ExprFunc
Function Definition, used in parse tree and func table.
Definition: ExprFunc.h:44
SeExpr2::RandFuncX::Data
Definition: imageSynthForPaint3d.cpp:37
SeExpr2::MapFuncX::Data
Definition: imageSynthForPaint3d.cpp:65
SeExpr2::RandFuncX::~RandFuncX
virtual ~RandFuncX()
Definition: imageSynthForPaint3d.cpp:60
SeExpr2
Definition: Context.h:22
SeExpr2::TriplanarFuncX::evalConstant
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
Definition: imageSynthForPaint3d.cpp:111
Vec.h
SeExpr2::min
double min(double x, double y)
Definition: ExprBuiltins.h:43
SeExpr2::ExprFuncSimple::ArgHandle::outFp
double & outFp
Definition: ExprFuncX.h:97
SeExpr2::ExprType::Error
ExprType & Error()
Mutate this into an error type.
Definition: ExprType.h:102
SeExpr2::clamp
double clamp(double x, double lo, double hi)
Definition: ExprBuiltins.h:40
SeExpr2::ExprVarEnvBuilder
Variable scope builder is used by the type checking and code gen to track visiblity of variables and ...
Definition: ExprEnv.h:148
ExprFuncX.h
SeExpr2::ExprFuncNode::checkArg
bool checkArg(int argIndex, ExprType type, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:578
SeExpr2::Expression
main expression class
Definition: Expression.h:76
SeExpr2::max
double max(double x, double y)
Definition: ExprBuiltins.h:42
SeExpr2::TriplanarFuncX::eval
virtual void eval(ArgHandle args)
Definition: imageSynthForPaint3d.cpp:113
SeExpr2::TriplanarFuncX
Definition: imageSynthForPaint3d.cpp:97
eval
virtual void eval(ArgHandle args)
Definition: ExprBuiltins.cpp:1028
SeExpr2::MapFuncX::prep
virtual ExprType prep(ExprFuncNode *node, bool wantScalar, ExprVarEnvBuilder &envBuilder) const
Definition: imageSynthForPaint3d.cpp:70
SeExpr2::RandFuncX
Definition: imageSynthForPaint3d.cpp:35
SeExpr2::MapFuncX::MapFuncX
MapFuncX()
Definition: imageSynthForPaint3d.cpp:92
SeExpr2::ExprFuncNode::Data
base class for custom instance data
Definition: ExprNode.h:570
SeExpr2::MapFuncX::Data::ranges
std::vector< std::pair< int, int > > ranges
Definition: imageSynthForPaint3d.cpp:66
SeExpr2::MapFuncX::~MapFuncX
virtual ~MapFuncX()
Definition: imageSynthForPaint3d.cpp:93
SeExpr2::RandFuncX::evalConstant
virtual ExprFuncNode::Data * evalConstant(const ExprFuncNode *node, ArgHandle args) const
Definition: imageSynthForPaint3d.cpp:49
SeExpr2::MapFuncX::eval
virtual void eval(ArgHandle args)
Definition: imageSynthForPaint3d.cpp:80
SeExpr2::ExprVarRef
abstract class for implementing variable references
Definition: Expression.h:45
SeExpr2::ExprFunc::define
static void define(const char *name, ExprFunc f, const char *docString)
Definition: ExprFunc.cpp:169
triplanar_docstring
static const char * triplanar_docstring
Definition: imageSynthForPaint3d.cpp:132
SeExpr2::RandFuncX::Data::ranges
std::vector< std::pair< int, int > > ranges
Definition: imageSynthForPaint3d.cpp:38
SeExpr2::TriplanarFuncX::Data
Definition: imageSynthForPaint3d.cpp:98
main
int main(int argc, char *argv[])
Definition: imageSynthForPaint3d.cpp:186
Expression.h
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
resolveVar
</pre > Once we have this we need an instance to store our variable and provide a reference to that We make it because resolveVar() is const . One does not need to store a variable reference in a given expression. In fact
SeExpr2::TriplanarFuncX::~TriplanarFuncX
virtual ~TriplanarFuncX()
Definition: imageSynthForPaint3d.cpp:126