contrek 1.2.9 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/ext/cpp_polygon_finder/PolygonFinder/src/Tests.cpp +14 -22
  4. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.cpp +5 -7
  5. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Node.h +4 -1
  6. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.cpp +14 -15
  7. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/NodeCluster.h +2 -4
  8. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/Polygon.h +2 -2
  9. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.cpp +13 -12
  10. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/PolygonFinder.h +10 -58
  11. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.cpp +6 -6
  12. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cluster.h +3 -2
  13. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Cursor.cpp +8 -8
  14. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/EndPoint.h +4 -4
  15. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Finder.h +2 -0
  16. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/InnerPolyline.cpp +6 -6
  17. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/InnerPolyline.h +3 -3
  18. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Merger.cpp +4 -3
  19. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.cpp +29 -9
  20. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Part.h +3 -1
  21. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Partitionable.cpp +45 -30
  22. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.cpp +12 -13
  23. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Polyline.h +4 -4
  24. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.cpp +2 -2
  25. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Position.h +1 -1
  26. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Queueable.h +4 -4
  27. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.cpp +7 -7
  28. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Sequence.h +2 -2
  29. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Shape.cpp +8 -2
  30. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Shape.h +4 -1
  31. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ShapePool.cpp +19 -5
  32. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/ShapePool.h +6 -2
  33. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/StreamingMerger.cpp +8 -5
  34. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.cpp +9 -0
  35. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/Tile.h +1 -0
  36. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/VerticalMerger.cpp +4 -13
  37. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/finder/concurrent/VerticalMerger.h +1 -0
  38. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.cpp +8 -8
  39. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/LinearReducer.h +2 -2
  40. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.cpp +1 -1
  41. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/Reducer.h +2 -2
  42. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.cpp +3 -3
  43. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/UniqReducer.h +1 -1
  44. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.cpp +3 -3
  45. data/ext/cpp_polygon_finder/PolygonFinder/src/polygon/reducers/VisvalingamReducer.h +10 -10
  46. data/ext/cpp_polygon_finder/cpp_polygon_finder.cpp +14 -14
  47. data/lib/contrek/bitmaps/chunky_bitmap.rb +11 -0
  48. data/lib/contrek/finder/concurrent/cluster.rb +1 -1
  49. data/lib/contrek/finder/concurrent/finder.rb +4 -0
  50. data/lib/contrek/finder/concurrent/merger.rb +1 -0
  51. data/lib/contrek/finder/concurrent/part.rb +11 -0
  52. data/lib/contrek/finder/concurrent/partitionable.rb +31 -17
  53. data/lib/contrek/finder/concurrent/vertical_merger.rb +4 -0
  54. data/lib/contrek/finder/polygon_finder.rb +2 -1
  55. data/lib/contrek/version.rb +1 -1
  56. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f506a5908c11f7ac1de118b4772ad9e85cd00746e4ee57b5d9c1600faea371e
4
- data.tar.gz: 81c2807712361d51398962c9496bf3c833b21eb42d34907069c923cd62654f62
3
+ metadata.gz: 58d88411970256b3edc37da05dd9304aaa4593b320e7d73db5966b69d403c4cf
4
+ data.tar.gz: 6a05687f7ffba4b22eb7ebf02abf2a622931bc3250968fa785fb13720036118e
5
5
  SHA512:
6
- metadata.gz: 76c41016ce95c124ed72beacd5c838bf5fe960483e3cf7b78848d53c3d997948f5de0c8ecacdb08d3c38b8faf7349ec79cef9546415773e5d5201019b04fe3b2
7
- data.tar.gz: 1823196730b740221b2e75be9915706b5b96afd91349dd898eda70d1ccce69f569270e134663137523ea3860e5d49a419b59a083a6a11be027bf4e14a1a0e30b
6
+ metadata.gz: 7150e06efce7580fdefd55725db0de52e2805b909e800679a0f99481c3e52333209d1b5ceb750c1fc63a28fa6aaaad7f7662d3baf3ebf377b29cfe4dacf6d19d
7
+ data.tar.gz: 988e85fd99234df2b3cd0e8bec0d8f68ba0f631111a3fda62e114e185dd1619589223266b5e3db71a2a5c478d2871f862209489df997a13a9da866b84718c609
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- contrek (1.2.9)
4
+ contrek (1.3.0)
5
5
  chunky_png (~> 1.4)
6
6
  concurrent-ruby (~> 1.3.5)
7
7
  rice (= 4.5.0)
@@ -60,16 +60,16 @@ void Tests::test_a()
60
60
  std::vector<int> array_compare;
61
61
 
62
62
  for (const auto& x : o->polygons)
63
- { for (const Point* p : x.outer) {
64
- array_compare.push_back(p->x);
65
- array_compare.push_back(p->y);
63
+ { for (const Point& p : x.outer) {
64
+ array_compare.push_back(p.x);
65
+ array_compare.push_back(p.y);
66
66
  }
67
67
  if (outer_array != array_compare) throw std::runtime_error("Wrong OUTER results!");
68
68
  array_compare.clear();
69
69
  for (const auto& z : x.inner)
70
- { for (const Point* y : z)
71
- { array_compare.push_back(y->x);
72
- array_compare.push_back(y->y);
70
+ { for (const Point& y : z)
71
+ { array_compare.push_back(y.x);
72
+ array_compare.push_back(y.y);
73
73
  }
74
74
  }
75
75
  if (inner_array != array_compare) throw std::runtime_error("Wrong INNER results!");
@@ -97,9 +97,9 @@ void Tests::test_b()
97
97
 
98
98
  void Tests::test_c()
99
99
  { Sequence sequence;
100
- Point* p1 = new Point({1, 1});
101
- Point* p2 = new Point({2, 2});
102
- Point* p3 = new Point({3, 3});
100
+ Point p1{1, 1};
101
+ Point p2{2, 2};
102
+ Point p3{3, 3};
103
103
 
104
104
  Hub* hub = new Hub(4);
105
105
 
@@ -114,7 +114,7 @@ void Tests::test_c()
114
114
  if (sequence.size != 3) throw std::runtime_error("Wrong sequence size");
115
115
 
116
116
  // iterator() initially gives head
117
- Point* head = sequence.head->payload;
117
+ const Point& head = sequence.head->payload;
118
118
  if (head != p1) throw std::runtime_error("Wrong head");
119
119
  if (sequence.iterator()->payload != p1) throw std::runtime_error("Wrong iterator to head");
120
120
  if (sequence.iterator() != pos1) throw std::runtime_error("Wrong iterator to head");
@@ -135,10 +135,6 @@ void Tests::test_c()
135
135
  sequence.rewind();
136
136
  if (sequence.iterator()->payload != p1) throw std::runtime_error("Wrong iterator to head");
137
137
 
138
- delete p1;
139
- delete p2;
140
- delete p3;
141
-
142
138
  delete hub;
143
139
 
144
140
  delete pos1;
@@ -348,10 +344,8 @@ void stream_png_image(const std::string& filepath, uint32_t stripe_height, bool
348
344
  ProcessResult *result = polygon_finder.process_info();
349
345
  if (result) {
350
346
  std::cout << "stripe " << stripe_count << ": found polygons " << result->groups << std::endl;
351
- ProcessResult* safe_result = result->clone();
352
- result_clones.push_back(safe_result);
353
- vmerger.add_tile(*safe_result);
354
- delete result;
347
+ result_clones.push_back(result);
348
+ vmerger.add_tile(*result);
355
349
  }
356
350
  stripe_count++;
357
351
  }
@@ -467,10 +461,8 @@ void stream_progressive_png_image(const std::string& filepath, uint32_t stripe_h
467
461
  ProcessResult *result = polygon_finder.process_info();
468
462
  if (result) {
469
463
  std::cout << "stripe " << stripe_count << ": found polygons " << result->groups << std::endl;
470
- ProcessResult* safe_result = result->clone();
471
- result_clones.push_back(safe_result);
472
- vmerger.add_tile(*safe_result, !(current_y_offset + stripe_height < total_height));
473
- delete result;
464
+ result_clones.push_back(result);
465
+ vmerger.add_tile(*result, !(current_y_offset + stripe_height < total_height));
474
466
  }
475
467
  stripe_count++;
476
468
  }
@@ -100,33 +100,31 @@ Node* Node::my_next_outer(Node *last, int versus) {
100
100
  return get_tangent_node_by_virtual_index(this->tangs_sequence[last_node_index]);
101
101
  }
102
102
 
103
- Point* Node::coords_entering_to(Node *enter_to, int mode, int tracking) {
103
+ Point Node::coords_entering_to(Node *enter_to, int mode, int tracking) {
104
104
  int enter_to_index;
105
105
  if (enter_to->y < this->y) enter_to_index = enter_to->abs_x_index + this->up_indexer;
106
106
  else enter_to_index = this->down_indexer - enter_to->abs_x_index;
107
107
 
108
108
  int tg_index = this->tangs_sequence[enter_to_index];
109
- Point* point;
110
109
  if (tg_index < 0) {
111
110
  Node& node_up = cluster->vert_nodes[y + T_UP][-(tg_index + 1)];
112
111
  if (mode == Node::A) {
113
112
  enter_to->track |= TURNER[tracking][OMAX - 1];
114
- point = &node_up.end_point;
113
+ return node_up.end_point;
115
114
  } else {
116
115
  enter_to->track |= TURNER[tracking][OMIN - 1];
117
- point = &node_up.start_point;
116
+ return node_up.start_point;
118
117
  }
119
118
  } else {
120
119
  Node& node_down = cluster->vert_nodes[y + T_DOWN][tg_index];
121
120
  if (mode == Node::A) {
122
121
  enter_to->track |= TURNER[tracking][OMIN - 1];
123
- point = &node_down.start_point;
122
+ return node_down.start_point;
124
123
  } else {
125
124
  enter_to->track |= TURNER[tracking][OMAX - 1];
126
- point = &node_down.end_point;
125
+ return node_down.end_point;
127
126
  }
128
127
  }
129
- return point;
130
128
  }
131
129
 
132
130
  Node* Node::get_tangent_node_by_virtual_index(int virtual_index) {
@@ -61,6 +61,9 @@ struct Point {
61
61
  bool operator==(const Point& other) const {
62
62
  return x == other.x && y == other.y;
63
63
  }
64
+ bool operator!=(const Point& other) const {
65
+ return !(*this == other);
66
+ }
64
67
  Point(int x_, int y_) : x(x_), y(y_) {}
65
68
  Point() : x(0), y(0) {}
66
69
  };
@@ -96,7 +99,7 @@ class Node : public Listable {
96
99
  NodeCluster* cluster;
97
100
  void add_intersection(Node& other_node, int other_node_index);
98
101
  SmallVec tangs_sequence;
99
- Point* coords_entering_to(Node *enter_to, int mode, int tracking);
102
+ Point coords_entering_to(Node *enter_to, int mode, int tracking);
100
103
  Node* my_next_outer(Node *last, int versus);
101
104
  Node* my_next_inner(Node *last, int versus);
102
105
  Node* get_tangent_node_by_virtual_index(int vitual_index);
@@ -18,7 +18,6 @@
18
18
  #include "NodeCluster.h"
19
19
  #include "Node.h"
20
20
  #include "RectBounds.h"
21
- #include "PointPool.h"
22
21
  #include "../reducers/UniqReducer.h"
23
22
  #include "../reducers/LinearReducer.h"
24
23
  #include "../reducers/VisvalingamReducer.h"
@@ -44,7 +43,7 @@ NodeCluster::~NodeCluster() {
44
43
  void NodeCluster::compress_coords(std::list<Polygon>& polygons, pf_Options options) {
45
44
  if (!(options.compress_linear || options.compress_uniq || options.compress_visvalingam)) return;
46
45
 
47
- auto compress_sequence = [&](std::vector<Point*>& points_vec) {
46
+ auto compress_sequence = [&](std::vector<Point>& points_vec) {
48
47
  if (points_vec.empty()) return;
49
48
 
50
49
  if (options.compress_uniq) {
@@ -122,9 +121,9 @@ void NodeCluster::plot(int versus) {
122
121
  next_node = root_node->get_tangent_node_by_virtual_index(root_node->tangs_sequence.front());
123
122
 
124
123
  if (next_node != nullptr)
125
- { Point* p = next_node->coords_entering_to(root_node, versus_inverter[versus], Node::OUTER);
124
+ { Point p = next_node->coords_entering_to(root_node, versus_inverter[versus], Node::OUTER);
125
+ poly.bounds.expand(p.x, p.y);
126
126
  poly.outer.push_back(p);
127
- poly.bounds.expand(p->x, p->y);
128
127
  }
129
128
  if ((this->nodes > 0) && (next_node != nullptr))
130
129
  { plot_node(poly.outer, next_node, root_node, versus, poly.bounds);
@@ -137,7 +136,7 @@ void NodeCluster::plot(int versus) {
137
136
  int index_inner = 0;
138
137
  while (inner_plot->size() > 0)
139
138
  { this->plot_sequence.clear();
140
- std::vector<Point*> inner_sequence;
139
+ std::vector<Point> inner_sequence;
141
140
  std::list<Node*>::iterator first_i;
142
141
  Node *first = nullptr;
143
142
 
@@ -243,7 +242,7 @@ std::pair<int, int> NodeCluster::test_in_hole_o(Node* node)
243
242
  return {-1, -1};
244
243
  }
245
244
 
246
- void NodeCluster::plot_inner_node(std::vector<Point*>& sequence_coords, Node *node, int versus, Node *stop_at, Node *start_node) {
245
+ void NodeCluster::plot_inner_node(std::vector<Point>& sequence_coords, Node *node, int versus, Node *stop_at, Node *start_node) {
247
246
  Node *current_node = node;
248
247
  bool strict_bounds = this->options->strict_bounds;
249
248
  while (current_node != nullptr) {
@@ -279,8 +278,8 @@ void NodeCluster::plot_inner_node(std::vector<Point*>& sequence_coords, Node *no
279
278
  }
280
279
  }
281
280
  } else if (strict_bounds) {
282
- sequence_coords.push_back(this->points_pool.acquire((first_is_max ? last_node->max_x : last_node->min_x), current_node->y));
283
- sequence_coords.push_back(this->points_pool.acquire((first_is_max ? next_node->min_x : next_node->max_x), current_node->y));
281
+ sequence_coords.push_back(Point{(first_is_max ? last_node->max_x : last_node->min_x), current_node->y});
282
+ sequence_coords.push_back(Point{(first_is_max ? next_node->min_x : next_node->max_x), current_node->y});
284
283
  }
285
284
 
286
285
  if (current_node->track_uncomplete()) {
@@ -293,7 +292,7 @@ void NodeCluster::plot_inner_node(std::vector<Point*>& sequence_coords, Node *no
293
292
  }
294
293
  }
295
294
 
296
- void NodeCluster::plot_node(std::vector<Point*>& sequence_coords, Node *node, Node *start_node, int versus, RectBounds& bounds) {
295
+ void NodeCluster::plot_node(std::vector<Point>& sequence_coords, Node *node, Node *start_node, int versus, RectBounds& bounds) {
297
296
  Node *current_node = node;
298
297
  bool strict_bounds = this->options->strict_bounds;
299
298
 
@@ -315,23 +314,23 @@ void NodeCluster::plot_node(std::vector<Point*>& sequence_coords, Node *node, No
315
314
  plot = (n == next_node);
316
315
  }
317
316
  if (plot) {
318
- Point* p = last_node->coords_entering_to(current_node, versus, Node::OUTER);
317
+ Point p = last_node->coords_entering_to(current_node, versus, Node::OUTER);
318
+ bounds.expand(p.x, p.y);
319
319
  sequence_coords.push_back(p);
320
- bounds.expand(p->x, p->y);
321
320
  if (current_node != start_node) {
322
321
  inner_plot->contains(current_node) ? inner_plot->remove(current_node) : inner_plot->push_back(current_node);
323
322
  if (last_node->y == next_node->y) {
324
- Point* p1 = next_node->coords_entering_to(current_node, versus_inverter[versus], Node::OUTER);
323
+ Point p1 = next_node->coords_entering_to(current_node, versus_inverter[versus], Node::OUTER);
324
+ bounds.expand(p1.x, p1.y);
325
325
  sequence_coords.push_back(p1);
326
- bounds.expand(p1->x, p1->y);
327
326
  inner_plot->contains(current_node) ? inner_plot->remove(current_node) : inner_plot->push_back(current_node);
328
327
  }
329
328
  }
330
329
  } else if (strict_bounds) {
331
330
  bool is_down = current_node->y > last_node->y;
332
331
  bool is_a = (versus == Node::A);
333
- sequence_coords.push_back(this->points_pool.acquire((is_down == is_a ? last_node->min_x : last_node->max_x), current_node->y));
334
- sequence_coords.push_back(this->points_pool.acquire((is_down == is_a ? next_node->max_x : next_node->min_x), current_node->y));
332
+ sequence_coords.push_back(Point{(is_down == is_a ? last_node->min_x : last_node->max_x), current_node->y});
333
+ sequence_coords.push_back(Point{(is_down == is_a ? next_node->max_x : next_node->min_x), current_node->y});
335
334
  }
336
335
 
337
336
  if (current_node == start_node) {
@@ -18,7 +18,6 @@
18
18
  #include "Lists.h"
19
19
  #include "RectBounds.h"
20
20
  #include "Polygon.h"
21
- #include "PointPool.h"
22
21
 
23
22
  class Node;
24
23
  struct Point;
@@ -26,8 +25,8 @@ struct pf_Options;
26
25
 
27
26
  class NodeCluster {
28
27
  private:
29
- void plot_node(std::vector<Point*>& sequence_coords, Node *node, Node *start_node, int versus, RectBounds& bounds);
30
- void plot_inner_node(std::vector<Point*>& sequence_coords, Node *node, int versus, Node *stop_at, Node *start_node);
28
+ void plot_node(std::vector<Point>& sequence_coords, Node *node, Node *start_node, int versus, RectBounds& bounds);
29
+ void plot_inner_node(std::vector<Point>& sequence_coords, Node *node, int versus, Node *stop_at, Node *start_node);
31
30
  std::vector<Node*> plot_sequence;
32
31
  List *inner_plot;
33
32
  List *inner_new;
@@ -35,7 +34,6 @@ class NodeCluster {
35
34
  int count = 0;
36
35
  int nodes;
37
36
  int width;
38
- PointPool points_pool;
39
37
 
40
38
  public:
41
39
  pf_Options *options;
@@ -14,8 +14,8 @@
14
14
  #include "RectBounds.h"
15
15
 
16
16
  struct Polygon {
17
- std::vector<Point*> outer;
18
- std::list<std::vector<Point*>> inner;
17
+ std::vector<Point> outer;
18
+ std::list<std::vector<Point>> inner;
19
19
  RectBounds bounds;
20
20
  Polygon() : bounds(RectBounds::empty()) {}
21
21
  };
@@ -108,6 +108,7 @@ ProcessResult* PolygonFinder::process_info() {
108
108
  pr->width = this->source_bitmap->w();
109
109
  pr->height = this->source_bitmap->h();
110
110
  pr->has_bounds = this->node_cluster->options->bounds;
111
+ pr->versus = this->options.versus;
111
112
 
112
113
  if (this->node_cluster->options->named_sequences && typeid(*this->source_bitmap) == typeid(Bitmap))
113
114
  { std::string sequence;
@@ -133,25 +134,25 @@ void ProcessResult::draw_on_bitmap(RawBitmap& bitmap) const {
133
134
  // --- OUTER ---
134
135
  if (!poly.outer.empty()) {
135
136
  for (size_t i = 0; i < poly.outer.size() - 1; ++i) {
136
- Point* p1 = poly.outer[i];
137
- Point* p2 = poly.outer[i+1];
138
- bitmap.draw_line(p1->x, p1->y, p2->x, p2->y, 255, 0, 0, 255);
137
+ const Point& p1 = poly.outer[i];
138
+ const Point& p2 = poly.outer[i+1];
139
+ bitmap.draw_line(p1.x, p1.y, p2.x, p2.y, 255, 0, 0, 255);
139
140
  }
140
- Point* last = poly.outer.back();
141
- Point* first = poly.outer.front();
142
- bitmap.draw_line(last->x, last->y, first->x, first->y, 255, 0, 0, 255);
141
+ const Point& last = poly.outer.back();
142
+ const Point& first = poly.outer.front();
143
+ bitmap.draw_line(last.x, last.y, first.x, first.y, 255, 0, 0, 255);
143
144
  }
144
145
  // --- INNER ---
145
146
  for (const auto& sequence : poly.inner) {
146
147
  if (sequence.empty()) continue;
147
148
  for (size_t i = 0; i < sequence.size() - 1; ++i) {
148
- Point* p1 = sequence[i];
149
- Point* p2 = sequence[i+1];
150
- bitmap.draw_line(p1->x, p1->y, p2->x, p2->y, 0, 128, 0, 255);
149
+ const Point& p1 = sequence[i];
150
+ const Point& p2 = sequence[i+1];
151
+ bitmap.draw_line(p1.x, p1.y, p2.x, p2.y, 0, 128, 0, 255);
151
152
  }
152
- Point* last = sequence.back();
153
- Point* first = sequence.front();
154
- bitmap.draw_line(last->x, last->y, first->x, first->y, 0, 128, 0, 255);
153
+ const Point& last = sequence.back();
154
+ const Point& first = sequence.front();
155
+ bitmap.draw_line(last.x, last.y, first.x, first.y, 0, 128, 0, 255);
155
156
  }
156
157
  }
157
158
  }
@@ -61,12 +61,12 @@ struct pf_Options {
61
61
  struct ProcessResult {
62
62
  int groups;
63
63
  int width, height;
64
+ int versus;
64
65
  bool has_bounds = false;
65
66
  std::map<std::string, double> benchmarks;
66
67
  std::list<Polygon> polygons;
67
68
  std::string named_sequence;
68
69
  std::vector<std::pair<int, int>> treemap;
69
- std::vector<Point> cloned_points_storage;
70
70
 
71
71
  void draw_on_bitmap(RawBitmap& canvas) const;
72
72
 
@@ -74,12 +74,12 @@ struct ProcessResult {
74
74
  int counter = 0;
75
75
  for (const auto& polygon : polygons) {
76
76
  std::cout << counter << " - " << "outer" << "\n";
77
- for (const Point* p : polygon.outer) std::cout << p->toString();
77
+ for (const Point& p : polygon.outer) std::cout << p.toString();
78
78
  bool first = true;
79
79
  for (const auto& seq : polygon.inner) {
80
80
  if (!first) std::cout << "\n";
81
81
  first = false;
82
- for (const Point* p : seq) std::cout << p->toString();
82
+ for (const Point& p : seq) std::cout << p.toString();
83
83
  }
84
84
  std::cout << "\n" << polygon.bounds.to_string() <<"\n";
85
85
  counter++;
@@ -95,61 +95,15 @@ struct ProcessResult {
95
95
 
96
96
  void translate(int x) {
97
97
  for (auto& polygon : polygons) {
98
- for (Point* p : polygon.outer) p->x += x;
99
- for (const auto& seq : polygon.inner) {
100
- for (Point* p : seq) p->x += x;
98
+ for (Point& p : polygon.outer) p.x += x;
99
+ for (auto& seq : polygon.inner) {
100
+ for (Point& p : seq) p.x += x;
101
101
  }
102
102
  polygon.bounds.min_x += x;
103
103
  polygon.bounds.max_x += x;
104
104
  }
105
105
  }
106
106
 
107
- ProcessResult* clone() const {
108
- ProcessResult* new_res = new ProcessResult();
109
- new_res->groups = this->groups;
110
- new_res->width = this->width;
111
- new_res->height = this->height;
112
- new_res->benchmarks = this->benchmarks;
113
- new_res->named_sequence = this->named_sequence;
114
- new_res->treemap = this->treemap;
115
-
116
- size_t estimated_points = 0;
117
- for (const auto& poly : this->polygons) {
118
- estimated_points += poly.outer.size();
119
- for (const auto& seq : poly.inner) estimated_points += seq.size();
120
- }
121
- new_res->cloned_points_storage.reserve(estimated_points);
122
-
123
- for (const auto& poly : this->polygons) {
124
- Polygon new_poly;
125
- new_poly.bounds = poly.bounds;
126
- new_poly.outer.reserve(poly.outer.size());
127
- // outer
128
- for (const Point* p : poly.outer) {
129
- if (p) {
130
- new_res->cloned_points_storage.push_back(Point(p->x, p->y));
131
- size_t idx = new_res->cloned_points_storage.size() - 1;
132
- new_poly.outer.push_back(&new_res->cloned_points_storage[idx]);
133
- }
134
- }
135
- // inner
136
- for (const auto& seq : poly.inner) {
137
- std::vector<Point*> new_seq;
138
- new_seq.reserve(seq.size());
139
- for (const Point* p : seq) {
140
- if (p) {
141
- new_res->cloned_points_storage.push_back(Point(p->x, p->y));
142
- size_t idx = new_res->cloned_points_storage.size() - 1;
143
- new_seq.push_back(&new_res->cloned_points_storage[idx]);
144
- }
145
- }
146
- new_poly.inner.push_back(new_seq);
147
- }
148
- new_res->polygons.push_back(new_poly);
149
- }
150
- return new_res;
151
- }
152
-
153
107
  void to_svg_stream(std::ostream& os) const {
154
108
  os << "<svg xmlns=\"http://www.w3.org/2000/svg\" "
155
109
  << "width=\"" << width << "\" height=\"" << height << "\">\n";
@@ -158,11 +112,10 @@ struct ProcessResult {
158
112
  if (!poly.outer.empty()) {
159
113
  os << "<polygon points=\"";
160
114
  bool first = true;
161
- for (const Point* p : poly.outer) {
162
- if (!p) continue;
115
+ for (const Point& p : poly.outer) {
163
116
  if (!first) os << " ";
164
117
  first = false;
165
- os << p->x << "," << p->y;
118
+ os << p.x << "," << p.y;
166
119
  }
167
120
  os << "\" fill=\"none\" stroke=\"red\" stroke-width=\"1\"/>\n";
168
121
  }
@@ -171,11 +124,10 @@ struct ProcessResult {
171
124
  if (sequence.empty()) continue;
172
125
  os << "<polygon points=\"";
173
126
  bool first = true;
174
- for (const Point* p : sequence) {
175
- if (!p) continue;
127
+ for (const Point& p : sequence) {
176
128
  if (!first) os << " ";
177
129
  first = false;
178
- os << p->x << "," << p->y;
130
+ os << p.x << "," << p.y;
179
131
  }
180
132
  os << "\" fill=\"none\" stroke=\"green\" stroke-width=\"1\"/>\n";
181
133
  }
@@ -18,7 +18,7 @@
18
18
  #include "../../CpuTimer.h"
19
19
 
20
20
  Cluster::Cluster(Finder *finder, int height, int start_x, int end_x)
21
- : finder(finder)
21
+ : finder_(finder)
22
22
  { tiles_.reserve(2); // only two (left|right)
23
23
  this->hub_ = new Hub(height);
24
24
  }
@@ -40,16 +40,16 @@ void Cluster::add(Tile* tile) {
40
40
  }
41
41
  }
42
42
 
43
- void Cluster::list_to_string(std::vector<Point*> list)
43
+ void Cluster::list_to_string(std::vector<Point> list)
44
44
  { std::cout << "(" << &list << ") ";
45
- for (Point* point : list) {
46
- std::cout << point->toString();
45
+ for (const Point& point : list) {
46
+ std::cout << point.toString();
47
47
  }
48
48
  std::cout << std::endl;
49
49
  }
50
50
 
51
51
  Tile* Cluster::merge_tiles() {
52
- bool treemap = this->finder->options().treemap;
52
+ bool treemap = this->finder_->options().treemap;
53
53
  double tot_inner = 0;
54
54
  double tot_outer = 0;
55
55
  CpuTimer timer;
@@ -141,7 +141,7 @@ Tile* Cluster::merge_tiles() {
141
141
  };
142
142
 
143
143
  Tile* tile = new Tile(
144
- this->finder, tiles_.front()->start_x(), tiles_.back()->end_x(), tiles_.front()->name() + tiles_.back()->name(), b);
144
+ this->finder_, tiles_.front()->start_x(), tiles_.back()->end_x(), tiles_.front()->name() + tiles_.back()->name(), b);
145
145
 
146
146
  tile->assign_shapes(new_shapes);
147
147
  for (Tile* old_tile : tiles_) {
@@ -18,7 +18,7 @@
18
18
 
19
19
  class Cluster {
20
20
  private:
21
- Finder *finder;
21
+ Finder *finder_;
22
22
  std::vector<Tile*> tiles_;
23
23
  Hub *hub_ = nullptr;
24
24
  void assign_ancestry(Shape *shape, InnerPolyline* inner_polyline);
@@ -31,7 +31,8 @@ class Cluster {
31
31
  Tile* merge_tiles();
32
32
  const std::vector<Tile*> tiles() const { return tiles_; }
33
33
  Hub* hub() { return hub_; }
34
- static void list_to_string(std::vector<Point*> list);
34
+ static void list_to_string(std::vector<Point> list);
35
35
  PartPool parts_pool;
36
36
  std::deque<Position> positions_pool;
37
+ const Finder* finder() const { return finder_; };
37
38
  };
@@ -29,7 +29,7 @@ Sequence* Cursor::join_outers()
29
29
  this->shapes_sequence_,
30
30
  outer_joined_polyline);
31
31
 
32
- if (*outer_joined_polyline->head->payload == *outer_joined_polyline->tail->payload &&
32
+ if (outer_joined_polyline->head->payload == outer_joined_polyline->tail->payload &&
33
33
  this->cluster.tiles().front()->left() &&
34
34
  this->cluster.tiles().back()->right()) outer_joined_polyline->pop();
35
35
 
@@ -151,11 +151,11 @@ std::vector<InnerPolyline*> Cursor::join_inners(Sequence* outer_seq, bool treema
151
151
  retme_sequence->move_from(*part, [&](QNode<Point>* pos) -> bool {
152
152
  Position *position = static_cast<Position*>(pos);
153
153
  if (part->is(Part::ADDED) &&
154
- !(position->payload->y >= bounds.min &&
155
- position->payload->y <= bounds.max)) {
154
+ !(position->payload.y >= bounds.min &&
155
+ position->payload.y <= bounds.max)) {
156
156
  return(false);
157
157
  }
158
- return(!(polyline->tile->tg_border(*position->payload) && position->end_point()->tracked_outer));
158
+ return(!(polyline->tile->tg_border(position->payload) && position->end_point()->tracked_outer));
159
159
  });
160
160
  }
161
161
  if (retme_sequence->is_not_vertical()) {
@@ -175,7 +175,7 @@ void Cursor::mark_children(std::vector<EndPoint*>& end_points, const Polyline* o
175
175
  for (size_t i = 0; i + 1 < end_points.size(); i += 2) {
176
176
  const auto& a = end_points[i];
177
177
  const auto& b = end_points[i + 1];
178
- auto [y_min, y_max] = std::minmax(a->get_point()->y, b->get_point()->y);
178
+ auto [y_min, y_max] = std::minmax(a->get_point().y, b->get_point().y);
179
179
  for (int y = y_min + 1; y < y_max; ++y) {
180
180
  EndPoint* end_point = this->cluster.hub()->get(y);
181
181
  if (end_point) {
@@ -199,9 +199,9 @@ void Cursor::traverse_inner(Part* act_part, std::vector<Part*>& all_parts, Bound
199
199
  auto [min_it, max_it] = std::minmax_element(
200
200
  points.begin(),
201
201
  points.end(),
202
- [](Point* a, Point* b) { return a->y < b->y; });
203
- bounds.min = std::min(bounds.min, (*min_it)->y);
204
- bounds.max = std::max(bounds.max, (*max_it)->y);
202
+ [](const Point& a, const Point& b) { return a.y < b.y; });
203
+ bounds.min = std::min(bounds.min, min_it->y);
204
+ bounds.max = std::max(bounds.max, max_it->y);
205
205
  }
206
206
  if (act_part->innerable()) {
207
207
  all_parts.push_back(act_part);
@@ -16,15 +16,15 @@ class Part;
16
16
 
17
17
  class EndPoint {
18
18
  public:
19
- EndPoint() : point_(nullptr) {}
19
+ EndPoint() {}
20
20
 
21
- void set_point(Point* p) { point_ = p; }
22
- Point* get_point() const { return point_; }
21
+ void set_point(const Point& p) { point_ = p; }
22
+ const Point& get_point() const { return point_; }
23
23
  std::vector<Queueable<Point>*>& queues() { return queues_; }
24
24
  bool queues_include(Queueable<Point>* q) const;
25
25
  bool tracked_outer = false;
26
26
 
27
27
  private:
28
- Point* point_;
28
+ Point point_;
29
29
  std::vector<Queueable<Point>*> queues_;
30
30
  };
@@ -56,4 +56,6 @@ class Finder : public Poolable {
56
56
  virtual ProcessResult* process_info();
57
57
  const pf_Options& options() const { return options_; }
58
58
  Queue<Tile*>& tiles() { return tiles_; }
59
+ virtual bool transpose() const { return false; }
60
+ int versus;
59
61
  };
@@ -11,7 +11,7 @@
11
11
  #include <vector>
12
12
  #include "InnerPolyline.h"
13
13
 
14
- InnerPolyline::InnerPolyline(std::vector<Point*> raw_coordinates, Shape* shape)
14
+ InnerPolyline::InnerPolyline(std::vector<Point> raw_coordinates, Shape* shape)
15
15
  : raw_coordinates_(std::move(raw_coordinates)),
16
16
  shape_(shape) {}
17
17
  InnerPolyline::InnerPolyline(Sequence* sequence)
@@ -19,7 +19,7 @@ InnerPolyline::InnerPolyline(Sequence* sequence)
19
19
  this->raw_coordinates_ = sequence->to_vector();
20
20
  }
21
21
 
22
- std::vector<Point*>& InnerPolyline::raw() {
22
+ std::vector<Point>& InnerPolyline::raw() {
23
23
  return this->raw_coordinates_;
24
24
  }
25
25
 
@@ -41,11 +41,11 @@ Shape* InnerPolyline::shape() {
41
41
 
42
42
  Bounds& InnerPolyline::raw_vertical_bounds() {
43
43
  if (!raw_coordinates_.empty()) {
44
- int min_y = raw_coordinates_[0]->y;
45
- int max_y = raw_coordinates_[0]->y;
44
+ int min_y = raw_coordinates_[0].y;
45
+ int max_y = raw_coordinates_[0].y;
46
46
  for (const auto& pos : raw_coordinates_) {
47
- if (pos->y < min_y) min_y = pos->y;
48
- if (pos->y > max_y) max_y = pos->y;
47
+ if (pos.y < min_y) min_y = pos.y;
48
+ if (pos.y > max_y) max_y = pos.y;
49
49
  }
50
50
  vertical_bounds_.min = min_y;
51
51
  vertical_bounds_.max = max_y;
@@ -14,15 +14,15 @@
14
14
 
15
15
  class InnerPolyline {
16
16
  public:
17
- explicit InnerPolyline(std::vector<Point*> raw_coordinates, Shape* shape);
17
+ explicit InnerPolyline(std::vector<Point> raw_coordinates, Shape* shape);
18
18
  explicit InnerPolyline(Sequence* sequence);
19
- std::vector<Point*>& raw();
19
+ std::vector<Point>& raw();
20
20
  Sequence* sequence() { return this->sequence_; }
21
21
  Bounds& vertical_bounds();
22
22
  Shape* shape();
23
23
  Shape* assigned_shape = nullptr;
24
24
  private:
25
- std::vector<Point*> raw_coordinates_;
25
+ std::vector<Point> raw_coordinates_;
26
26
  Sequence* sequence_ = nullptr;
27
27
  Shape* shape_;
28
28
  Bounds& raw_vertical_bounds();