rays 0.1.47 → 0.1.48
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.
- checksums.yaml +4 -4
- data/.doc/ext/rays/bitmap.cpp +287 -46
- data/.doc/ext/rays/camera.cpp +2 -2
- data/.doc/ext/rays/defs.cpp +32 -8
- data/.doc/ext/rays/font.cpp +50 -2
- data/.doc/ext/rays/native.cpp +2 -4
- data/.doc/ext/rays/painter.cpp +73 -3
- data/.doc/ext/rays/polygon.cpp +131 -97
- data/.doc/ext/rays/polyline.cpp +89 -10
- data/.doc/ext/rays/rays.cpp +80 -0
- data/.doc/ext/rays/{noise.cpp → util.cpp} +2 -2
- data/ChangeLog.md +23 -0
- data/VERSION +1 -1
- data/ext/rays/bitmap.cpp +288 -46
- data/ext/rays/camera.cpp +2 -2
- data/ext/rays/defs.cpp +32 -8
- data/ext/rays/defs.h +56 -3
- data/ext/rays/font.cpp +56 -4
- data/ext/rays/native.cpp +2 -4
- data/ext/rays/painter.cpp +80 -3
- data/ext/rays/polygon.cpp +134 -99
- data/ext/rays/polyline.cpp +95 -9
- data/ext/rays/rays.cpp +80 -0
- data/ext/rays/{noise.cpp → util.cpp} +2 -2
- data/include/rays/defs.h +24 -26
- data/include/rays/font.h +17 -3
- data/include/rays/painter.h +14 -0
- data/include/rays/polygon.h +56 -37
- data/include/rays/polyline.h +17 -2
- data/include/rays/ruby/polygon.h +0 -11
- data/include/rays/ruby/rays.h +4 -0
- data/include/rays/{noise.h → util.h} +2 -2
- data/lib/rays/color.rb +1 -1
- data/lib/rays/font.rb +1 -1
- data/lib/rays/image.rb +1 -1
- data/lib/rays/painter.rb +12 -1
- data/lib/rays/point.rb +1 -1
- data/lib/rays/polygon.rb +44 -35
- data/lib/rays/polyline.rb +54 -8
- data/lib/rays.rb +0 -1
- data/rays.gemspec +1 -1
- data/src/font.cpp +24 -2
- data/src/font.h +8 -1
- data/src/ios/font.mm +88 -27
- data/src/osx/font.mm +90 -28
- data/src/osx/helper.h +2 -2
- data/src/osx/helper.mm +2 -2
- data/src/painter.cpp +155 -85
- data/src/painter.h +11 -3
- data/src/polygon.cpp +404 -315
- data/src/polyline.cpp +138 -27
- data/src/polyline.h +3 -5
- data/src/shader.cpp +36 -4
- data/src/shader.h +1 -1
- data/src/texture.cpp +2 -2
- data/src/{noise.cpp → util.cpp} +1 -1
- data/src/win32/font.cpp +1 -1
- data/test/test_bitmap.rb +12 -5
- data/test/test_color.rb +4 -0
- data/test/test_font.rb +20 -2
- data/test/test_image.rb +18 -18
- data/test/test_point.rb +1 -1
- data/test/test_polygon.rb +52 -45
- data/test/test_polyline.rb +191 -72
- metadata +9 -15
- data/.doc/ext/rays/polygon_line.cpp +0 -97
- data/ext/rays/polygon_line.cpp +0 -100
- data/lib/rays/polygon_line.rb +0 -33
- data/test/test_polygon_line.rb +0 -164
data/src/polygon.cpp
CHANGED
@@ -50,66 +50,62 @@ namespace Rays
|
|
50
50
|
{
|
51
51
|
|
52
52
|
|
53
|
-
class
|
53
|
+
class Triangles
|
54
54
|
{
|
55
55
|
|
56
56
|
public:
|
57
57
|
|
58
|
-
|
58
|
+
Triangles (size_t npoints)
|
59
59
|
{
|
60
60
|
points.reserve(npoints);
|
61
61
|
}
|
62
62
|
|
63
|
-
|
63
|
+
void append (const Polyline& polyline)
|
64
64
|
{
|
65
|
-
|
66
|
-
return segments.back().begin;
|
67
|
-
}
|
68
|
-
|
69
|
-
void end (size_t n)
|
70
|
-
{
|
71
|
-
if (segments.empty())
|
72
|
-
invalid_state_error(__FILE__, __LINE__);
|
65
|
+
if (polyline.empty()) return;
|
73
66
|
|
74
|
-
|
75
|
-
|
67
|
+
const Point* points_ = polyline.points();
|
68
|
+
const Color* colors_ = polyline.colors();
|
69
|
+
const Coord3* texcoords_ = polyline.texcoords();
|
70
|
+
if (!points_)
|
76
71
|
argument_error(__FILE__, __LINE__);
|
77
72
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
{
|
85
|
-
points.emplace_back(point);
|
86
|
-
}
|
73
|
+
if (
|
74
|
+
!points.empty() &&
|
75
|
+
(!colors_ != !pcolors || !texcoords_ != !ptexcoords))
|
76
|
+
{
|
77
|
+
argument_error(__FILE__, __LINE__);
|
78
|
+
}
|
87
79
|
|
88
|
-
|
89
|
-
|
90
|
-
|
80
|
+
segments.emplace_back(points.size(), 0, polyline.hole());
|
81
|
+
points.insert(points.end(), points_, points_ + polyline.size());
|
82
|
+
segments.back().end = points.size();
|
91
83
|
|
92
|
-
|
93
|
-
size_t index_offset = 0;
|
94
|
-
for (const auto& seg : segments)
|
84
|
+
if (colors_)
|
95
85
|
{
|
96
|
-
|
97
|
-
if (!seg.hole)
|
86
|
+
if (!pcolors)
|
98
87
|
{
|
99
|
-
|
100
|
-
|
101
|
-
index_offset = seg.begin;
|
88
|
+
pcolors.reset(new decltype(pcolors)::element_type());
|
89
|
+
pcolors->reserve(points.capacity());
|
102
90
|
}
|
103
|
-
|
91
|
+
pcolors->insert(pcolors->end(), colors_, colors_ + polyline.size());
|
104
92
|
}
|
105
|
-
triangulate(polylines, index_offset);
|
106
93
|
|
107
|
-
|
108
|
-
|
94
|
+
if (texcoords_)
|
95
|
+
{
|
96
|
+
if (!ptexcoords)
|
97
|
+
{
|
98
|
+
ptexcoords.reset(new decltype(ptexcoords)::element_type());
|
99
|
+
ptexcoords->reserve(points.capacity());
|
100
|
+
}
|
101
|
+
ptexcoords->insert(
|
102
|
+
ptexcoords->end(), texcoords_, texcoords_ + polyline.size());
|
103
|
+
}
|
109
104
|
}
|
110
105
|
|
111
|
-
bool
|
106
|
+
bool get (Polygon::TrianglePointList* triangles) const
|
112
107
|
{
|
108
|
+
triangulate();
|
113
109
|
if (indices.empty()) return false;
|
114
110
|
|
115
111
|
triangles->reserve(triangles->size() + indices.size());
|
@@ -118,6 +114,30 @@ namespace Rays
|
|
118
114
|
return true;
|
119
115
|
}
|
120
116
|
|
117
|
+
void draw (Painter* painter, const Color& color) const
|
118
|
+
{
|
119
|
+
triangulate();
|
120
|
+
if (indices.empty()) return;
|
121
|
+
|
122
|
+
if (pcolors)
|
123
|
+
{
|
124
|
+
Painter_draw(
|
125
|
+
painter, GL_TRIANGLES,
|
126
|
+
&points[0], points.size(),
|
127
|
+
&indices[0], indices.size(),
|
128
|
+
&(*pcolors)[0],
|
129
|
+
ptexcoords ? &(*ptexcoords)[0] : NULL);
|
130
|
+
}
|
131
|
+
else
|
132
|
+
{
|
133
|
+
Painter_draw(
|
134
|
+
painter, GL_TRIANGLES, color,
|
135
|
+
&points[0], points.size(),
|
136
|
+
&indices[0], indices.size(),
|
137
|
+
ptexcoords ? &(*ptexcoords)[0] : NULL);
|
138
|
+
}
|
139
|
+
}
|
140
|
+
|
121
141
|
private:
|
122
142
|
|
123
143
|
struct Segment
|
@@ -165,13 +185,40 @@ namespace Rays
|
|
165
185
|
|
166
186
|
typedef std::vector<Polyline> PolylineList;
|
167
187
|
|
168
|
-
std::vector<Segment> segments;
|
169
|
-
|
170
188
|
std::vector<Point> points;
|
171
189
|
|
172
|
-
std::vector<
|
190
|
+
std::unique_ptr<std::vector<Color>> pcolors;
|
191
|
+
|
192
|
+
std::unique_ptr<std::vector<Coord3>> ptexcoords;
|
193
|
+
|
194
|
+
mutable std::vector<Segment> segments;
|
195
|
+
|
196
|
+
mutable std::vector<uint32_t> indices;
|
197
|
+
|
198
|
+
void triangulate () const
|
199
|
+
{
|
200
|
+
if (segments.empty()) return;
|
201
|
+
|
202
|
+
PolylineList polylines;
|
203
|
+
size_t index_offset = 0;
|
204
|
+
for (const auto& seg : segments)
|
205
|
+
{
|
206
|
+
Polyline polyline(&points[0] + seg.begin, seg.end - seg.begin);
|
207
|
+
if (!seg.hole)
|
208
|
+
{
|
209
|
+
triangulate(polylines, index_offset);
|
210
|
+
polylines.clear();
|
211
|
+
index_offset = seg.begin;
|
212
|
+
}
|
213
|
+
polylines.emplace_back(polyline);
|
214
|
+
}
|
215
|
+
triangulate(polylines, index_offset);
|
216
|
+
|
217
|
+
segments.clear();
|
218
|
+
segments.shrink_to_fit();
|
219
|
+
}
|
173
220
|
|
174
|
-
void triangulate (const PolylineList& polylines, size_t index_offset)
|
221
|
+
void triangulate (const PolylineList& polylines, size_t index_offset) const
|
175
222
|
{
|
176
223
|
if (polylines.empty()) return;
|
177
224
|
|
@@ -180,17 +227,17 @@ namespace Rays
|
|
180
227
|
indices.emplace_back(index_offset + index);
|
181
228
|
}
|
182
229
|
|
183
|
-
};//
|
230
|
+
};// Triangles
|
184
231
|
|
185
232
|
|
186
233
|
struct Polygon::Data
|
187
234
|
{
|
188
235
|
|
189
|
-
|
236
|
+
PolylineList polylines;
|
190
237
|
|
191
|
-
mutable std::unique_ptr<Bounds>
|
238
|
+
mutable std::unique_ptr<Bounds> pbounds;
|
192
239
|
|
193
|
-
mutable std::unique_ptr<
|
240
|
+
mutable std::unique_ptr<Triangles> ptriangles;
|
194
241
|
|
195
242
|
virtual ~Data ()
|
196
243
|
{
|
@@ -200,14 +247,14 @@ namespace Rays
|
|
200
247
|
{
|
201
248
|
if (!pbounds)
|
202
249
|
{
|
203
|
-
if (
|
250
|
+
if (polylines.empty())
|
204
251
|
pbounds.reset(new Bounds(-1, -1, -1));
|
205
252
|
else
|
206
253
|
{
|
207
|
-
pbounds.reset(new Bounds(
|
208
|
-
for (const auto&
|
254
|
+
pbounds.reset(new Bounds(polylines[0][0], 0));
|
255
|
+
for (const auto& polyline : polylines)
|
209
256
|
{
|
210
|
-
for (const auto& point :
|
257
|
+
for (const auto& point : polyline)
|
211
258
|
*pbounds |= point;
|
212
259
|
}
|
213
260
|
}
|
@@ -215,48 +262,24 @@ namespace Rays
|
|
215
262
|
return *pbounds;
|
216
263
|
}
|
217
264
|
|
218
|
-
void append (const Polyline& polyline
|
265
|
+
void append (const Polyline& polyline)
|
219
266
|
{
|
220
267
|
if (polyline.empty())
|
221
268
|
return;
|
222
269
|
|
223
|
-
|
224
|
-
pbounds.reset();
|
225
|
-
}
|
226
|
-
|
227
|
-
void append (const Line& line)
|
228
|
-
{
|
229
|
-
if (line.empty())
|
230
|
-
return;
|
231
|
-
|
232
|
-
lines.emplace_back(line);
|
233
|
-
pbounds.reset();
|
270
|
+
polylines.emplace_back(polyline);
|
234
271
|
}
|
235
272
|
|
236
273
|
bool triangulate (TrianglePointList* triangles) const
|
237
274
|
{
|
238
|
-
assert(triangles);
|
239
|
-
|
240
|
-
if (!ptriangulator)
|
241
|
-
{
|
242
|
-
ptriangulator.reset(new Triangulator(count_points_for_triangulation()));
|
243
|
-
auto& t = *ptriangulator;
|
244
|
-
|
245
|
-
for (const auto& line : lines)
|
246
|
-
{
|
247
|
-
size_t n = t.begin(line.hole());
|
248
|
-
for (const auto& point : line)
|
249
|
-
t.append(point);
|
250
|
-
t.end(n);
|
251
|
-
}
|
252
|
-
t.triangulate();
|
253
|
-
}
|
254
|
-
|
255
275
|
triangles->clear();
|
256
|
-
return
|
276
|
+
return this->triangles().get(triangles);
|
257
277
|
}
|
258
278
|
|
259
|
-
virtual void fill (Painter* painter, const Color& color) const
|
279
|
+
virtual void fill (Painter* painter, const Color& color) const
|
280
|
+
{
|
281
|
+
triangles().draw(painter, color);
|
282
|
+
}
|
260
283
|
|
261
284
|
virtual void stroke (
|
262
285
|
const Polygon& polygon, Painter* painter, const Color& color) const
|
@@ -275,20 +298,31 @@ namespace Rays
|
|
275
298
|
|
276
299
|
private:
|
277
300
|
|
301
|
+
Triangles& triangles () const
|
302
|
+
{
|
303
|
+
if (!ptriangles)
|
304
|
+
{
|
305
|
+
ptriangles.reset(new Triangles(count_points_for_triangulation()));
|
306
|
+
for (const auto& polyline : polylines)
|
307
|
+
ptriangles->append(polyline);
|
308
|
+
}
|
309
|
+
return *ptriangles;
|
310
|
+
}
|
311
|
+
|
278
312
|
size_t count_points_for_triangulation () const
|
279
313
|
{
|
280
314
|
size_t count = 0;
|
281
|
-
for (const auto&
|
315
|
+
for (const auto& polyline : polylines)
|
282
316
|
{
|
283
|
-
if (can_triangulate(
|
284
|
-
count +=
|
317
|
+
if (can_triangulate(polyline))
|
318
|
+
count += polyline.size();
|
285
319
|
}
|
286
320
|
return count;
|
287
321
|
}
|
288
322
|
|
289
|
-
bool can_triangulate (const
|
323
|
+
bool can_triangulate (const Polyline& polyline) const
|
290
324
|
{
|
291
|
-
return (
|
325
|
+
return (polyline.fill() || polyline.hole()) && polyline.size() >= 3;
|
292
326
|
}
|
293
327
|
|
294
328
|
void stroke_with_width (
|
@@ -349,11 +383,11 @@ namespace Rays
|
|
349
383
|
{
|
350
384
|
assert(painter && color);
|
351
385
|
|
352
|
-
for (const auto&
|
386
|
+
for (const auto& polyline : polylines)
|
353
387
|
{
|
354
|
-
|
355
|
-
painter,
|
356
|
-
&
|
388
|
+
Painter_draw(
|
389
|
+
painter, polyline.loop() ? GL_LINE_LOOP : GL_LINE_STRIP, color,
|
390
|
+
&polyline[0], polyline.size());
|
357
391
|
}
|
358
392
|
}
|
359
393
|
|
@@ -419,14 +453,14 @@ namespace Rays
|
|
419
453
|
assert(clipper);
|
420
454
|
|
421
455
|
clip::Path path;
|
422
|
-
for (const auto&
|
456
|
+
for (const auto& polyline : polygon)
|
423
457
|
{
|
424
|
-
if (!
|
458
|
+
if (!polyline) continue;
|
425
459
|
|
426
|
-
Polyline_get_path(&path,
|
460
|
+
Polyline_get_path(&path, polyline, polyline.hole());
|
427
461
|
if (path.empty()) continue;
|
428
462
|
|
429
|
-
clipper->AddPath(path, type,
|
463
|
+
clipper->AddPath(path, type, polyline.loop());
|
430
464
|
}
|
431
465
|
}
|
432
466
|
|
@@ -465,7 +499,7 @@ namespace Rays
|
|
465
499
|
static bool
|
466
500
|
add_polyline_to_offsetter (
|
467
501
|
clip::ClipperOffset* offsetter, const Polyline& polyline,
|
468
|
-
CapType cap, JoinType join, bool
|
502
|
+
CapType cap, JoinType join, bool fill, bool hole)
|
469
503
|
{
|
470
504
|
assert(offsetter);
|
471
505
|
|
@@ -486,10 +520,10 @@ namespace Rays
|
|
486
520
|
assert(offsetter);
|
487
521
|
|
488
522
|
bool added = false;
|
489
|
-
for (const auto&
|
523
|
+
for (const auto& polyline : polygon.self->polylines)
|
490
524
|
{
|
491
525
|
added |= add_polyline_to_offsetter(
|
492
|
-
offsetter,
|
526
|
+
offsetter, polyline, cap, join, true, polyline.hole());
|
493
527
|
}
|
494
528
|
return added;
|
495
529
|
}
|
@@ -502,12 +536,11 @@ namespace Rays
|
|
502
536
|
if (node.Contour.empty() || node.IsHole())
|
503
537
|
return false;
|
504
538
|
|
505
|
-
Polyline polyline;
|
506
|
-
Polyline_create(&polyline, node.Contour, !node.IsOpen(), false);
|
539
|
+
Polyline polyline = Polyline_create(node.Contour, !node.IsOpen());
|
507
540
|
if (!polyline)
|
508
541
|
return false;
|
509
542
|
|
510
|
-
polygon->self->append(polyline
|
543
|
+
polygon->self->append(polyline);
|
511
544
|
return true;
|
512
545
|
}
|
513
546
|
|
@@ -521,12 +554,11 @@ namespace Rays
|
|
521
554
|
if (!child->IsHole())
|
522
555
|
return;
|
523
556
|
|
524
|
-
Polyline polyline;
|
525
|
-
Polyline_create(&polyline, child->Contour, !child->IsOpen(), true);
|
557
|
+
Polyline polyline = Polyline_create(child->Contour, !child->IsOpen(), true);
|
526
558
|
if (!polyline)
|
527
559
|
continue;
|
528
560
|
|
529
|
-
polygon->self->append(polyline
|
561
|
+
polygon->self->append(polyline);
|
530
562
|
}
|
531
563
|
}
|
532
564
|
|
@@ -605,26 +637,6 @@ namespace Rays
|
|
605
637
|
}
|
606
638
|
|
607
639
|
|
608
|
-
struct PolygonData : public Polygon::Data
|
609
|
-
{
|
610
|
-
|
611
|
-
mutable Polygon::TrianglePointList triangles;
|
612
|
-
|
613
|
-
void fill (Painter* painter, const Color& color) const
|
614
|
-
{
|
615
|
-
if (triangles.empty())
|
616
|
-
{
|
617
|
-
if (!triangulate(&triangles))
|
618
|
-
return;
|
619
|
-
}
|
620
|
-
|
621
|
-
Painter_draw_polygon(
|
622
|
-
painter, GL_TRIANGLES, color, &triangles[0], triangles.size());
|
623
|
-
}
|
624
|
-
|
625
|
-
};// PolygonData
|
626
|
-
|
627
|
-
|
628
640
|
struct RectData : public Polygon::Data
|
629
641
|
{
|
630
642
|
|
@@ -652,11 +664,11 @@ namespace Rays
|
|
652
664
|
|
653
665
|
void fill (Painter* painter, const Color& color) const
|
654
666
|
{
|
655
|
-
if (
|
667
|
+
if (polylines.size() != 1)
|
656
668
|
invalid_state_error(__FILE__, __LINE__);
|
657
669
|
|
658
|
-
const auto& outline =
|
659
|
-
|
670
|
+
const auto& outline = polylines[0];
|
671
|
+
Painter_draw(
|
660
672
|
painter, GL_TRIANGLE_FAN, color, &outline[0], outline.size());
|
661
673
|
}
|
662
674
|
|
@@ -787,10 +799,10 @@ namespace Rays
|
|
787
799
|
};// RectData
|
788
800
|
|
789
801
|
|
790
|
-
struct EllipseData : public
|
802
|
+
struct EllipseData : public Polygon::Data
|
791
803
|
{
|
792
804
|
|
793
|
-
typedef
|
805
|
+
typedef Polygon::Data Super;
|
794
806
|
|
795
807
|
GLenum mode = 0;
|
796
808
|
|
@@ -813,7 +825,7 @@ namespace Rays
|
|
813
825
|
|
814
826
|
void fill (Painter* painter, const Color& color) const
|
815
827
|
{
|
816
|
-
if (
|
828
|
+
if (polylines.size() <= 0)
|
817
829
|
invalid_state_error(__FILE__, __LINE__);
|
818
830
|
|
819
831
|
if (mode == 0)
|
@@ -822,11 +834,11 @@ namespace Rays
|
|
822
834
|
return;
|
823
835
|
}
|
824
836
|
|
825
|
-
if (
|
837
|
+
if (polylines.size() >= 2)
|
826
838
|
invalid_state_error(__FILE__, __LINE__);
|
827
839
|
|
828
|
-
const auto& outline =
|
829
|
-
|
840
|
+
const auto& outline = polylines[0];
|
841
|
+
Painter_draw(painter, mode, color, &outline[0], outline.size());
|
830
842
|
}
|
831
843
|
|
832
844
|
private:
|
@@ -881,7 +893,7 @@ namespace Rays
|
|
881
893
|
hole_x, hole_y, hole_size.x, hole_size.y,
|
882
894
|
radian_from, radian_to, nsegment, seg));
|
883
895
|
}
|
884
|
-
append(Polyline(&points[0], points.size(), true
|
896
|
+
append(Polyline(&points[0], points.size(), true, NULL, NULL, true));
|
885
897
|
}
|
886
898
|
}
|
887
899
|
|
@@ -946,50 +958,51 @@ namespace Rays
|
|
946
958
|
};// EllipseData
|
947
959
|
|
948
960
|
|
949
|
-
|
950
|
-
|
961
|
+
Polygon
|
962
|
+
create_point (coord x, coord y)
|
951
963
|
{
|
952
|
-
|
953
|
-
{
|
954
|
-
case DRAW_POINTS: return "DRAW_POINTS";
|
955
|
-
case DRAW_LINES: return "DRAW_LINES";
|
956
|
-
case DRAW_LINE_STRIP: return "DRAW_LINE_STRIP";
|
957
|
-
case DRAW_TRIANGLES: return "DRAW_TRIANGLES";
|
958
|
-
case DRAW_TRIANGLE_STRIP: return "DRAW_TRIANGLE_STRIP";
|
959
|
-
case DRAW_TRIANGLE_FAN: return "DRAW_TRIANGLE_FAN";
|
960
|
-
case DRAW_QUADS: return "DRAW_QUADS";
|
961
|
-
case DRAW_QUAD_STRIP: return "DRAW_QUAD_STRIP";
|
962
|
-
case DRAW_POLYGON: return "DRAW_POLYGON";
|
963
|
-
default: argument_error(__FILE__, __LINE__, "unknown draw mode");
|
964
|
-
}
|
964
|
+
return create_point(Point(x, y));
|
965
965
|
}
|
966
966
|
|
967
|
-
|
968
|
-
|
967
|
+
Polygon
|
968
|
+
create_point (const Point& point)
|
969
969
|
{
|
970
|
-
|
970
|
+
return create_points(&point, 1);
|
971
971
|
}
|
972
972
|
|
973
|
-
|
974
|
-
create_points (
|
973
|
+
Polygon
|
974
|
+
create_points (const Point* points, size_t size)
|
975
975
|
{
|
976
|
+
Polygon p;
|
976
977
|
for (size_t i = 0; i < size; ++i)
|
977
|
-
|
978
|
+
p.self->append(Polyline(&points[i], 1, false, false));
|
979
|
+
return p;
|
978
980
|
}
|
979
981
|
|
980
|
-
|
981
|
-
|
982
|
+
Polygon
|
983
|
+
create_line (coord x1, coord y1, coord x2, coord y2)
|
982
984
|
{
|
983
|
-
|
984
|
-
|
985
|
+
const Point points[] = {
|
986
|
+
Point(x1, y1),
|
987
|
+
Point(x2, y2)
|
988
|
+
};
|
989
|
+
return create_line(points, 2);
|
985
990
|
}
|
986
991
|
|
987
|
-
|
988
|
-
|
989
|
-
|
992
|
+
Polygon
|
993
|
+
create_line (const Point& p1, const Point& p2)
|
994
|
+
{
|
995
|
+
const Point points[] = {p1, p2};
|
996
|
+
return create_line(points, 2);
|
997
|
+
}
|
998
|
+
|
999
|
+
Polygon
|
1000
|
+
create_line (const Point* points, size_t size, bool loop)
|
990
1001
|
{
|
991
|
-
|
992
|
-
|
1002
|
+
Polygon p;(points, size, loop);
|
1003
|
+
//if (!loop || size < 3)
|
1004
|
+
p.self->append(Polyline(points, size, loop, false));
|
1005
|
+
#if 0
|
993
1006
|
else
|
994
1007
|
{
|
995
1008
|
std::vector<Point> array;
|
@@ -998,105 +1011,133 @@ namespace Rays
|
|
998
1011
|
array.emplace_back(points[0]);
|
999
1012
|
polygon->self->append(Polyline(&array[0], array.size(), true, false));
|
1000
1013
|
}
|
1014
|
+
#endif
|
1015
|
+
return p;
|
1001
1016
|
}
|
1002
1017
|
|
1003
|
-
|
1018
|
+
Polygon
|
1019
|
+
create_line (const Polyline& polyline)
|
1020
|
+
{
|
1021
|
+
return Polygon(polyline);
|
1022
|
+
}
|
1023
|
+
|
1024
|
+
Polygon
|
1025
|
+
create_lines (const Point* points, size_t size)
|
1026
|
+
{
|
1027
|
+
Polygon p;
|
1028
|
+
for (size_t i = 0; i + 1 < size; i += 2)
|
1029
|
+
p.self->append(Polyline(&points[i], 2, false, false));
|
1030
|
+
return p;
|
1031
|
+
}
|
1032
|
+
|
1033
|
+
Polygon
|
1034
|
+
create_triangle (
|
1035
|
+
coord x1, coord y1, coord x2, coord y2, coord x3, coord y3, bool loop)
|
1036
|
+
{
|
1037
|
+
const Point points[] = {Point(x1, y1), Point(x2, y2), Point(x3, y3)};
|
1038
|
+
return create_triangles(points, 3, loop);
|
1039
|
+
}
|
1040
|
+
|
1041
|
+
Polygon
|
1042
|
+
create_triangle (
|
1043
|
+
const Point& p1, const Point& p2, const Point& p3, bool loop)
|
1044
|
+
{
|
1045
|
+
const Point points[] = {p1, p2, p3};
|
1046
|
+
return create_triangles(points, 3, loop);
|
1047
|
+
}
|
1048
|
+
|
1049
|
+
Polygon
|
1004
1050
|
create_triangles (
|
1005
|
-
|
1051
|
+
const Point* points, size_t size, bool loop,
|
1052
|
+
const Color* colors, const Coord3* texcoords)
|
1006
1053
|
{
|
1054
|
+
Polygon p;
|
1007
1055
|
for (size_t i = 0; i + 2 < size; i += 3)
|
1008
|
-
|
1056
|
+
{
|
1057
|
+
p.self->append(Polyline(
|
1058
|
+
&points[i], 3, loop, true,
|
1059
|
+
colors ? &colors[i] : NULL,
|
1060
|
+
texcoords ? &texcoords[i] : NULL));
|
1061
|
+
}
|
1062
|
+
return p;
|
1009
1063
|
}
|
1010
1064
|
|
1011
|
-
|
1012
|
-
create_triangle_strip (
|
1065
|
+
Polygon
|
1066
|
+
create_triangle_strip (
|
1067
|
+
const Point* points, size_t size,
|
1068
|
+
const Color* colors, const Coord3* texcoords)
|
1013
1069
|
{
|
1014
|
-
|
1070
|
+
Polygon p;
|
1071
|
+
if (size < 3) return p;
|
1015
1072
|
|
1016
1073
|
size_t last = size - 1;
|
1017
1074
|
size_t in_last = last % 2 == 0 ? last - 1 : last;
|
1018
1075
|
size_t out_last = last % 2 == 0 ? last : last - 1;
|
1019
1076
|
|
1020
|
-
std::vector<Point>
|
1021
|
-
|
1077
|
+
std::vector<Point> points_;
|
1078
|
+
points_.reserve(size);
|
1079
|
+
points_.emplace_back(points[0]);
|
1022
1080
|
for (size_t i = 1; i <= in_last; i += 2)
|
1023
|
-
|
1081
|
+
points_.emplace_back(points[i]);
|
1024
1082
|
for (size_t i = out_last; i >= 2; i -= 2)
|
1025
|
-
|
1083
|
+
points_.emplace_back(points[i]);
|
1026
1084
|
|
1027
|
-
|
1085
|
+
std::unique_ptr<std::vector<Color>> pcolors_;
|
1086
|
+
if (colors)
|
1087
|
+
{
|
1088
|
+
pcolors_.reset(new decltype(pcolors_)::element_type());
|
1089
|
+
pcolors_->reserve(size);
|
1090
|
+
pcolors_->emplace_back(colors[0]);
|
1091
|
+
for (size_t i = 1; i <= in_last; i += 2)
|
1092
|
+
pcolors_->emplace_back(colors[i]);
|
1093
|
+
for (size_t i = out_last; i >= 2; i -= 2)
|
1094
|
+
pcolors_->emplace_back(colors[i]);
|
1095
|
+
}
|
1096
|
+
|
1097
|
+
std::unique_ptr<std::vector<Coord3>> ptexcoords_;
|
1098
|
+
if (texcoords)
|
1099
|
+
{
|
1100
|
+
ptexcoords_.reset(new decltype(ptexcoords_)::element_type());
|
1101
|
+
ptexcoords_->reserve(size);
|
1102
|
+
ptexcoords_->emplace_back(texcoords[0]);
|
1103
|
+
for (size_t i = 1; i <= in_last; i += 2)
|
1104
|
+
ptexcoords_->emplace_back(texcoords[i]);
|
1105
|
+
for (size_t i = out_last; i >= 2; i -= 2)
|
1106
|
+
ptexcoords_->emplace_back(texcoords[i]);
|
1107
|
+
}
|
1108
|
+
|
1109
|
+
p.self->append(Polyline(
|
1110
|
+
&points_[0], points_.size(), true,
|
1111
|
+
pcolors_ ? &(*pcolors_)[0] : NULL,
|
1112
|
+
ptexcoords_ ? &(*ptexcoords_)[0] : NULL));
|
1028
1113
|
if (size >= 4)
|
1029
|
-
|
1114
|
+
{
|
1115
|
+
p.self->append(Polyline(
|
1116
|
+
&points[1], size - 2, false,
|
1117
|
+
colors ? &colors[1] : NULL,
|
1118
|
+
texcoords ? &texcoords[1] : NULL));
|
1119
|
+
}
|
1120
|
+
return p;
|
1030
1121
|
}
|
1031
1122
|
|
1032
|
-
|
1033
|
-
create_triangle_fan (
|
1123
|
+
Polygon
|
1124
|
+
create_triangle_fan (
|
1125
|
+
const Point* points, size_t size,
|
1126
|
+
const Color* colors, const Coord3* texcoords)
|
1034
1127
|
{
|
1035
|
-
|
1128
|
+
Polygon p(points, size, true, colors, texcoords);
|
1036
1129
|
|
1037
1130
|
Point array[2];
|
1038
1131
|
array[0] = points[0];
|
1039
1132
|
for (size_t i = 2; i < size - 1; ++i)
|
1040
1133
|
{
|
1041
1134
|
array[1] = points[i];
|
1042
|
-
|
1135
|
+
p.self->append(Polyline(
|
1136
|
+
&array[0], 2, false,
|
1137
|
+
colors ? &colors[0] : NULL,
|
1138
|
+
texcoords ? &texcoords[0] : NULL));
|
1043
1139
|
}
|
1044
|
-
|
1045
|
-
|
1046
|
-
static void
|
1047
|
-
create_quads (Polygon* polygon, const Point* points, size_t size, bool loop)
|
1048
|
-
{
|
1049
|
-
for (size_t i = 0; i + 3 < size; i += 4)
|
1050
|
-
polygon->self->append(Polyline(&points[i], 4, loop, true));
|
1051
|
-
}
|
1052
|
-
|
1053
|
-
static void
|
1054
|
-
create_quad_strip (Polygon* polygon, const Point* points, size_t size)
|
1055
|
-
{
|
1056
|
-
if (size < 4) return;
|
1057
|
-
|
1058
|
-
if (size % 2 != 0) --size;
|
1059
|
-
size_t in_last = size - 2;
|
1060
|
-
size_t out_last = size - 1;
|
1061
|
-
|
1062
|
-
std::vector<Point> array;
|
1063
|
-
for (size_t i = 0; i <= in_last; i += 2)
|
1064
|
-
array.emplace_back(points[i]);
|
1065
|
-
for (int i = (int) out_last; i >= 1; i -= 2)
|
1066
|
-
array.emplace_back(points[i]);
|
1067
|
-
|
1068
|
-
polygon->self->append(Polyline(&array[0], array.size(), true));
|
1069
|
-
for (size_t i = 2; i < in_last; i += 2)
|
1070
|
-
polygon->self->append(Polyline(&points[i], 2));
|
1071
|
-
}
|
1072
|
-
|
1073
|
-
Polygon
|
1074
|
-
create_line (coord x1, coord y1, coord x2, coord y2)
|
1075
|
-
{
|
1076
|
-
const Point points[] = {
|
1077
|
-
Point(x1, y1),
|
1078
|
-
Point(x2, y2)
|
1079
|
-
};
|
1080
|
-
return create_line(points, 2);
|
1081
|
-
}
|
1082
|
-
|
1083
|
-
Polygon
|
1084
|
-
create_line (const Point& p1, const Point& p2)
|
1085
|
-
{
|
1086
|
-
const Point points[] = {p1, p2};
|
1087
|
-
return create_line(points, 2);
|
1088
|
-
}
|
1089
|
-
|
1090
|
-
Polygon
|
1091
|
-
create_line (const Point* points, size_t size, bool loop)
|
1092
|
-
{
|
1093
|
-
return Polygon(points, size, loop);
|
1094
|
-
}
|
1095
|
-
|
1096
|
-
Polygon
|
1097
|
-
create_line (const Polyline& polyline)
|
1098
|
-
{
|
1099
|
-
return Polygon(polyline);
|
1140
|
+
return p;
|
1100
1141
|
}
|
1101
1142
|
|
1102
1143
|
Polygon
|
@@ -1148,6 +1189,96 @@ namespace Rays
|
|
1148
1189
|
nsegment);
|
1149
1190
|
}
|
1150
1191
|
|
1192
|
+
Polygon
|
1193
|
+
create_quad (
|
1194
|
+
coord x1, coord y1, coord x2, coord y2,
|
1195
|
+
coord x3, coord y3, coord x4, coord y4,
|
1196
|
+
bool loop)
|
1197
|
+
{
|
1198
|
+
Point points[] = {Point(x1, y1), Point(x2, y2), Point(x3, y3), Point(x4, y4)};
|
1199
|
+
return create_quads(points, 4, loop);
|
1200
|
+
}
|
1201
|
+
|
1202
|
+
Polygon
|
1203
|
+
create_quad (
|
1204
|
+
const Point& p1, const Point& p2, const Point& p3, const Point& p4,
|
1205
|
+
bool loop)
|
1206
|
+
{
|
1207
|
+
Point points[] = {p1, p2, p3, p4};
|
1208
|
+
return create_quads(points, 4, loop);
|
1209
|
+
}
|
1210
|
+
|
1211
|
+
Polygon
|
1212
|
+
create_quads (
|
1213
|
+
const Point* points, size_t size, bool loop,
|
1214
|
+
const Color* colors, const Coord3* texcoords)
|
1215
|
+
{
|
1216
|
+
Polygon p;
|
1217
|
+
for (size_t i = 0; i + 3 < size; i += 4)
|
1218
|
+
{
|
1219
|
+
p.self->append(Polyline(
|
1220
|
+
&points[i], 4, loop, true,
|
1221
|
+
colors ? &colors[i] : NULL,
|
1222
|
+
texcoords ? &texcoords[i] : NULL));
|
1223
|
+
}
|
1224
|
+
return p;
|
1225
|
+
}
|
1226
|
+
|
1227
|
+
Polygon
|
1228
|
+
create_quad_strip (
|
1229
|
+
const Point* points, size_t size,
|
1230
|
+
const Color* colors, const Coord3* texcoords)
|
1231
|
+
{
|
1232
|
+
Polygon p;
|
1233
|
+
if (size < 4) return p;
|
1234
|
+
|
1235
|
+
if (size % 2 != 0) --size;
|
1236
|
+
size_t in_last = size - 2;
|
1237
|
+
size_t out_last = size - 1;
|
1238
|
+
|
1239
|
+
std::vector<Point> points_;
|
1240
|
+
points_.reserve(size);
|
1241
|
+
for (size_t i = 0; i <= in_last; i += 2)
|
1242
|
+
points_.emplace_back(points[i]);
|
1243
|
+
for (int i = (int) out_last; i >= 1; i -= 2)
|
1244
|
+
points_.emplace_back(points[i]);
|
1245
|
+
|
1246
|
+
std::unique_ptr<std::vector<Color>> pcolors_;
|
1247
|
+
if (colors)
|
1248
|
+
{
|
1249
|
+
pcolors_.reset(new decltype(pcolors_)::element_type());
|
1250
|
+
pcolors_->reserve(size);
|
1251
|
+
for (size_t i = 0; i <= in_last; i += 2)
|
1252
|
+
pcolors_->emplace_back(colors[i]);
|
1253
|
+
for (int i = (int) out_last; i >= 1; i -= 2)
|
1254
|
+
pcolors_->emplace_back(colors[i]);
|
1255
|
+
}
|
1256
|
+
|
1257
|
+
std::unique_ptr<std::vector<Coord3>> ptexcoords_;
|
1258
|
+
if (texcoords)
|
1259
|
+
{
|
1260
|
+
ptexcoords_.reset(new decltype(ptexcoords_)::element_type());
|
1261
|
+
ptexcoords_->reserve(size);
|
1262
|
+
for (size_t i = 0; i <= in_last; i += 2)
|
1263
|
+
ptexcoords_->emplace_back(texcoords[i]);
|
1264
|
+
for (int i = (int) out_last; i >= 1; i -= 2)
|
1265
|
+
ptexcoords_->emplace_back(texcoords[i]);
|
1266
|
+
}
|
1267
|
+
|
1268
|
+
p.self->append(Polyline(
|
1269
|
+
&points_[0], points_.size(), true,
|
1270
|
+
pcolors_ ? &(*pcolors_)[0] : NULL,
|
1271
|
+
ptexcoords_ ? &(*ptexcoords_)[0] : NULL));
|
1272
|
+
for (size_t i = 2; i < in_last; i += 2)
|
1273
|
+
{
|
1274
|
+
p.self->append(Polyline(
|
1275
|
+
&points[i], 2, false,
|
1276
|
+
colors ? &colors[i] : NULL,
|
1277
|
+
texcoords ? &texcoords[i] : NULL));
|
1278
|
+
}
|
1279
|
+
return p;
|
1280
|
+
}
|
1281
|
+
|
1151
1282
|
Polygon
|
1152
1283
|
create_ellipse (
|
1153
1284
|
coord x, coord y, coord width, coord height,
|
@@ -1342,54 +1473,36 @@ namespace Rays
|
|
1342
1473
|
|
1343
1474
|
|
1344
1475
|
Polygon::Polygon ()
|
1345
|
-
: self(new PolygonData())
|
1346
1476
|
{
|
1347
1477
|
}
|
1348
1478
|
|
1349
|
-
Polygon::Polygon (
|
1350
|
-
|
1351
|
-
|
1352
|
-
if (!points || size <= 0) return;
|
1353
|
-
|
1354
|
-
create_polygon(this, points, size, loop);
|
1355
|
-
}
|
1356
|
-
|
1357
|
-
Polygon::Polygon (DrawMode mode, const Point* points, size_t size, bool loop)
|
1358
|
-
: self(new PolygonData())
|
1479
|
+
Polygon::Polygon (
|
1480
|
+
const Point* points, size_t size, bool loop,
|
1481
|
+
const Color* colors, const Coord3* texcoords)
|
1359
1482
|
{
|
1360
1483
|
if (!points || size <= 0) return;
|
1361
1484
|
|
1362
|
-
|
1363
|
-
{
|
1364
|
-
case DRAW_POINTS: create_points( this, points, size); break;
|
1365
|
-
case DRAW_LINES: create_lines( this, points, size); break;
|
1366
|
-
case DRAW_LINE_STRIP: create_line_strip( this, points, size, loop); break;
|
1367
|
-
case DRAW_TRIANGLES: create_triangles( this, points, size, loop); break;
|
1368
|
-
case DRAW_TRIANGLE_STRIP: create_triangle_strip(this, points, size); break;
|
1369
|
-
case DRAW_TRIANGLE_FAN: create_triangle_fan( this, points, size); break;
|
1370
|
-
case DRAW_QUADS: create_quads( this, points, size, loop); break;
|
1371
|
-
case DRAW_QUAD_STRIP: create_quad_strip( this, points, size); break;
|
1372
|
-
case DRAW_POLYGON: create_polygon( this, points, size, loop); break;
|
1373
|
-
default:
|
1374
|
-
argument_error(
|
1375
|
-
__FILE__, __LINE__,
|
1376
|
-
Xot::stringf("unknown draw mode '%s'", get_draw_mode_name(mode)));
|
1377
|
-
}
|
1485
|
+
self->append(Polyline(points, size, loop, true, colors, texcoords));
|
1378
1486
|
}
|
1379
1487
|
|
1380
1488
|
Polygon::Polygon (const Polyline& polyline)
|
1381
|
-
: self(new PolygonData())
|
1382
1489
|
{
|
1490
|
+
if (polyline.hole())
|
1491
|
+
argument_error(__FILE__, __LINE__);
|
1492
|
+
|
1383
1493
|
self->append(polyline);
|
1384
1494
|
}
|
1385
1495
|
|
1386
|
-
Polygon::Polygon (const
|
1387
|
-
: self(new PolygonData())
|
1496
|
+
Polygon::Polygon (const Polyline* polylines, size_t size)
|
1388
1497
|
{
|
1389
|
-
if (!
|
1498
|
+
if (!polylines || size <= 0)
|
1499
|
+
return;
|
1500
|
+
|
1501
|
+
if (polylines[0].hole())
|
1502
|
+
argument_error(__FILE__, __LINE__);
|
1390
1503
|
|
1391
1504
|
for (size_t i = 0; i < size; ++i)
|
1392
|
-
self->append(
|
1505
|
+
self->append(polylines[i]);
|
1393
1506
|
}
|
1394
1507
|
|
1395
1508
|
Polygon::Polygon (Data* data)
|
@@ -1418,7 +1531,7 @@ namespace Rays
|
|
1418
1531
|
size_t
|
1419
1532
|
Polygon::size () const
|
1420
1533
|
{
|
1421
|
-
return self->
|
1534
|
+
return self->polylines.size();
|
1422
1535
|
}
|
1423
1536
|
|
1424
1537
|
bool
|
@@ -1426,9 +1539,9 @@ namespace Rays
|
|
1426
1539
|
{
|
1427
1540
|
if (deep)
|
1428
1541
|
{
|
1429
|
-
for (const auto&
|
1542
|
+
for (const auto& polyline : self->polylines)
|
1430
1543
|
{
|
1431
|
-
if (!
|
1544
|
+
if (!polyline.empty())
|
1432
1545
|
return false;
|
1433
1546
|
}
|
1434
1547
|
}
|
@@ -1439,29 +1552,29 @@ namespace Rays
|
|
1439
1552
|
Polygon::const_iterator
|
1440
1553
|
Polygon::begin () const
|
1441
1554
|
{
|
1442
|
-
return self->
|
1555
|
+
return self->polylines.begin();
|
1443
1556
|
}
|
1444
1557
|
|
1445
1558
|
Polygon::const_iterator
|
1446
1559
|
Polygon::end () const
|
1447
1560
|
{
|
1448
|
-
return self->
|
1561
|
+
return self->polylines.end();
|
1449
1562
|
}
|
1450
1563
|
|
1451
|
-
const
|
1564
|
+
const Polyline&
|
1452
1565
|
Polygon::operator [] (size_t index) const
|
1453
1566
|
{
|
1454
|
-
return self->
|
1567
|
+
return self->polylines[index];
|
1455
1568
|
}
|
1456
1569
|
|
1457
1570
|
Polygon::operator bool () const
|
1458
1571
|
{
|
1459
|
-
if (self->
|
1572
|
+
if (self->polylines.empty())
|
1460
1573
|
return true;
|
1461
1574
|
|
1462
|
-
for (const auto&
|
1575
|
+
for (const auto& polyline : self->polylines)
|
1463
1576
|
{
|
1464
|
-
if (
|
1577
|
+
if (polyline) return true;
|
1465
1578
|
}
|
1466
1579
|
|
1467
1580
|
return false;
|
@@ -1479,10 +1592,23 @@ namespace Rays
|
|
1479
1592
|
return self->triangulate(triangles);
|
1480
1593
|
}
|
1481
1594
|
|
1595
|
+
Polygon
|
1596
|
+
operator + (const Polygon& lhs, const Polyline& rhs)
|
1597
|
+
{
|
1598
|
+
std::vector<Polyline> polylines;
|
1599
|
+
for (const auto& polyline : lhs)
|
1600
|
+
polylines.emplace_back(polyline);
|
1601
|
+
polylines.emplace_back(rhs);
|
1602
|
+
return Polygon(&polylines[0], polylines.size());
|
1603
|
+
}
|
1604
|
+
|
1482
1605
|
Polygon
|
1483
1606
|
operator + (const Polygon& lhs, const Polygon& rhs)
|
1484
1607
|
{
|
1485
|
-
|
1608
|
+
std::vector<Polyline> polylines;
|
1609
|
+
for (const auto& polyline : lhs) polylines.emplace_back(polyline);
|
1610
|
+
for (const auto& polyline : rhs) polylines.emplace_back(polyline);
|
1611
|
+
return Polygon(&polylines[0], polylines.size());
|
1486
1612
|
}
|
1487
1613
|
|
1488
1614
|
Polygon
|
@@ -1518,41 +1644,4 @@ namespace Rays
|
|
1518
1644
|
}
|
1519
1645
|
|
1520
1646
|
|
1521
|
-
Polygon::Line::Line ()
|
1522
|
-
: Super(), hole_(false)
|
1523
|
-
{
|
1524
|
-
}
|
1525
|
-
|
1526
|
-
Polygon::Line::Line (const Point* points, size_t size, bool loop, bool hole)
|
1527
|
-
: Super(points, size, loop), hole_(hole)
|
1528
|
-
{
|
1529
|
-
if (!*this)
|
1530
|
-
argument_error(__FILE__, __LINE__);
|
1531
|
-
}
|
1532
|
-
|
1533
|
-
Polygon::Line::Line (const Polyline& polyline, bool hole)
|
1534
|
-
: Super(polyline), hole_(hole)
|
1535
|
-
{
|
1536
|
-
if (!*this)
|
1537
|
-
argument_error(__FILE__, __LINE__);
|
1538
|
-
}
|
1539
|
-
|
1540
|
-
bool
|
1541
|
-
Polygon::Line::hole () const
|
1542
|
-
{
|
1543
|
-
return hole_;
|
1544
|
-
}
|
1545
|
-
|
1546
|
-
Polygon::Line::operator bool () const
|
1547
|
-
{
|
1548
|
-
return Super::operator bool() && (loop() || !hole());
|
1549
|
-
}
|
1550
|
-
|
1551
|
-
bool
|
1552
|
-
Polygon::Line::operator ! () const
|
1553
|
-
{
|
1554
|
-
return !operator bool();
|
1555
|
-
}
|
1556
|
-
|
1557
|
-
|
1558
1647
|
}// Rays
|