KSeExpr  4.0.4.0
imageSynthForPaint3d.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2011-2019 Disney Enterprises, Inc.
2 // SPDX-License-Identifier: LicenseRef-Apache-2.0
3 // SPDX-FileCopyrightText: 2020 L. E. Segovia <amy@amyspark.me>
4 // SPDX-License-Identifier: GPL-3.0-or-later
5 
9 #include <cstdio>
10 #include <cstdlib>
11 #include <cstring>
12 #include <fstream>
13 #include <map>
14 #include <memory>
15 #include <png.h>
16 #include <vector>
17 
18 #include <KSeExpr/ExprFunc.h>
19 #include <KSeExpr/ExprFuncX.h>
20 #include <KSeExpr/Expression.h>
21 #include <KSeExpr/Interpreter.h>
23 #include <KSeExpr/Vec.h>
24 
25 namespace KSeExpr
26 {
27 class ImageSynthRandFuncX : public ExprFuncSimple
28 {
29  struct Data : public ExprFuncNode::Data {
30  std::vector<std::pair<int, int>> ranges;
31  std::string format;
32  };
33 
34  ExprType prep(ExprFuncNode *node, bool, ExprVarEnvBuilder &envBuilder) const override
35  {
36  bool valid = true;
37  for (int i = 0; i < node->numChildren(); i++)
38  valid &= node->checkArg(i, ExprType().FP(1).Varying(), envBuilder);
39  return valid ? ExprType().FP(1).Varying() : ExprType().Error();
40  }
41 
42  ExprFuncNode::Data *evalConstant(const ExprFuncNode *, ArgHandle) const override
43  {
44  return new Data;
45  }
46 
47  void eval(ArgHandle args) override
48  {
49  if (args.nargs() >= 2) {
50  args.outFp = (args.inFp<1>(0)[0] - args.inFp<1>(1)[0]) / 2.0;
51  } else
52  args.outFp = 0.5;
53  }
54 
55 public:
56  ImageSynthRandFuncX()
57  : ExprFuncSimple(true)
58  {
59  } // Thread Safe
60  ~ImageSynthRandFuncX() override = default;
61  ImageSynthRandFuncX &operator=(ImageSynthRandFuncX &&) = default;
62  ImageSynthRandFuncX &operator=(const ImageSynthRandFuncX &) = default;
63  ImageSynthRandFuncX(ImageSynthRandFuncX &&) = default;
64  ImageSynthRandFuncX(const ImageSynthRandFuncX &) = default;
65 };
66 
67 // map(string name, [float format-arg], [float u], [float v], [int channel])
68 class MapFuncX : public ExprFuncSimple
69 {
70  struct Data : public ExprFuncNode::Data {
71  std::vector<std::pair<int, int>> ranges;
72  std::string format;
73  };
74 
75  ExprType prep(ExprFuncNode *node, bool, ExprVarEnvBuilder &envBuilder) const override
76  {
77  bool valid = true;
78  valid &= node->checkArg(0, ExprType().String().Constant(), envBuilder);
79  for (int i = 1; i < node->numChildren(); i++)
80  valid &= node->checkArg(i, ExprType().FP(1).Varying(), envBuilder);
81  return valid ? ExprType().FP(3).Varying() : ExprType().Error();
82  }
83 
85  {
86  return new Data;
87  }
88 
89  void eval(ArgHandle args) override
90  {
91  double *out = &args.outFp;
92 
93  double val = 0.5;
94  int num = args.nargs();
95  if (num > 2)
96  for (int k = 2; k < num; k++)
97  val += args.inFp<1>(k)[0];
98 
99  for (int k = 0; k < 3; k++)
100  out[k] = val;
101  }
102 
103 public:
105  : ExprFuncSimple(true)
106  {
107  } // Thread Safe
108 
109  ~MapFuncX() override = default;
110  MapFuncX &operator=(MapFuncX &&) = default;
111  MapFuncX &operator=(const MapFuncX &) = default;
112  MapFuncX(MapFuncX &&) = default;
113  MapFuncX(const MapFuncX &) = default;
114 };
115 
116 // triplanar(string name, [vector scale], [float blend], [vector rotation], [vector translation])
118 {
119  struct Data : public ExprFuncNode::Data {
120  std::vector<std::pair<int, int>> ranges;
121  std::string format;
122  };
123 
124  ExprType prep(ExprFuncNode *node, bool, ExprVarEnvBuilder &envBuilder) const override
125  {
126  bool valid = true;
127  valid &= node->checkArg(0, ExprType().String().Constant(), envBuilder);
128  for (int i = 1; i < node->numChildren(); i++)
129  valid &= node->checkArg(i, ExprType().FP(1).Varying(), envBuilder);
130  return valid ? ExprType().FP(3).Varying() : ExprType().Error();
131  }
132 
134  {
135  return new Data;
136  }
137 
138  void eval(ArgHandle args) override
139  {
140  double *out = &args.outFp;
141 
142  double val = 0.5;
143  int num = args.nargs();
144  if (num > 1)
145  for (int k = 1; k < num; k++)
146  val += (args.inFp<3>(k)[0] + args.inFp<3>(k)[1] + args.inFp<3>(k)[2]);
147 
148  for (int k = 0; k < 3; k++)
149  out[k] = val;
150  }
151 
152 public:
154  : ExprFuncSimple(true)
155  {
156  } // Thread Safe
157 
158  ~TriplanarFuncX() override = default;
162  TriplanarFuncX(const TriplanarFuncX &) = default;
163 };
164 } // namespace KSeExpr
165 
166 static const char *rand_docstring = "rand\n";
167 static const char *map_docstring = "map\n";
168 static const char *triplanar_docstring = "triplanar\n";
169 
170 using namespace KSeExpr;
171 
173 class ImageSynthExpr : public Expression
174 {
175 public:
177  ImageSynthExpr(const std::string &expr)
178  : Expression(expr, ExprType().FP(3))
179  {
180  }
181 
183  struct Var : public ExprVarRef {
184  Var(const double val)
185  : ExprVarRef(ExprType().FP(1).Varying())
186  , val(val)
187  {
188  }
189 
190  Var()
191  : ExprVarRef(ExprType().FP(1).Varying())
192  {
193  }
194 
195  double val {}; // independent variable
196  void eval(double *result) override
197  {
198  result[0] = val;
199  }
200 
201  void eval(const char **) override
202  {
203  assert(false);
204  }
205  };
206 
207  struct VecVar : public ExprVarRef {
208  VecVar()
209  : ExprVarRef(ExprType().FP(3).Varying())
210  , val(0.0)
211  {
212  }
213 
214  Vec<double, 3, false> val; // independent variable
215 
216  void eval(double *result) override
217  {
218  for (int k = 0; k < 3; k++)
219  result[k] = val[k];
220  }
221 
222  void eval(const char **) override
223  {
224  }
225  };
226 
228  mutable std::map<std::string, Var> vars;
229  mutable std::map<std::string, VecVar> vecvars;
230 
232  ExprVarRef *resolveVar(const std::string &name) const override
233  {
234  {
235  auto i = vars.find(name);
236  if (i != vars.end())
237  return &i->second;
238  }
239  {
240  auto i = vecvars.find(name);
241  if (i != vecvars.end())
242  return &i->second;
243  }
244  return nullptr;
245  }
246 };
247 
248 double clamp(double x)
249 {
250  return std::max(0., std::min(255., x));
251 }
252 
253 int main(int argc, char *argv[])
254 {
255  if (argc != 5) {
256  std::cerr << "Usage: " << argv[0] << " <image file> <width> <height> <exprFile>" << std::endl;
257  return 1;
258  }
259 
260  auto imageSynthRand = std::make_unique<KSeExpr::ImageSynthRandFuncX>();
261  auto map = std::make_unique<KSeExpr::MapFuncX>();
262  auto triplanar = std::make_unique<KSeExpr::TriplanarFuncX>();
263 
264  // Disney: this function overrides the existing rand() -- amyspark
265  ExprFunc::define("rand", ExprFunc(*imageSynthRand, 0, 3), rand_docstring);
266  ExprFunc::define("map", ExprFunc(*map, 1, 4), map_docstring);
267  ExprFunc::define("triplanar", ExprFunc(*triplanar, 1, 5), triplanar_docstring);
268 
269  // parse arguments
270  const char *imageFile = argv[1];
271  const char *exprFile = argv[4];
272  size_t width = std::strtoul(argv[2], nullptr, 10); // NOLINT readability-magic-numbers
273  size_t height = std::strtoul(argv[3], nullptr, 10); // NOLINT readability-magic-numbers
274  if (!width || !height) {
275  std::cerr << "invalid width/height" << std::endl;
276  return 1;
277  }
278 
279  std::ifstream istream(exprFile);
280  if (!istream) {
281  std::cerr << "Cannot read file " << exprFile << std::endl;
282  return 1;
283  }
284  std::string exprStr((std::istreambuf_iterator<char>(istream)), std::istreambuf_iterator<char>());
285  ImageSynthExpr expr(exprStr);
286 
287  // make variables
288  expr.vars["u"] = ImageSynthExpr::Var(0.);
289  expr.vars["v"] = ImageSynthExpr::Var(0.);
290  expr.vars["w"] = ImageSynthExpr::Var(width);
291  expr.vars["h"] = ImageSynthExpr::Var(height);
292 
293  expr.vars["faceId"] = ImageSynthExpr::Var(0.);
294  expr.vecvars["P"] = ImageSynthExpr::VecVar();
295  expr.vecvars["Cs"] = ImageSynthExpr::VecVar();
296  expr.vecvars["Ci"] = ImageSynthExpr::VecVar();
297 
298  // check if expression is valid
299  bool valid = expr.isValid();
300  if (!valid) {
301  std::cerr << "Invalid expression " << std::endl;
302  std::cerr << expr.parseError() << std::endl;
303  return 1;
304  }
305  // if(!expr.returnType().isFP(3)){
306  // std::cerr<<"Expected color FP[3] got type "<<expr.returnType().toString()<<std::endl;
307  // return 1;
308  // }
309 
310  // evaluate expression
311  std::cerr << "Evaluating expression... from " << exprFile << std::endl;
312  std::vector<unsigned char> image(width * height * 4);
313  double one_over_width = 1. / width;
314  double one_over_height = 1. / height;
315  double &u = expr.vars["u"].val;
316  double &v = expr.vars["v"].val;
317 
318  double &faceId = expr.vars["faceId"].val;
319  Vec<double, 3, false> &P = expr.vecvars["P"].val;
320  Vec<double, 3, false> &Cs = expr.vecvars["Cs"].val;
321  Vec<double, 3, false> &Ci = expr.vecvars["Ci"].val;
322 
323  {
324  PerformanceTimer timer("eval time: ");
325  for (size_t row {}; row < height; row++) {
326  for (size_t col {}; col < width; col++) {
327  auto i = (row * width + col) * 4;
328  u = one_over_width * (col + .5);
329  v = one_over_height * (row + .5);
330 
331  faceId = floor(u * 5);
332  P[0] = u * 10;
333  P[1] = v * 10;
334  P[2] = 0.5 * 10;
335  Cs[0] = 0.;
336  Cs[1] = 0.4;
337  Cs[2] = 0.6;
338  Ci[0] = 0.;
339  Ci[1] = 0.4;
340  Ci[2] = 0.6;
341 
342  const double *result = expr.evalFP();
343 
344  // expr._interpreter->print();
345  image[i] = clamp(result[0] * 256.);
346  image[i + 1] = clamp(result[1] * 256.);
347  image[i + 2] = clamp(result[2] * 256.);
348  image[i + 3] = 255;
349  }
350  }
351  }
352 
353  // write image as png
354  std::cerr << "Writing image..." << imageFile << std::endl;
355  std::unique_ptr<std::FILE, decltype(&std::fclose)> fp {fopen(imageFile, "wb"), &std::fclose};
356  if (!fp) {
357  perror("fopen");
358  return 1;
359  }
360  png_structp png_ptr {png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr)};
361  png_infop info_ptr {png_create_info_struct(png_ptr)};
362  png_init_io(png_ptr, fp.get());
363  png_set_IHDR(png_ptr,
364  info_ptr,
365  width,
366  height,
367  8, // NOLINT readability-magic-numbers
368  PNG_COLOR_TYPE_RGBA,
369  PNG_INTERLACE_NONE,
370  PNG_COMPRESSION_TYPE_DEFAULT,
371  PNG_FILTER_TYPE_DEFAULT);
372  std::vector<png_byte *> ptrs(height);
373  for (size_t i {}; i < height; i++) {
374  ptrs[i] = &image[width * i * 4];
375  }
376  png_set_rows(png_ptr, info_ptr, ptrs.data());
377  png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr);
378 }
ExprType prep(ExprFuncNode *node, bool, ExprVarEnvBuilder &envBuilder) const override
Definition: ExprBuiltins.cpp:8
ExprFuncNode::Data * evalConstant(const ExprFuncNode *, ArgHandle) const override
void eval(ArgHandle args) override
Node that calls a function.
Definition: ExprNode.h:654
bool checkArg(int argIndex, const ExprType &type, ExprVarEnvBuilder &envBuilder)
Definition: ExprNode.cpp:631
Vec< double, d, true > inFp(int i)
Definition: ExprFuncX.h:77
ExprFuncX & operator=(const ExprFuncX &)=default
Function Definition, used in parse tree and func table.
Definition: ExprFunc.h:35
static void define(const char *name, const ExprFunc &f, const char *docString)
Definition: ExprFunc.cpp:158
int numChildren() const
Number of children.
Definition: ExprNode.h:108
ExprType & Varying()
Mutate this into a varying lifetime.
Definition: ExprType.h:134
ExprType & FP(int d)
Mutate this into a floating point type of dimension d.
Definition: ExprType.h:97
ExprType & Error()
Mutate this into an error type.
Definition: ExprType.h:111
Variable scope builder is used by the type checking and code gen to track visiblity of variables and ...
Definition: ExprEnv.h:181
abstract class for implementing variable references
Definition: Expression.h:36
main expression class
Definition: Expression.h:67
ExprFuncNode::Data * evalConstant(const ExprFuncNode *, ArgHandle) const override
void eval(ArgHandle args) override
ExprType prep(ExprFuncNode *node, bool, ExprVarEnvBuilder &envBuilder) const override
MapFuncX(const MapFuncX &)=default
MapFuncX & operator=(const MapFuncX &)=default
MapFuncX & operator=(MapFuncX &&)=default
MapFuncX(MapFuncX &&)=default
~MapFuncX() override=default
TriplanarFuncX(const TriplanarFuncX &)=default
~TriplanarFuncX() override=default
ExprFuncNode::Data * evalConstant(const ExprFuncNode *, ArgHandle) const override
ExprType prep(ExprFuncNode *node, bool, ExprVarEnvBuilder &envBuilder) const override
TriplanarFuncX & operator=(TriplanarFuncX &&)=default
TriplanarFuncX & operator=(const TriplanarFuncX &)=default
void eval(ArgHandle args) override
TriplanarFuncX(TriplanarFuncX &&)=default
int main(int argc, char *argv[])
static const char * rand_docstring
static const char * triplanar_docstring
static const char * map_docstring
KSeExpr_DEFAULT double_t floor(double_t val)
Definition: Utils.cpp:168
double max(double x, double y)
Definition: ExprBuiltins.h:74
double min(double x, double y)
Definition: ExprBuiltins.h:78
double clamp(double x, double lo, double hi)
Definition: ExprBuiltins.h:66
static const char * rand_docstring
base class for custom instance data
Definition: ExprNode.h:723
std::vector< std::pair< int, int > > ranges
std::vector< std::pair< int, int > > ranges