ruby_clipper 5.0.3 → 6.2.1.5.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,4 @@
1
- /*
1
+ /*
2
2
  * Clipper Ruby Bindings
3
3
  * Copyright 2010 Mike Owens <http://mike.filespanker.com/>
4
4
  * Changed by Dag Rende for Clipper after 2.9
@@ -7,7 +7,7 @@
7
7
  *
8
8
  */
9
9
 
10
- #include <clipper.hpp>
10
+ #include "clipper.hpp"
11
11
  #include <ruby.h>
12
12
 
13
13
  #ifndef DBL2NUM
@@ -26,6 +26,11 @@ static ID id_ex_polygons;
26
26
  static ID id_jtSquare;
27
27
  static ID id_jtMiter;
28
28
  static ID id_jtRound;
29
+ static ID id_etClosedPolygon;
30
+ static ID id_etClosedLine;
31
+ static ID id_etOpenButt;
32
+ static ID id_etOpenSquare;
33
+ static ID id_etOpenRound;
29
34
 
30
35
  static inline Clipper*
31
36
  XCLIPPER(VALUE x)
@@ -35,6 +40,14 @@ XCLIPPER(VALUE x)
35
40
  return clipper;
36
41
  }
37
42
 
43
+ static inline ClipperOffset*
44
+ XCLIPPEROFFSET(VALUE x)
45
+ {
46
+ ClipperOffset* clipperOffset;
47
+ Data_Get_Struct(x, ClipperOffset, clipperOffset);
48
+ return clipperOffset;
49
+ }
50
+
38
51
  static inline PolyFillType
39
52
  sym_to_filltype(VALUE sym)
40
53
  {
@@ -53,6 +66,26 @@ sym_to_filltype(VALUE sym)
53
66
  rb_raise(rb_eArgError, "%s", "Expected :even_odd, :non_zero, :positive or :negative");
54
67
  }
55
68
 
69
+ static inline EndType
70
+ sym_to_endtype(VALUE sym)
71
+ {
72
+ ID inp = rb_to_id(sym);
73
+
74
+ if (inp == id_etClosedPolygon) {
75
+ return etClosedPolygon;
76
+ } else if (inp == id_etClosedLine) {
77
+ return etClosedLine;
78
+ } else if (inp == id_etOpenButt) {
79
+ return etOpenButt;
80
+ } else if (inp == id_etOpenSquare) {
81
+ return etOpenSquare;
82
+ } else if (inp == id_etOpenRound) {
83
+ return etOpenRound;
84
+ }
85
+
86
+ rb_raise(rb_eArgError, "%s", "Expected :etClosedPolygon, :etClosedLine or :etOpenButt or :etOpenSquare or :etOpenRound");
87
+ }
88
+
56
89
  static inline JoinType
57
90
  sym_to_jointype(VALUE sym)
58
91
  {
@@ -71,11 +104,16 @@ sym_to_jointype(VALUE sym)
71
104
 
72
105
  extern "C" {
73
106
 
107
+ static inline IntPoint
108
+ xy_to_intpoint(VALUE px, VALUE py, double multiplier) {
109
+ return IntPoint((long64)(NUM2DBL(px) * multiplier), (long64)(NUM2DBL(py) * multiplier));
110
+ }
111
+
74
112
  static void
75
- ary_to_polygon(VALUE ary, ClipperLib::Polygon* poly, double multiplier)
113
+ ary_to_polygon(VALUE ary, ClipperLib::Path* poly, double multiplier)
76
114
  {
77
115
  const char* earg =
78
- "Polygons have format: [[p0_x, p0_y], [p1_x, p1_y], ...]";
116
+ "Paths have format: [[p0_x, p0_y], [p1_x, p1_y], ...]";
79
117
 
80
118
  Check_Type(ary, T_ARRAY);
81
119
 
@@ -99,6 +137,12 @@ rbclipper_free(void* ptr)
99
137
  delete (Clipper*) ptr;
100
138
  }
101
139
 
140
+ static void
141
+ rbclipperoffset_free(void* ptr)
142
+ {
143
+ delete (ClipperOffset*) ptr;
144
+ }
145
+
102
146
  static VALUE
103
147
  rbclipper_new(VALUE klass)
104
148
  {
@@ -109,30 +153,40 @@ rbclipper_new(VALUE klass)
109
153
  return r;
110
154
  }
111
155
 
156
+ static VALUE
157
+ rbclipperoffset_new(VALUE klass)
158
+ {
159
+ ClipperOffset* ptr = new ClipperOffset;
160
+ VALUE r = Data_Wrap_Struct(klass, 0, rbclipperoffset_free, ptr);
161
+ rb_obj_call_init(r, 0, 0);
162
+ rb_iv_set(r, "@multiplier", INT2NUM(1048576));
163
+ return r;
164
+ }
165
+
112
166
  static VALUE
113
167
  rbclipper_add_polygon_internal(VALUE self, VALUE polygon,
114
168
  PolyType polytype)
115
169
  {
116
- ClipperLib::Polygon tmp;
170
+ ClipperLib::Path tmp;
117
171
  double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
118
172
  ary_to_polygon(polygon, &tmp, multiplier);
119
- XCLIPPER(self)->AddPolygon(tmp, polytype);
173
+ XCLIPPER(self)->AddPath(tmp, polytype, true);
120
174
  return Qnil;
121
175
  }
122
176
 
123
177
  static VALUE
124
178
  rbclipper_add_polygons_internal(VALUE self, VALUE polygonsValue, PolyType polytype) {
125
179
  double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
126
- Polygons polygons;
180
+ Paths polygons;
127
181
  for(long i = 0; i != RARRAY_LEN(polygonsValue); i++) {
128
182
  VALUE sub = rb_ary_entry(polygonsValue, i);
129
183
  Check_Type(sub, T_ARRAY);
130
184
 
131
- ClipperLib::Polygon tmp;
185
+ ClipperLib::Path tmp;
132
186
  ary_to_polygon(sub, &tmp, multiplier);
133
187
  polygons.push_back(tmp);
134
188
  }
135
- XCLIPPER(self)->AddPolygons(polygons, polytype);
189
+ XCLIPPER(self)->AddPaths(polygons, polytype, true);
136
190
  return Qnil;
137
191
  }
138
192
 
@@ -167,6 +221,13 @@ rbclipper_clear(VALUE self)
167
221
  return Qnil;
168
222
  }
169
223
 
224
+ static VALUE
225
+ rbclipperoffset_clear(VALUE self)
226
+ {
227
+ XCLIPPEROFFSET(self)->Clear();
228
+ return Qnil;
229
+ }
230
+
170
231
  static VALUE
171
232
  rbclipper_multiplier(VALUE self)
172
233
  {
@@ -184,10 +245,9 @@ static VALUE
184
245
  rbclipper_orientation(VALUE self, VALUE polygonValue)
185
246
  {
186
247
  double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
187
- ClipperLib::Polygon polygon;
248
+ ClipperLib::Path polygon;
188
249
  ary_to_polygon(polygonValue, &polygon, multiplier);
189
250
 
190
- Polygons resultPolygons;
191
251
  return ClipperLib::Orientation(polygon) ? Qtrue : Qfalse;
192
252
  }
193
253
 
@@ -195,44 +255,50 @@ static VALUE
195
255
  rbclipper_area(VALUE self, VALUE polygonValue)
196
256
  {
197
257
  double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
198
- ClipperLib::Polygon polygon;
258
+ ClipperLib::Path polygon;
199
259
  ary_to_polygon(polygonValue, &polygon, multiplier);
200
260
 
201
- Polygons resultPolygons;
202
261
  return DBL2NUM(ClipperLib::Area(polygon) / multiplier / multiplier);
203
262
  }
204
263
 
264
+ static VALUE
265
+ rbclipper_point_in_polygon(VALUE self, VALUE px, VALUE py, VALUE polygonValue)
266
+ {
267
+ double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
268
+ ClipperLib::Path polygon;
269
+ ary_to_polygon(polygonValue, &polygon, multiplier);
270
+
271
+ return abs(ClipperLib::PointInPolygon(xy_to_intpoint(px, py, multiplier), polygon)) == 1 ? Qtrue : Qfalse;
272
+ }
205
273
 
206
274
  static VALUE
207
- rbclipper_offset_polygons(int argc, VALUE* argv, VALUE self)
275
+ rbclipper_offset_polygons(int argc, VALUE* argv, VALUE self)
208
276
  {
209
277
  double multiplier = NUM2DBL(rb_iv_get(self, "@multiplier"));
210
278
  double inv_multiplier = 1.0 / multiplier;
211
- VALUE polygonsValue, deltaValue, joinTypeValue, miterLimitValue;
279
+ VALUE polygonsValue, deltaValue, joinTypeValue, endTypeValue;
212
280
 
213
- rb_scan_args(argc, argv, "31", &polygonsValue, &deltaValue, &joinTypeValue, &miterLimitValue);
281
+ rb_scan_args(argc, argv, "31", &polygonsValue, &deltaValue, &joinTypeValue, &endTypeValue);
214
282
 
215
- Polygons polygons;
283
+ Paths polygons;
216
284
  for(long i = 0; i != RARRAY_LEN(polygonsValue); i++) {
217
285
  VALUE sub = rb_ary_entry(polygonsValue, i);
218
286
  Check_Type(sub, T_ARRAY);
219
287
 
220
- ClipperLib::Polygon tmp;
288
+ ClipperLib::Path tmp;
221
289
  ary_to_polygon(sub, &tmp, multiplier);
222
290
  polygons.push_back(tmp);
223
291
  }
224
- double miterLimit = 0;
225
- if (!NIL_P(miterLimitValue)) {
226
- miterLimit = NUM2DBL(miterLimitValue);
227
- }
228
292
 
229
- Polygons resultPolygons;
230
- ClipperLib::OffsetPolygons(polygons, resultPolygons, NUM2DBL(deltaValue) * multiplier, sym_to_jointype(joinTypeValue), miterLimit * multiplier);
293
+ Paths resultPaths;
294
+
295
+ XCLIPPEROFFSET(self)->AddPaths(polygons, sym_to_jointype(joinTypeValue), sym_to_endtype(endTypeValue));
296
+ XCLIPPEROFFSET(self)->Execute(resultPaths, NUM2DBL(deltaValue) * multiplier);
231
297
 
232
298
  VALUE r = rb_ary_new();
233
- for(Polygons::iterator i = resultPolygons.begin(); i != resultPolygons.end(); ++i) {
299
+ for(Paths::iterator i = resultPaths.begin(); i != resultPaths.end(); ++i) {
234
300
  VALUE sub = rb_ary_new();
235
- for(Polygon::iterator p = i->begin(); p != i->end(); ++p) {
301
+ for(Path::iterator p = i->begin(); p != i->end(); ++p) {
236
302
  rb_ary_push(sub, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
237
303
  }
238
304
  rb_ary_push(r, sub);
@@ -260,43 +326,18 @@ rbclipper_execute_internal(VALUE self, ClipType cliptype,
260
326
 
261
327
  VALUE r = rb_ary_new();
262
328
  if (resulttype == ID2SYM(id_polygons)) {
263
- Polygons solution;
329
+ Paths solution;
264
330
  XCLIPPER(self)->Execute((ClipType) cliptype,
265
331
  solution,
266
332
  sym_to_filltype(subjfill),
267
333
  sym_to_filltype(clipfill));
268
- for(Polygons::iterator i = solution.begin(); i != solution.end(); ++i) {
334
+ for(Paths::iterator i = solution.begin(); i != solution.end(); ++i) {
269
335
  VALUE sub = rb_ary_new();
270
- for(Polygon::iterator p = i->begin(); p != i->end(); ++p) {
336
+ for(Path::iterator p = i->begin(); p != i->end(); ++p) {
271
337
  rb_ary_push(sub, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
272
338
  }
273
339
  rb_ary_push(r, sub);
274
340
  }
275
- } else {
276
- ExPolygons solution;
277
- XCLIPPER(self)->Execute((ClipType) cliptype,
278
- solution,
279
- sym_to_filltype(subjfill),
280
- sym_to_filltype(clipfill));
281
- for(ExPolygons::iterator i = solution.begin(); i != solution.end(); ++i) {
282
- VALUE expolygon_arr = rb_ary_new();
283
-
284
- VALUE outer_arr = rb_ary_new();
285
- for(Polygon::iterator p = i->outer.begin(); p != i->outer.end(); ++p) {
286
- rb_ary_push(outer_arr, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
287
- }
288
- rb_ary_push(expolygon_arr, outer_arr);
289
-
290
- for(Polygons::iterator ps = i->holes.begin(); ps != i->holes.end(); ++ps) {
291
- VALUE hole_arr = rb_ary_new();
292
- for(Polygon::iterator p = ps->begin(); p != ps->end(); ++p) {
293
- rb_ary_push(hole_arr, rb_ary_new3(2, DBL2NUM(p->X * inv_multiplier), DBL2NUM(p->Y * inv_multiplier)));
294
- }
295
- rb_ary_push(expolygon_arr, hole_arr);
296
- }
297
-
298
- rb_ary_push(r, expolygon_arr);
299
- }
300
341
  }
301
342
  return r;
302
343
  }
@@ -335,10 +376,10 @@ rbclipper_xor(int argc, VALUE* argv, VALUE self)
335
376
  return rbclipper_execute_internal(self, ctXor, subjfill, clipfill, resulttype);
336
377
  }
337
378
 
338
-
339
379
  typedef VALUE (*ruby_method)(...);
340
380
 
341
381
  void Init_clipper() {
382
+
342
383
  id_even_odd = rb_intern("even_odd");
343
384
  id_non_zero = rb_intern("non_zero");
344
385
  id_positive = rb_intern("positive");
@@ -348,6 +389,11 @@ void Init_clipper() {
348
389
  id_jtSquare = rb_intern("jtSquare");
349
390
  id_jtMiter = rb_intern("jtMiter");
350
391
  id_jtRound = rb_intern("jtRound");
392
+ id_etClosedPolygon = rb_intern("etClosedPolygon");
393
+ id_etClosedLine = rb_intern("etClosedLine");
394
+ id_etOpenButt = rb_intern("etOpenButt");
395
+ id_etOpenSquare = rb_intern("etOpenSquare");
396
+ id_etOpenRound = rb_intern("etOpenRound");
351
397
 
352
398
  VALUE mod = rb_define_module("Clipper");
353
399
 
@@ -357,10 +403,12 @@ void Init_clipper() {
357
403
 
358
404
  rb_define_method(k, "orientation",
359
405
  (ruby_method) rbclipper_orientation, 1);
406
+ rb_define_method(k, "pt_in_polygon",
407
+ (ruby_method) rbclipper_point_in_polygon, 3);
360
408
  rb_define_method(k, "area",
361
409
  (ruby_method) rbclipper_area, 1);
362
- rb_define_method(k, "offset_polygons",
363
- (ruby_method) rbclipper_offset_polygons, -1);
410
+ // rb_define_method(k, "offset_polygons",
411
+ // (ruby_method) rbclipper_offset_polygons, -1);
364
412
  rb_define_method(k, "add_subject_polygon",
365
413
  (ruby_method) rbclipper_add_subject_polygon, 1);
366
414
  rb_define_method(k, "add_clip_polygon",
@@ -384,6 +432,19 @@ void Init_clipper() {
384
432
  (ruby_method) rbclipper_multiplier, 0);
385
433
  rb_define_method(k, "multiplier=",
386
434
  (ruby_method) rbclipper_multiplier_eq, 1);
387
- }
435
+
436
+ VALUE ko = rb_define_class_under(mod, "ClipperOffset", rb_cObject);
437
+ rb_define_singleton_method(ko, "new",
438
+ (ruby_method) rbclipperoffset_new, 0);
439
+ rb_define_method(ko, "offset_polygons",
440
+ (ruby_method) rbclipper_offset_polygons, -1);
441
+ rb_define_method(ko, "clear!",
442
+ (ruby_method) rbclipperoffset_clear, 0);
443
+
444
+ rb_define_method(ko, "multiplier",
445
+ (ruby_method) rbclipper_multiplier, 0);
446
+ rb_define_method(ko, "multiplier=",
447
+ (ruby_method) rbclipper_multiplier_eq, 1);
448
+ }
388
449
 
389
450
  } /* extern "C" */
@@ -2,5 +2,5 @@ module Clipper
2
2
  # Keep first two components sync'd to Clipper's major/minor.
3
3
  # Last is our build number based on that. Hopefully there
4
4
  # won't be too much churn re: Clipper's version vs. the bindings.
5
- VERSION = "5.0.3"
5
+ VERSION = "6.2.1.5.2"
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_clipper
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.3
4
+ version: 6.2.1.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Angus Johnson
@@ -12,22 +12,22 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2015-02-23 00:00:00.000000000 Z
15
+ date: 2015-12-27 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: bundler
19
19
  requirement: !ruby/object:Gem::Requirement
20
20
  requirements:
21
- - - "~>"
21
+ - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: '1.0'
23
+ version: 1.0.0
24
24
  type: :development
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
27
27
  requirements:
28
- - - "~>"
28
+ - - ">="
29
29
  - !ruby/object:Gem::Version
30
- version: '1.0'
30
+ version: 1.0.0
31
31
  description: Builds a native ruby extension for Clipper
32
32
  email:
33
33
  - simon@sfcgeorge.co.uk
@@ -76,3 +76,4 @@ signing_key:
76
76
  specification_version: 4
77
77
  summary: Ruby wrapper for Clipper, Angus Johnson's excellent polygon clipping library
78
78
  test_files: []
79
+ has_rdoc: