rbpoly2tri 0.0.1

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.
@@ -0,0 +1,16 @@
1
+ require 'mkmf'
2
+
3
+ abs_root = File.expand_path(File.dirname(__FILE__))
4
+
5
+ $defs.push "-DNDEBUG -I#{abs_root}/throw_assert -isystem #{abs_root}/throw_assert"
6
+
7
+ # Collect all the poly2tri sources
8
+ $srcs = %w(rbpoly2tri.cc)
9
+ $srcs += Dir["../poly2tri/common/*.cc"]
10
+ $srcs += Dir["../poly2tri/sweep/*.cc"]
11
+
12
+ $objs = $srcs.map{|src| src.gsub(/\.cc$/, '.o')}
13
+
14
+ $cleanfiles = $objs
15
+
16
+ create_makefile('rbpoly2tri/rbpoly2tri')
@@ -0,0 +1,198 @@
1
+ #include "../poly2tri/poly2tri.h"
2
+ #include <ruby.h>
3
+
4
+ using namespace p2t;
5
+
6
+ extern "C" {
7
+
8
+ /* Converts a ruby [x,y] to a Point */
9
+ static Point
10
+ value_to_point(VALUE ptval)
11
+ {
12
+ Check_Type(ptval, T_ARRAY);
13
+ if (RARRAY_LEN(ptval) != 2) {
14
+ rb_raise(rb_eArgError, "%s", "Points are in format [x,y]");
15
+ }
16
+ return Point(NUM2DBL(rb_ary_entry(ptval, 0)),
17
+ NUM2DBL(rb_ary_entry(ptval, 1)));
18
+ }
19
+
20
+ /* converts ruby point-arrays to vector<Point*> and return it.
21
+ * if mem_track is given, each item returned is also appended
22
+ * to it. This allows the big-sweep delete finish. */
23
+ static std::vector<Point*>
24
+ ptary_to_vector(VALUE ary,
25
+ std::vector<Point*> *mem_track = 0)
26
+ {
27
+ /* We don't want to leave v in an inconsistent state if we
28
+ find an error half-way through ary, so we copy to tmp,
29
+ and then push into v if everything worked. */
30
+ std::vector<Point> tmp;
31
+
32
+ Check_Type(ary, T_ARRAY);
33
+ for (long i = 0; i != RARRAY_LEN(ary); i++) {
34
+ VALUE item = rb_ary_entry(ary, i);
35
+ tmp.push_back(value_to_point(item));
36
+ }
37
+
38
+ std::vector<Point*> result;
39
+ for (size_t i = 0; i != tmp.size(); i++) {
40
+ /* sigh, copy-ctor */
41
+ Point* heaped = new Point(tmp[i].x, tmp[i].y);
42
+ result.push_back(heaped);
43
+ if (mem_track) {
44
+ mem_track->push_back(heaped);
45
+ }
46
+ }
47
+ return result;
48
+ }
49
+
50
+ /* Uh, for some reason, we own the points given to Poly2tri */
51
+ typedef struct {
52
+ CDT *cdt;
53
+ std::vector<Point*> mem_track;
54
+ } CDTWrap;
55
+
56
+ /* Return the underlying CDTWrap* of a value, type safe */
57
+ static inline CDTWrap*
58
+ XWRAP(VALUE x)
59
+ {
60
+ CDTWrap *result;
61
+ Data_Get_Struct(x, CDTWrap, result);
62
+ return result;
63
+ }
64
+
65
+
66
+ static void
67
+ rb_cdt_free(void* ptr)
68
+ {
69
+ CDTWrap *wrap = (CDTWrap*)(ptr);
70
+ if (wrap->cdt) {
71
+ delete wrap->cdt;
72
+ wrap->cdt = 0;
73
+ }
74
+
75
+ /* every point given to the cdt should've ended up here */
76
+ for (size_t i = 0; i != wrap->mem_track.size(); ++i) {
77
+ delete wrap->mem_track[i];
78
+ }
79
+ }
80
+
81
+ static VALUE
82
+ rb_cdt_new(VALUE klass, VALUE polyline)
83
+ {
84
+ CDTWrap* ptr = new CDTWrap;
85
+ ptr->cdt = 0;
86
+
87
+ VALUE r = Data_Wrap_Struct(klass, 0, rb_cdt_free, ptr);
88
+ rb_obj_call_init(r, 1, &polyline);
89
+ return r;
90
+ }
91
+
92
+ static VALUE
93
+ rb_cdt_initialize(VALUE self, VALUE polyline)
94
+ {
95
+ CDTWrap *ptr = XWRAP(self);
96
+
97
+ if (! ptr->cdt) {
98
+ ptr->cdt = new CDT(ptary_to_vector(polyline, &ptr->mem_track));
99
+ }
100
+
101
+ return Qnil;
102
+ }
103
+
104
+ static VALUE
105
+ rb_cdt_add_hole(VALUE self, VALUE polyline)
106
+ {
107
+ CDTWrap *ptr = XWRAP(self);
108
+ ptr->cdt->AddHole(ptary_to_vector(polyline, &ptr->mem_track));
109
+ return Qnil;
110
+ }
111
+
112
+ static VALUE
113
+ rb_cdt_add_point(VALUE self, VALUE rp)
114
+ {
115
+ /* Make sure it can be constructed from the ruby value before we go
116
+ * off allocating memory */
117
+ Point p = value_to_point(rp);
118
+ Point* heaped = new Point(p);
119
+
120
+ /* Add it, and log so it can be free'd */
121
+ CDTWrap* ptr = XWRAP(self);
122
+ ptr->mem_track.push_back(heaped);
123
+ ptr->cdt->AddPoint(heaped);
124
+
125
+ return Qnil;
126
+ }
127
+
128
+ static VALUE
129
+ rb_cdt_triangulate(VALUE self)
130
+ {
131
+ CDTWrap *ptr = XWRAP(self);
132
+
133
+ /* I have never closely considered what would happen to the stack if I were
134
+ * to rb_raise (longjmp) while the C++ stack is unwinding. I'd prefer to
135
+ * keep that a mystery.
136
+ */
137
+
138
+ bool err = false;
139
+
140
+ try {
141
+ ptr->cdt->Triangulate();
142
+ } catch (...) {
143
+ err = true;
144
+ }
145
+
146
+ if (err) {
147
+ rb_raise(rb_eRuntimeError, "Couldnt triangulate (duplicate vertices?)");
148
+ }
149
+
150
+ return Qnil;
151
+ }
152
+
153
+ static VALUE
154
+ rb_cdt_get_triangles(VALUE self)
155
+ {
156
+ CDTWrap *ptr = XWRAP(self);
157
+ CDT *cdt = ptr->cdt;
158
+
159
+ /* Notice I patched this in poly2tri to return a const-ref,
160
+ * as this is a totally needless copy */
161
+ const std::vector<Triangle*>& tris = cdt->GetTriangles();
162
+
163
+ /* Result is a list of polys... */
164
+ VALUE result = rb_ary_new();
165
+ for(size_t i = 0; i != tris.size(); i++) {
166
+ Triangle* tri = tris[i];
167
+ /* rb_tri is the current triangle... */
168
+ VALUE rb_tri = rb_ary_new2(3);
169
+ for(size_t ptidx = 0; ptidx != 3; ptidx++) {
170
+ Point *pt = tri->GetPoint(ptidx);
171
+ /* And we push each point as an [x,y] coordinate */
172
+ rb_ary_push(rb_tri, rb_ary_new3(2, DBL2NUM(pt->x), DBL2NUM(pt->y)));
173
+ }
174
+
175
+ rb_ary_push(result, rb_tri);
176
+ }
177
+
178
+ return result;
179
+ }
180
+
181
+ typedef VALUE(*rubymethod)(...);
182
+
183
+ void Init_rbpoly2tri()
184
+ {
185
+ VALUE m = rb_define_module("Poly2Tri");
186
+
187
+ VALUE k = rb_define_class_under(m, "CDT", rb_cObject);
188
+ rb_define_singleton_method(k, "new", (rubymethod) rb_cdt_new, 1);
189
+ rb_define_method(k, "initialize", (rubymethod) rb_cdt_initialize, 1);
190
+ rb_define_method(k, "add_hole", (rubymethod) rb_cdt_add_hole, 1);
191
+ rb_define_method(k, "add_point", (rubymethod) rb_cdt_add_point, 1);
192
+ rb_define_method(k, "triangulate!", (rubymethod) rb_cdt_triangulate, 0);
193
+ rb_define_method(k, "triangles", (rubymethod) rb_cdt_get_triangles, 0);
194
+ // rb_define_method(k, "map", (rubymethod) rb_cdt_get_map, 0);
195
+
196
+ }
197
+
198
+ } /* extern "C" */
@@ -0,0 +1,19 @@
1
+ /*
2
+ * poly2tri handles input errors with assert(). Some CPP trickery
3
+ * (extconf.rb) puts this directory ahead of the system directories, so
4
+ * we can intercept <assert.h> and <cassert> and give this definition,
5
+ * which throws.
6
+ *
7
+ * Note, since poly2tri expects the program to terminate on a bad
8
+ * assert(), I wouldn't be surprised to learn if it leaves resources
9
+ * dangling in certain code paths.
10
+ *
11
+ */
12
+
13
+ #undef assert
14
+ inline void assert(bool x) {
15
+ if (! x) {
16
+ throw false;
17
+ }
18
+ }
19
+
data/lib/rbpoly2tri.rb ADDED
@@ -0,0 +1 @@
1
+ require 'rbpoly2tri/rbpoly2tri'
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rbpoly2tri
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Mike Owens
9
+ - Dimitri Roche
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2012-11-15 00:00:00.000000000 Z
14
+ dependencies: []
15
+ description: ! 'Ruby Bindings to poly2tri: Constrained Delaunay Triangulation'
16
+ email: dimroc@gmail.com
17
+ executables: []
18
+ extensions:
19
+ - ext/rbpoly2tri/extconf.rb
20
+ extra_rdoc_files: []
21
+ files:
22
+ - lib/rbpoly2tri.rb
23
+ - ext/poly2tri/common/shapes.cc
24
+ - ext/poly2tri/sweep/advancing_front.cc
25
+ - ext/poly2tri/sweep/cdt.cc
26
+ - ext/poly2tri/sweep/sweep.cc
27
+ - ext/poly2tri/sweep/sweep_context.cc
28
+ - ext/rbpoly2tri/rbpoly2tri.cc
29
+ - ext/poly2tri/common/shapes.h
30
+ - ext/poly2tri/common/utils.h
31
+ - ext/poly2tri/poly2tri.h
32
+ - ext/poly2tri/sweep/advancing_front.h
33
+ - ext/poly2tri/sweep/cdt.h
34
+ - ext/poly2tri/sweep/sweep.h
35
+ - ext/poly2tri/sweep/sweep_context.h
36
+ - ext/throw_assert/assert.h
37
+ - ext/rbpoly2tri/extconf.rb
38
+ homepage: https://github.com/dimroc/rbpoly2tri
39
+ licenses: []
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 1.8.24
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: Ruby Bindings to poly2tri
62
+ test_files: []