Geometrize  1.0
An application for geometrizing images into geometric primitives
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Friends Macros
geometrizerengine.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cstdint>
4 #include <functional>
5 #include <map>
6 #include <memory>
7 #include <string>
8 #include <vector>
9 
10 #include <QObject>
11 
12 #include "chaiscript/chaiscript.hpp"
13 
14 #include "geometrize/bitmap/bitmap.h"
15 #include "geometrize/commonutil.h"
16 #include "geometrize/core.h"
17 #include "geometrize/model.h"
18 #include "geometrize/shape/circle.h"
19 #include "geometrize/shape/ellipse.h"
20 #include "geometrize/shape/line.h"
21 #include "geometrize/shape/polyline.h"
22 #include "geometrize/shape/quadraticbezier.h"
23 #include "geometrize/rasterizer/rasterizer.h"
24 #include "geometrize/rasterizer/scanline.h"
25 #include "geometrize/shape/rectangle.h"
26 #include "geometrize/shape/rotatedellipse.h"
27 #include "geometrize/shape/rotatedrectangle.h"
28 #include "geometrize/shape/shape.h"
29 #include "geometrize/shape/shapefactory.h"
30 #include "geometrize/shape/shapetypes.h"
31 #include "geometrize/shape/triangle.h"
32 
33 #include "common/util.h"
35 #include "script/scriptrunner.h"
36 #include "script/scriptutil.h"
37 
38 namespace chaiscript
39 {
40 class ChaiScript;
41 }
42 
43 namespace geometrize
44 {
45 class Shape;
46 }
47 
48 namespace geometrize
49 {
50 
51 namespace script
52 {
53 
57 class GeometrizerEngine : public QObject, public std::enable_shared_from_this<GeometrizerEngine>
58 {
59  Q_OBJECT
60 
61 public:
63  GeometrizerEngine(const chaiscript::ChaiScript::State& state);
64  virtual ~GeometrizerEngine() = default;
66  GeometrizerEngine(const GeometrizerEngine&) = delete;
67 
68  void installScripts(const std::map<std::string, std::string>& scripts);
69 
74  geometrize::core::EnergyFunction makeEnergyFunction() const
75  {
76  auto self(shared_from_this());
77  geometrize::core::EnergyFunction f = [self, this](const std::vector<geometrize::Scanline>& lines,
78  const std::uint32_t alpha,
79  const geometrize::Bitmap& target,
80  const geometrize::Bitmap& current,
81  geometrize::Bitmap& buffer,
82  double score) {
83  return m_customEnergyFunction(lines, alpha, target, current, buffer, score);
84  };
85  return f;
86  }
87 
95  std::function<std::shared_ptr<geometrize::Shape>()> makeShapeCreator(geometrize::ShapeTypes types, std::int32_t w, std::int32_t h) const
96  {
97  auto self(shared_from_this());
98  auto f = [self, this, types, w, h]() {
99  std::shared_ptr<geometrize::Shape> s = geometrize::randomShapeOf(types);
100 
101  switch(s->getType()) {
102  case geometrize::ShapeTypes::RECTANGLE: {
103  s->setup = [this](geometrize::Shape& s) { return setup(static_cast<geometrize::Rectangle&>(s)); };
104  s->mutate = [this](geometrize::Shape& s) { mutate(static_cast<geometrize::Rectangle&>(s)); };
105  s->rasterize = [w, h](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::Rectangle&>(s), w, h); };
106  break;
107  }
108  case geometrize::ShapeTypes::ROTATED_RECTANGLE: {
109  s->setup = [this](geometrize::Shape& s) { return setup(static_cast<geometrize::RotatedRectangle&>(s)); };
110  s->mutate = [this](geometrize::Shape& s) { mutate(static_cast<geometrize::RotatedRectangle&>(s)); };
111  s->rasterize = [w, h](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::RotatedRectangle&>(s), w, h); };
112  break;
113  }
114  case geometrize::ShapeTypes::TRIANGLE: {
115  s->setup = [this](geometrize::Shape& s) { return setup(static_cast<geometrize::Triangle&>(s)); };
116  s->mutate = [this](geometrize::Shape& s) { mutate(static_cast<geometrize::Triangle&>(s)); };
117  s->rasterize = [w, h](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::Triangle&>(s), w, h); };
118  break;
119  }
120  case geometrize::ShapeTypes::ELLIPSE: {
121  s->setup = [this](geometrize::Shape& s) { return setup(static_cast<geometrize::Ellipse&>(s)); };
122  s->mutate = [this](geometrize::Shape& s) { mutate(static_cast<geometrize::Ellipse&>(s)); };
123  s->rasterize = [w, h](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::Ellipse&>(s), w, h); };
124  break;
125  }
126  case geometrize::ShapeTypes::ROTATED_ELLIPSE: {
127  s->setup = [this](geometrize::Shape& s) { return setup(static_cast<geometrize::RotatedEllipse&>(s)); };
128  s->mutate = [this](geometrize::Shape& s) { mutate(static_cast<geometrize::RotatedEllipse&>(s)); };
129  s->rasterize = [w, h](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::RotatedEllipse&>(s), w, h); };
130  break;
131  }
132  case geometrize::ShapeTypes::CIRCLE: {
133  s->setup = [this](geometrize::Shape& s) { return setup(static_cast<geometrize::Circle&>(s)); };
134  s->mutate = [this](geometrize::Shape& s) { mutate(static_cast<geometrize::Circle&>(s)); };
135  s->rasterize = [w, h](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::Circle&>(s), w, h); };
136  break;
137  }
138  case geometrize::ShapeTypes::LINE: {
139  s->setup = [this](geometrize::Shape& s) { return setup(static_cast<geometrize::Line&>(s)); };
140  s->mutate = [this](geometrize::Shape& s) { mutate(static_cast<geometrize::Line&>(s)); };
141  s->rasterize = [w, h](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::Line&>(s), w, h); };
142  break;
143  }
144  case geometrize::ShapeTypes::QUADRATIC_BEZIER: {
145  s->setup = [this](geometrize::Shape& s) { return setup(static_cast<geometrize::QuadraticBezier&>(s)); };
146  s->mutate = [this](geometrize::Shape& s) { mutate(static_cast<geometrize::QuadraticBezier&>(s)); };
147  s->rasterize = [w, h](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::QuadraticBezier&>(s), w, h); };
148  break;
149  }
150  case geometrize::ShapeTypes::POLYLINE: {
151  s->setup = [this](geometrize::Shape& s) { return setup(static_cast<geometrize::Polyline&>(s)); };
152  s->mutate = [this](geometrize::Shape& s) { mutate(static_cast<geometrize::Polyline&>(s)); };
153  s->rasterize = [w, h](const geometrize::Shape& s) { return geometrize::rasterize(static_cast<const geometrize::Polyline&>(s), w, h); };
154  break;
155  }
156  default:
157  assert(0 && "Bad shape type");
158  }
159 
160  return s;
161  };
162 
163  return f;
164  }
165 
170  chaiscript::ChaiScript* getEngine();
171 
172 signals:
178  void signal_scriptEvaluationSucceeded(const std::string& functionName, const std::string& code);
179 
186  void signal_scriptEvaluationFailed(const std::string& functionName, const std::string& code, const std::string& errorMessage);
187 
188 private:
189  template<class T>
190  void installShapeScript(const std::string& functionName, const std::map<std::string, std::string>& scripts)
191  {
192  try {
193  const auto it{scripts.find(functionName)};
194  assert(it != scripts.end());
195  m_engine->eval(it->second);
196  } catch(...) {
197  // Either syntax error or the function was already defined
198  //assert(0 && "Encountered script error when adding default shape function");
199  }
200 
201  try {
202  const auto f{m_engine->eval<std::function<void(T&)>>(functionName)};
203 
204  const auto g = [f](T& s) {
205  try {
206  f(s);
207  } catch(std::exception& e) {
208  std::cout << e.what() << std::endl;
209  }
210  };
211 
212  const std::string setupPrefix{"setup"};
213  const std::string mutatePrefix{"mutate"};
214  if(functionName.find(setupPrefix) == 0) {
215  setSetupFunction(g);
216  return;
217  } else if(functionName.find(mutatePrefix) == 0) {
219  return;
220  }
221  } catch(std::exception& e) {
222  std::cout << e.what() << std::endl;
223  }
224 
225  assert(0 && "Checking for unrecognized required function, will ignore it");
226  }
227 
228  void installCustomEnergyScript(const std::string& functionName, const std::string& scriptCode)
229  {
230  try {
231  m_engine->eval(scriptCode);
232  } catch(...) {
233  // Either syntax error or the function was already defined
234  //assert(0 && "Encountered script error when adding custom energy function");
235  }
236 
237  try {
238  const auto f{m_engine->eval<geometrize::core::EnergyFunction>(functionName)};
239 
240  const geometrize::core::EnergyFunction g = [f](
241  const std::vector<geometrize::Scanline>& lines,
242  const std::uint32_t alpha,
243  const geometrize::Bitmap& target,
244  const geometrize::Bitmap& current,
245  geometrize::Bitmap& buffer,
246  const double score) {
247  try {
248  return f(lines, alpha, target, current, buffer, score);
249  } catch(std::exception& e) {
250  std::cout << e.what() << std::endl;
251  return 0.0;
252  }
253  };
254 
256  return;
257  } catch(std::exception& e) {
258  std::cout << e.what() << std::endl;
259  }
260 
261  assert(0 && "Checking for unrecognized required function, will ignore it");
262  }
263 
264  void setup(geometrize::Circle& shape) const
265  {
266  m_setupCircle(shape);
267  }
268 
269  void mutate(geometrize::Circle& shape) const
270  {
271  m_mutateCircle(shape);
272  }
273 
274  void setSetupFunction(const std::function<void(geometrize::Circle&)>& f)
275  {
276  m_setupCircle = f;
277  }
278 
279  void setMutatorFunction(const std::function<void(geometrize::Circle&)>& f)
280  {
281  m_mutateCircle = f;
282  }
283 
284  void setup(geometrize::Ellipse& shape) const
285  {
286  m_setupEllipse(shape);
287  }
288 
289  void mutate(geometrize::Ellipse& shape) const
290  {
291  m_mutateEllipse(shape);
292  }
293 
294  void setSetupFunction(const std::function<void(geometrize::Ellipse&)>& f)
295  {
296  m_setupEllipse = f;
297  }
298 
299  void setMutatorFunction(const std::function<void(geometrize::Ellipse&)>& f)
300  {
301  m_mutateEllipse = f;
302  }
303 
304  void setup(geometrize::Line& shape) const
305  {
306  m_setupLine(shape);
307  }
308 
309  void mutate(geometrize::Line& shape) const
310  {
311  m_mutateLine(shape);
312  }
313 
314  void setSetupFunction(const std::function<void(geometrize::Line&)>& f)
315  {
316  m_setupLine = f;
317  }
318 
319  void setMutatorFunction(const std::function<void(geometrize::Line&)>& f)
320  {
321  m_mutateLine = f;
322  }
323 
324  void setup(geometrize::Polyline& shape) const
325  {
326  m_setupPolyline(shape);
327  }
328 
329  void mutate(geometrize::Polyline& shape) const
330  {
331  m_mutatePolyline(shape);
332  }
333 
334  void setSetupFunction(const std::function<void(geometrize::Polyline&)>& f)
335  {
336  m_setupPolyline = f;
337  }
338 
339  void setMutatorFunction(const std::function<void(geometrize::Polyline&)>& f)
340  {
341  m_mutatePolyline = f;
342  }
343 
344  void setup(geometrize::QuadraticBezier& shape) const
345  {
346  m_setupQuadraticBezier(shape);
347  }
348 
349  void mutate(geometrize::QuadraticBezier& shape) const
350  {
352  }
353 
354  void setSetupFunction(const std::function<void(geometrize::QuadraticBezier&)>& f)
355  {
357  }
358 
359  void setMutatorFunction(const std::function<void(geometrize::QuadraticBezier&)>& f)
360  {
362  }
363 
364  void setup(geometrize::Rectangle& shape) const
365  {
366  m_setupRectangle(shape);
367  }
368 
369  void mutate(geometrize::Rectangle& shape) const
370  {
371  m_mutateRectangle(shape);
372  }
373 
374  void setSetupFunction(const std::function<void(geometrize::Rectangle&)>& f)
375  {
376  m_setupRectangle = f;
377  }
378 
379  void setMutatorFunction(const std::function<void(geometrize::Rectangle&)>& f)
380  {
381  m_mutateRectangle = f;
382  }
383 
384  void setup(geometrize::RotatedEllipse& shape) const
385  {
386  m_setupRotatedEllipse(shape);
387  }
388 
389  void mutate(geometrize::RotatedEllipse& shape) const
390  {
391  m_mutateRotatedEllipse(shape);
392  }
393 
394  void setSetupFunction(const std::function<void(geometrize::RotatedEllipse&)>& f)
395  {
397  }
398 
399  void setMutatorFunction(const std::function<void(geometrize::RotatedEllipse&)>& f)
400  {
402  }
403 
404  void setup(geometrize::RotatedRectangle& shape) const
405  {
407  }
408 
409  void mutate(geometrize::RotatedRectangle& shape) const
410  {
412  }
413 
414  void setSetupFunction(const std::function<void(geometrize::RotatedRectangle&)>& f)
415  {
417  }
418 
419  void setMutatorFunction(const std::function<void(geometrize::RotatedRectangle&)>& f)
420  {
422  }
423 
424  void setup(geometrize::Triangle& shape) const
425  {
426  m_setupTriangle(shape);
427  }
428 
429  void mutate(geometrize::Triangle& shape) const
430  {
431  m_mutateTriangle(shape);
432  }
433 
434  void setSetupFunction(const std::function<void(geometrize::Triangle&)>& f)
435  {
436  m_setupTriangle = f;
437  }
438 
439  void setMutatorFunction(const std::function<void(geometrize::Triangle&)>& f)
440  {
441  m_mutateTriangle = f;
442  }
443 
444  void setCustomEnergyFunction(const geometrize::core::EnergyFunction& f)
445  {
447  }
448 
449  std::function<void(geometrize::Circle&)> m_setupCircle;
450  std::function<void(geometrize::Ellipse&)> m_setupEllipse;
451  std::function<void(geometrize::Line&)> m_setupLine;
452  std::function<void(geometrize::Polyline&)> m_setupPolyline;
453  std::function<void(geometrize::QuadraticBezier&)> m_setupQuadraticBezier;
454  std::function<void(geometrize::Rectangle&)> m_setupRectangle;
455  std::function<void(geometrize::RotatedEllipse&)> m_setupRotatedEllipse;
456  std::function<void(geometrize::RotatedRectangle&)> m_setupRotatedRectangle;
457  std::function<void(geometrize::Triangle&)> m_setupTriangle;
458 
459  std::function<void(geometrize::Circle&)> m_mutateCircle;
460  std::function<void(geometrize::Ellipse&)> m_mutateEllipse;
461  std::function<void(geometrize::Line&)> m_mutateLine;
462  std::function<void(geometrize::Polyline&)> m_mutatePolyline;
463  std::function<void(geometrize::QuadraticBezier&)> m_mutateQuadraticBezier;
464  std::function<void(geometrize::Rectangle&)> m_mutateRectangle;
465  std::function<void(geometrize::RotatedEllipse&)> m_mutateRotatedEllipse;
466  std::function<void(geometrize::RotatedRectangle&)> m_mutateRotatedRectangle;
467  std::function<void(geometrize::Triangle&)> m_mutateTriangle;
468 
469  geometrize::core::EnergyFunction m_customEnergyFunction;
470 
471  std::unique_ptr<chaiscript::ChaiScript> m_engine;
472 };
473 
474 }
475 
476 }
std::function< void(geometrize::QuadraticBezier &)> m_setupQuadraticBezier
Definition: geometrizerengine.h:453
void setup(geometrize::Triangle &shape) const
Definition: geometrizerengine.h:424
std::function< void(geometrize::Ellipse &)> m_mutateEllipse
Definition: geometrizerengine.h:460
void mutate(geometrize::Polyline &shape) const
Definition: geometrizerengine.h:329
void mutate(geometrize::Ellipse &shape) const
Definition: geometrizerengine.h:289
std::function< void(geometrize::Line &)> m_mutateLine
Definition: geometrizerengine.h:461
void setup(geometrize::RotatedRectangle &shape) const
Definition: geometrizerengine.h:404
The GeometrizerEngine class encapsulates script-based setup and mutation methods for geometrizing sha...
Definition: geometrizerengine.h:57
std::function< void(geometrize::RotatedRectangle &)> m_setupRotatedRectangle
Definition: geometrizerengine.h:456
chaiscript::ChaiScript * getEngine()
getEngine Gets a pointer to the script engine used by the shape mutation engine.
Definition: geometrizerengine.cpp:52
void mutate(geometrize::Circle &shape) const
Definition: geometrizerengine.h:269
void mutate(geometrize::QuadraticBezier &shape) const
Definition: geometrizerengine.h:349
GeometrizerEngine & operator=(const GeometrizerEngine &)=delete
void setMutatorFunction(const std::function< void(geometrize::RotatedRectangle &)> &f)
Definition: geometrizerengine.h:419
void setSetupFunction(const std::function< void(geometrize::QuadraticBezier &)> &f)
Definition: geometrizerengine.h:354
void setup(geometrize::RotatedEllipse &shape) const
Definition: geometrizerengine.h:384
void setSetupFunction(const std::function< void(geometrize::Triangle &)> &f)
Definition: geometrizerengine.h:434
void setup(geometrize::Ellipse &shape) const
Definition: geometrizerengine.h:284
std::function< void(geometrize::Polyline &)> m_mutatePolyline
Definition: geometrizerengine.h:462
std::function< void(geometrize::Rectangle &)> m_setupRectangle
Definition: geometrizerengine.h:454
void setMutatorFunction(const std::function< void(geometrize::RotatedEllipse &)> &f)
Definition: geometrizerengine.h:399
std::function< void(geometrize::Polyline &)> m_setupPolyline
Definition: geometrizerengine.h:452
void setMutatorFunction(const std::function< void(geometrize::Rectangle &)> &f)
Definition: geometrizerengine.h:379
void setMutatorFunction(const std::function< void(geometrize::Circle &)> &f)
Definition: geometrizerengine.h:279
void setSetupFunction(const std::function< void(geometrize::Ellipse &)> &f)
Definition: geometrizerengine.h:294
void setMutatorFunction(const std::function< void(geometrize::QuadraticBezier &)> &f)
Definition: geometrizerengine.h:359
void mutate(geometrize::Triangle &shape) const
Definition: geometrizerengine.h:429
void mutate(geometrize::RotatedRectangle &shape) const
Definition: geometrizerengine.h:409
void setMutatorFunction(const std::function< void(geometrize::Ellipse &)> &f)
Definition: geometrizerengine.h:299
void mutate(geometrize::RotatedEllipse &shape) const
Definition: geometrizerengine.h:389
std::function< void(geometrize::Triangle &)> m_mutateTriangle
Definition: geometrizerengine.h:467
std::function< void(geometrize::RotatedEllipse &)> m_mutateRotatedEllipse
Definition: geometrizerengine.h:465
void signal_scriptEvaluationFailed(const std::string &functionName, const std::string &code, const std::string &errorMessage)
signal_scriptEvaluationFailed Signal dispatched when a script fails to parse/evaluate.
void setSetupFunction(const std::function< void(geometrize::Line &)> &f)
Definition: geometrizerengine.h:314
geometrize::core::EnergyFunction m_customEnergyFunction
Definition: geometrizerengine.h:469
std::function< void(geometrize::Circle &)> m_setupCircle
Definition: geometrizerengine.h:449
void mutate(geometrize::Rectangle &shape) const
Definition: geometrizerengine.h:369
std::unique_ptr< chaiscript::ChaiScript > m_engine
Definition: geometrizerengine.h:471
void setup(geometrize::Polyline &shape) const
Definition: geometrizerengine.h:324
std::function< void(geometrize::Rectangle &)> m_mutateRectangle
Definition: geometrizerengine.h:464
void setSetupFunction(const std::function< void(geometrize::Circle &)> &f)
Definition: geometrizerengine.h:274
std::function< void(geometrize::QuadraticBezier &)> m_mutateQuadraticBezier
Definition: geometrizerengine.h:463
void setSetupFunction(const std::function< void(geometrize::Polyline &)> &f)
Definition: geometrizerengine.h:334
void installShapeScript(const std::string &functionName, const std::map< std::string, std::string > &scripts)
Definition: geometrizerengine.h:190
void setSetupFunction(const std::function< void(geometrize::Rectangle &)> &f)
Definition: geometrizerengine.h:374
void setup(geometrize::Circle &shape) const
Definition: geometrizerengine.h:264
void setSetupFunction(const std::function< void(geometrize::RotatedEllipse &)> &f)
Definition: geometrizerengine.h:394
void setMutatorFunction(const std::function< void(geometrize::Line &)> &f)
Definition: geometrizerengine.h:319
void setCustomEnergyFunction(const geometrize::core::EnergyFunction &f)
Definition: geometrizerengine.h:444
std::function< void(geometrize::RotatedRectangle &)> m_mutateRotatedRectangle
Definition: geometrizerengine.h:466
void setMutatorFunction(const std::function< void(geometrize::Triangle &)> &f)
Definition: geometrizerengine.h:439
void installCustomEnergyScript(const std::string &functionName, const std::string &scriptCode)
Definition: geometrizerengine.h:228
void installScripts(const std::map< std::string, std::string > &scripts)
Definition: geometrizerengine.cpp:57
void mutate(geometrize::Line &shape) const
Definition: geometrizerengine.h:309
std::function< void(geometrize::Circle &)> m_mutateCircle
Definition: geometrizerengine.h:459
void setup(geometrize::Line &shape) const
Definition: geometrizerengine.h:304
void setup(geometrize::Rectangle &shape) const
Definition: geometrizerengine.h:364
void setup(geometrize::QuadraticBezier &shape) const
Definition: geometrizerengine.h:344
std::function< void(geometrize::RotatedEllipse &)> m_setupRotatedEllipse
Definition: geometrizerengine.h:455
geometrize::core::EnergyFunction makeEnergyFunction() const
makeEnergyFunction Returns a custom energy function for the core geometrization algorithm.
Definition: geometrizerengine.h:74
std::function< std::shared_ptr< geometrize::Shape >)> makeShapeCreator(geometrize::ShapeTypes types, std::int32_t w, std::int32_t h) const
makeShapeCreator Returns a function that generates shapes for the core geometrization algorithm This ...
Definition: geometrizerengine.h:95
void setSetupFunction(const std::function< void(geometrize::RotatedRectangle &)> &f)
Definition: geometrizerengine.h:414
std::function< void(geometrize::Line &)> m_setupLine
Definition: geometrizerengine.h:451
std::function< void(geometrize::Ellipse &)> m_setupEllipse
Definition: geometrizerengine.h:450
std::function< void(geometrize::Triangle &)> m_setupTriangle
Definition: geometrizerengine.h:457
void setMutatorFunction(const std::function< void(geometrize::Polyline &)> &f)
Definition: geometrizerengine.h:339
GeometrizerEngine()
Definition: geometrizerengine.cpp:43
void signal_scriptEvaluationSucceeded(const std::string &functionName, const std::string &code)
signal_scriptEvaluationSucceeded Signal dispatched when a script is successfully parsed/evaluated.