siren2 0.1.2

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 (97) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +21 -0
  6. data/README.md +36 -0
  7. data/Rakefile +18 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/ext/siren2/extconf.rb +66 -0
  11. data/ext/siren2/inc/bndbox.h +51 -0
  12. data/ext/siren2/inc/bo.h +20 -0
  13. data/ext/siren2/inc/brep.h +17 -0
  14. data/ext/siren2/inc/common.h +98 -0
  15. data/ext/siren2/inc/curve.h +65 -0
  16. data/ext/siren2/inc/curve/bscurve.h +22 -0
  17. data/ext/siren2/inc/curve/bzcurve.h +17 -0
  18. data/ext/siren2/inc/curve/circle.h +29 -0
  19. data/ext/siren2/inc/curve/ellipse.h +15 -0
  20. data/ext/siren2/inc/curve/hyperbola.h +15 -0
  21. data/ext/siren2/inc/curve/line.h +17 -0
  22. data/ext/siren2/inc/curve/offsetcurve.h +15 -0
  23. data/ext/siren2/inc/curve/parabola.h +15 -0
  24. data/ext/siren2/inc/filler.h +26 -0
  25. data/ext/siren2/inc/heal.h +19 -0
  26. data/ext/siren2/inc/io/iges.h +19 -0
  27. data/ext/siren2/inc/io/step.h +18 -0
  28. data/ext/siren2/inc/io/stl.h +13 -0
  29. data/ext/siren2/inc/offset.h +35 -0
  30. data/ext/siren2/inc/shape.h +140 -0
  31. data/ext/siren2/inc/shape/chunk.h +26 -0
  32. data/ext/siren2/inc/shape/compound.h +22 -0
  33. data/ext/siren2/inc/shape/edge.h +50 -0
  34. data/ext/siren2/inc/shape/face.h +67 -0
  35. data/ext/siren2/inc/shape/shell.h +21 -0
  36. data/ext/siren2/inc/shape/solid.h +41 -0
  37. data/ext/siren2/inc/shape/vertex.h +23 -0
  38. data/ext/siren2/inc/shape/wire.h +31 -0
  39. data/ext/siren2/inc/siren.h +39 -0
  40. data/ext/siren2/inc/surface/dummy +0 -0
  41. data/ext/siren2/inc/topalgo.h +52 -0
  42. data/ext/siren2/inc/trans.h +48 -0
  43. data/ext/siren2/inc/vec.h +65 -0
  44. data/ext/siren2/src/bndbox.cpp +343 -0
  45. data/ext/siren2/src/bo.cpp +66 -0
  46. data/ext/siren2/src/brep.cpp +69 -0
  47. data/ext/siren2/src/common.cpp +18 -0
  48. data/ext/siren2/src/curve.cpp +75 -0
  49. data/ext/siren2/src/curve/bscurve.cpp +118 -0
  50. data/ext/siren2/src/curve/bzcurve.cpp +55 -0
  51. data/ext/siren2/src/curve/circle.cpp +146 -0
  52. data/ext/siren2/src/curve/ellipse.cpp +17 -0
  53. data/ext/siren2/src/curve/hyperbola.cpp +17 -0
  54. data/ext/siren2/src/curve/line.cpp +24 -0
  55. data/ext/siren2/src/curve/offsetcurve.cpp +17 -0
  56. data/ext/siren2/src/curve/parabola.cpp +17 -0
  57. data/ext/siren2/src/filler.cpp +191 -0
  58. data/ext/siren2/src/heal.cpp +92 -0
  59. data/ext/siren2/src/io/iges.cpp +85 -0
  60. data/ext/siren2/src/io/step.cpp +47 -0
  61. data/ext/siren2/src/io/stl.cpp +22 -0
  62. data/ext/siren2/src/offset.cpp +256 -0
  63. data/ext/siren2/src/shape.cpp +617 -0
  64. data/ext/siren2/src/shape/chunk.cpp +65 -0
  65. data/ext/siren2/src/shape/compound.cpp +96 -0
  66. data/ext/siren2/src/shape/edge.cpp +254 -0
  67. data/ext/siren2/src/shape/face.cpp +366 -0
  68. data/ext/siren2/src/shape/shell.cpp +41 -0
  69. data/ext/siren2/src/shape/solid.cpp +256 -0
  70. data/ext/siren2/src/shape/vertex.cpp +68 -0
  71. data/ext/siren2/src/shape/wire.cpp +100 -0
  72. data/ext/siren2/src/siren.cpp +80 -0
  73. data/ext/siren2/src/surface/dummy +0 -0
  74. data/ext/siren2/src/topalgo.cpp +246 -0
  75. data/ext/siren2/src/trans.cpp +330 -0
  76. data/ext/siren2/src/vec.cpp +454 -0
  77. data/lib/io/dxf.rb +68 -0
  78. data/lib/io/plot.rb +38 -0
  79. data/lib/io/ply.rb +57 -0
  80. data/lib/io/stl.rb +35 -0
  81. data/lib/io/svg.rb +44 -0
  82. data/lib/kernel/array.rb +133 -0
  83. data/lib/kernel/float.rb +15 -0
  84. data/lib/shape.rb +157 -0
  85. data/lib/shape/compound.rb +11 -0
  86. data/lib/shape/edge.rb +15 -0
  87. data/lib/shape/face.rb +7 -0
  88. data/lib/shape/shell.rb +21 -0
  89. data/lib/shape/solid.rb +10 -0
  90. data/lib/shape/vertex.rb +7 -0
  91. data/lib/shape/wire.rb +14 -0
  92. data/lib/shapes.rb +52 -0
  93. data/lib/siren.rb +166 -0
  94. data/lib/siren2/version.rb +3 -0
  95. data/lib/vec.rb +81 -0
  96. data/siren2.gemspec +28 -0
  97. metadata +195 -0
@@ -0,0 +1,41 @@
1
+ #include "shape/shell.h"
2
+
3
+ VALUE sr_cShell;
4
+
5
+ SR_SHAPE_GET(Shell, shell)
6
+ SR_SHAPE_CHECK(Shell, shell)
7
+
8
+ bool siren_shell_install()
9
+ {
10
+ SR_SHAPE_INIT(Shell)
11
+ rb_define_method(sr_cShell, "initialize", RUBY_METHOD_FUNC(siren_shape_init), -1);
12
+ rb_define_singleton_method(sr_cShell, "make", RUBY_METHOD_FUNC(siren_shell_make), -1);
13
+ rb_define_singleton_method(sr_cShell, "sew", RUBY_METHOD_FUNC(siren_shell_make), -1);
14
+ return true;
15
+ }
16
+
17
+ VALUE siren_shell_make(int argc, VALUE* argv, VALUE self)
18
+ {
19
+ VALUE ary;
20
+ VALUE tol;
21
+ rb_scan_args(argc, argv, "11", &ary, &tol);
22
+ BRepBuilderAPI_Sewing sewer;
23
+ sewer.Init();
24
+ if (argc == 2 && NUM2DBL(tol) >= 0.0) {
25
+ sewer.SetTolerance(NUM2DBL(tol));
26
+ }
27
+ int len = RARRAY_LEN(ary);
28
+ for (int i=0; i < len; i++) {
29
+ VALUE item = RARRAY_AREF(ary, i);
30
+ TopoDS_Shape* shape = siren_shape_get(item);
31
+ if (shape->IsNull()) {
32
+ continue;
33
+ }
34
+ TopExp_Explorer ex(*shape, TopAbs_FACE);
35
+ for (; ex.More(); ex.Next()) {
36
+ sewer.Add(ex.Current());
37
+ }
38
+ }
39
+ sewer.Perform();
40
+ return siren_shape_new(sewer.SewedShape());
41
+ }
@@ -0,0 +1,256 @@
1
+ #include "shape/solid.h"
2
+
3
+ VALUE sr_cSolid;
4
+
5
+ SR_SHAPE_GET(Solid, solid)
6
+ SR_SHAPE_CHECK(Solid, solid)
7
+
8
+ bool siren_solid_install()
9
+ {
10
+ SR_SHAPE_INIT(Solid)
11
+ rb_define_method(sr_cSolid, "initialize", RUBY_METHOD_FUNC(siren_solid_init), -1);
12
+ rb_define_singleton_method(sr_cSolid, "box", RUBY_METHOD_FUNC(siren_solid_box), -1);
13
+ rb_define_singleton_method(sr_cSolid, "box2p", RUBY_METHOD_FUNC(siren_solid_box2p), -1);
14
+ rb_define_singleton_method(sr_cSolid, "boxax", RUBY_METHOD_FUNC(siren_solid_boxax), -1);
15
+ rb_define_singleton_method(sr_cSolid, "sphere", RUBY_METHOD_FUNC(siren_solid_sphere), -1);
16
+ rb_define_singleton_method(sr_cSolid, "cylinder", RUBY_METHOD_FUNC(siren_solid_cylinder), -1);
17
+ rb_define_singleton_method(sr_cSolid, "cone", RUBY_METHOD_FUNC(siren_solid_cone), -1);
18
+ rb_define_singleton_method(sr_cSolid, "torus", RUBY_METHOD_FUNC(siren_solid_torus), -1);
19
+ rb_define_singleton_method(sr_cSolid, "halfspace", RUBY_METHOD_FUNC(siren_solid_halfspace), -1);
20
+ rb_define_singleton_method(sr_cSolid, "prism", RUBY_METHOD_FUNC(siren_solid_prism), -1);
21
+ rb_define_singleton_method(sr_cSolid, "revol", RUBY_METHOD_FUNC(siren_solid_revol), -1);
22
+ rb_define_singleton_method(sr_cSolid, "revolution", RUBY_METHOD_FUNC(siren_solid_revolution), -1);
23
+ rb_define_singleton_method(sr_cSolid, "wedge", RUBY_METHOD_FUNC(siren_solid_wedge), -1);
24
+ return true;
25
+ }
26
+
27
+ VALUE siren_solid_init(int argc, VALUE* argv, VALUE self)
28
+ {
29
+ VALUE* a;
30
+ rb_scan_args(argc, argv, "1", &a);
31
+ int len = RARRAY_LEN(a);
32
+ if (argc == 0 || len == 0) {
33
+ rb_raise(Qnil, "No shapes specified.");
34
+ }
35
+ BRepBuilderAPI_MakeSolid solid_maker;
36
+ for (int i = 0; i < len; i++) {
37
+ TopoDS_Shell shell = siren_shell_get(a[i]);
38
+ solid_maker.Add(shell);
39
+ }
40
+ if (!solid_maker.IsDone()) {
41
+ rb_raise(Qnil, "Failed to make a Solid.");
42
+ }
43
+ TopoDS_Shape shape = solid_maker.Shape();
44
+ if (shape.IsNull()) {
45
+ rb_raise(Qnil, "Failed to make a Solid.");
46
+ }
47
+ auto p = siren_shape_get(self);
48
+ *p = shape;
49
+ return self;
50
+ }
51
+
52
+ VALUE siren_solid_box(int argc, VALUE* argv, VALUE self)
53
+ {
54
+ VALUE size, pos;
55
+ rb_scan_args(argc, argv, "02", &size, &pos);
56
+
57
+ Standard_Real sx, sy, sz;
58
+ if (argc >= 1) {
59
+ siren_ary_to_xyz(size, sx, sy, sz);
60
+ }
61
+ else {
62
+ sx = 1.0; sy = 1.0; sz = 1.0;
63
+ }
64
+
65
+ gp_Pnt op;
66
+ if (argc >= 2) {
67
+ Standard_Real px, py, pz;
68
+ siren_ary_to_xyz(pos, px, py, pz);
69
+ op = gp_Pnt(px, py, pz);
70
+ }
71
+ else {
72
+ op = gp_Pnt(0., 0., 0.);
73
+ }
74
+ if (std::fabs(sx * sy * sz) == 0.0) {
75
+ rb_raise(Qnil,
76
+ "Failed to make solid. Incorrect size specified.");
77
+ }
78
+ BRepPrimAPI_MakeBox api(op, sx, sy, sz);
79
+ return siren_shape_new(api.Shape());
80
+ }
81
+
82
+ VALUE siren_solid_box2p(int argc, VALUE* argv, VALUE self)
83
+ {
84
+ VALUE p1, p2;
85
+ rb_scan_args(argc, argv, "02", &p1, &p2);
86
+
87
+ Standard_Real x1 = 0.0, y1 = 0.0, z1 = 0.0;
88
+ Standard_Real x2 = 1.0, y2 = 1.0, z2 = 1.0;
89
+
90
+ if (argc >= 1) {
91
+ siren_ary_to_xyz(p1, x1, y1, z1);
92
+ }
93
+ if (argc >= 2) {
94
+ siren_ary_to_xyz(p2, x2, y2, z2);
95
+ }
96
+
97
+ gp_Pnt point1(x1, x1, x1);
98
+ gp_Pnt point2(x2, x2, x2);
99
+
100
+ BRepPrimAPI_MakeBox api(point1, point2);
101
+ return siren_shape_new(api.Shape());
102
+ }
103
+
104
+ VALUE siren_solid_boxax(int argc, VALUE* argv, VALUE self)
105
+ {
106
+ VALUE size, pos, dir;
107
+ rb_scan_args(argc, argv, "3", &size, &pos, &dir);
108
+
109
+ Standard_Real sx, sy, sz;
110
+ siren_ary_to_xyz(size, sx, sy, sz);
111
+
112
+ Standard_Real px, py, pz;
113
+ siren_ary_to_xyz(pos, px, py, pz);
114
+
115
+ Standard_Real dx, dy, dz;
116
+ siren_ary_to_xyz(dir, dx, dy, dz);
117
+
118
+ gp_Ax2 ax(gp_Pnt(px, py, pz), gp_Dir(dx, dy, dz));
119
+
120
+ BRepPrimAPI_MakeBox api(ax, sx, sy, sz);
121
+ return siren_shape_new(api.Shape());
122
+ }
123
+
124
+ VALUE siren_solid_sphere(int argc, VALUE* argv, VALUE self)
125
+ {
126
+ VALUE r = 1.0;
127
+ VALUE pos;
128
+ rb_scan_args(argc, argv, "02", &r, &pos);
129
+
130
+ Check_Type(r, T_FLOAT);
131
+
132
+ gp_Pnt op;
133
+ if (argc == 2) {
134
+ Standard_Real px, py, pz;
135
+ siren_ary_to_xyz(pos, px, py, pz);
136
+ op = gp_Pnt(px, py, pz);
137
+ }
138
+ else {
139
+ op = gp_Pnt(0., 0., 0.);
140
+ }
141
+
142
+ if (NUM2DBL(r) < 0) {
143
+ rb_raise(Qnil, "Failed to make solid."
144
+ " Specified radius value below 0.");
145
+ }
146
+
147
+ BRepPrimAPI_MakeSphere api(op, NUM2DBL(r));
148
+ return siren_shape_new(api.Shape());
149
+ }
150
+
151
+ VALUE siren_solid_cylinder(int argc, VALUE* argv, VALUE self)
152
+ {
153
+ VALUE pos, norm;
154
+ VALUE r, h, a;
155
+ rb_scan_args(argc, argv, "5", &pos, &norm, &r, &h, &a);
156
+
157
+ Check_Type(r, T_FLOAT);
158
+ Check_Type(h, T_FLOAT);
159
+ Check_Type(a, T_FLOAT);
160
+
161
+ gp_Ax2 ax = siren_ary_to_ax2(pos, norm);
162
+
163
+ BRepPrimAPI_MakeCylinder api(ax, NUM2DBL(r), NUM2DBL(h), NUM2DBL(a));
164
+
165
+ return siren_shape_new(api.Shape());
166
+ }
167
+
168
+ VALUE siren_solid_cone(int argc, VALUE* argv, VALUE self)
169
+ {
170
+ VALUE pos, norm;
171
+ VALUE r1, r2, h, ang;
172
+ rb_scan_args(argc, argv, "6", &pos, &norm, &r1, &r2, &h, &ang);
173
+
174
+ Check_Type(r1, T_FLOAT);
175
+ Check_Type(r2, T_FLOAT);
176
+ Check_Type(h, T_FLOAT);
177
+ Check_Type(ang, T_FLOAT);
178
+
179
+ gp_Ax2 ax = siren_ary_to_ax2(pos, norm);
180
+
181
+ BRepPrimAPI_MakeCone api(ax, NUM2DBL(r1), NUM2DBL(r2), NUM2DBL(h), NUM2DBL(ang));
182
+ return siren_shape_new(api.Shape());
183
+ }
184
+
185
+ VALUE siren_solid_torus(int argc, VALUE* argv, VALUE self)
186
+ {
187
+ VALUE r1, r2, ang;
188
+ VALUE pos, norm;
189
+ rb_scan_args(argc, argv, "5", &pos, &norm, &r1, &r2, &ang);
190
+
191
+ Check_Type(r1, T_FLOAT);
192
+ Check_Type(r2, T_FLOAT);
193
+ Check_Type(ang, T_FLOAT);
194
+
195
+ gp_Ax2 ax = siren_ary_to_ax2(pos, norm);
196
+
197
+ BRepPrimAPI_MakeTorus api(ax, NUM2DBL(r1), NUM2DBL(r2), NUM2DBL(ang));
198
+ return siren_shape_new(api.Shape());
199
+ }
200
+
201
+ VALUE siren_solid_halfspace(int argc, VALUE* argv, VALUE self)
202
+ {
203
+ VALUE surf, refpnt;
204
+ rb_scan_args(argc, argv, "2", &surf, &refpnt);
205
+
206
+ siren_shape_check(surf);
207
+
208
+ TopoDS_Shape* shape = siren_shape_get(surf);
209
+ TopoDS_Solid solid;
210
+ gp_Pnt pnt = siren_ary_to_pnt(refpnt);
211
+ if (shape->ShapeType() == TopAbs_FACE) {
212
+ solid = BRepPrimAPI_MakeHalfSpace(TopoDS::Face(*shape), pnt);
213
+ }
214
+ else if (shape->ShapeType() == TopAbs_SHELL) {
215
+ solid = BRepPrimAPI_MakeHalfSpace(TopoDS::Shell(*shape), pnt);
216
+ }
217
+ else {
218
+ rb_raise(Qnil, "Specified shape type is not FACE or SHELL.");
219
+ }
220
+ return siren_shape_new(solid);
221
+ }
222
+
223
+ VALUE siren_solid_prism(int argc, VALUE* argv, VALUE self)
224
+ {
225
+ rb_raise(Qnil, "Not implemented.");
226
+ return Qnil;
227
+ }
228
+
229
+ VALUE siren_solid_revol(int argc, VALUE* argv, VALUE self)
230
+ {
231
+ rb_raise(Qnil, "Not implemented.");
232
+ return Qnil;
233
+ }
234
+
235
+ VALUE siren_solid_revolution(int argc, VALUE* argv, VALUE self)
236
+ {
237
+ rb_raise(Qnil, "Not implemented.");
238
+ return Qnil;
239
+ }
240
+
241
+ VALUE siren_solid_wedge(int argc, VALUE* argv, VALUE self)
242
+ {
243
+ VALUE dx = DBL2NUM(1.0), dy = DBL2NUM(1.0), dz = DBL2NUM(1.0),
244
+ x = DBL2NUM(0.5), z = DBL2NUM(0.5), X = DBL2NUM(0.5), Z = DBL2NUM(0.5);
245
+ rb_scan_args(argc, argv, "07", &dx, &dy, &dz, &x, &z, &X, &Z);
246
+ try {
247
+ BRepPrimAPI_MakeWedge api(NUM2DBL(dx), NUM2DBL(dy), NUM2DBL(dz),
248
+ NUM2DBL(x), NUM2DBL(z), NUM2DBL(X), NUM2DBL(Z));
249
+ TopoDS_Shape s = api.Shape();
250
+ return siren_shape_new(s);
251
+ }
252
+ catch (...) {
253
+ rb_raise(Qnil, "Failed to make a wedge.");
254
+ }
255
+ return Qnil;
256
+ }
@@ -0,0 +1,68 @@
1
+ #include "shape/vertex.h"
2
+
3
+ #define rb_array_p(x) RB_TYPE_P(x, T_ARRAY)
4
+
5
+ VALUE sr_cVertex;
6
+
7
+ SR_SHAPE_GET(Vertex, vertex)
8
+ SR_SHAPE_CHECK(Vertex, vertex)
9
+
10
+ bool siren_vertex_install()
11
+ {
12
+ SR_SHAPE_INIT(Vertex)
13
+ rb_define_method(sr_cVertex, "initialize", RUBY_METHOD_FUNC(siren_vertex_init), -1);
14
+ rb_define_method(sr_cVertex, "xyz", RUBY_METHOD_FUNC(siren_vertex_xyz), -1);
15
+ rb_define_method(sr_cVertex, "to_a", RUBY_METHOD_FUNC(siren_vertex_xyz), -1);
16
+ rb_define_method(sr_cVertex, "to_v", RUBY_METHOD_FUNC(siren_vertex_to_v), -1);
17
+ return true;
18
+ }
19
+
20
+ VALUE siren_vertex_init(int argc, VALUE* argv, VALUE self)
21
+ {
22
+ VALUE* a;
23
+ VALUE len;
24
+ rb_scan_args(argc, argv, "*", &a, &len);
25
+
26
+ Standard_Real x = 0.0, y = 0.0, z = 0.0;
27
+ if (len > 0 && rb_array_p(a[0])) {
28
+ gp_Pnt p = siren_ary_to_pnt(a[0]);
29
+ x = p.X(); y = p.Y(); z = p.Z();
30
+ }
31
+ else {
32
+ if (len >= 1) {
33
+ if (FIXNUM_P(a[0]))
34
+ x = DBL2NUM(a[0]);
35
+ else if (RB_FLOAT_TYPE_P(a[0]))
36
+ x = VALUE(a[0]);
37
+ }
38
+ if (len >= 2) {
39
+ if (FIXNUM_P(a[1]))
40
+ y = DBL2NUM(a[1]);
41
+ else if (RB_FLOAT_TYPE_P(a[1]))
42
+ y = VALUE(a[1]);
43
+ }
44
+ if (len >= 3) {
45
+ if (FIXNUM_P(a[2]))
46
+ z = DBL2NUM(a[2]);
47
+ else if (RB_FLOAT_TYPE_P(a[2]))
48
+ z = VALUE(a[2]);
49
+ }
50
+ }
51
+ TopoDS_Vertex v = BRepBuilderAPI_MakeVertex(gp_Pnt(x, y, z));
52
+ auto p = siren_shape_get(self);
53
+ *p = v;
54
+ return self;
55
+ }
56
+
57
+ VALUE siren_vertex_xyz(int argc, VALUE* argv, VALUE self)
58
+ {
59
+ TopoDS_Vertex vertex = siren_vertex_get(self);
60
+ return siren_pnt_to_ary(BRep_Tool::Pnt(vertex));
61
+ }
62
+
63
+ VALUE siren_vertex_to_v(int argc, VALUE* argv, VALUE self)
64
+ {
65
+ TopoDS_Vertex vertex = siren_vertex_get(self);
66
+ gp_Pnt p = BRep_Tool::Pnt(vertex);
67
+ return siren_vec_new(p.X(), p.Y(), p.Z());
68
+ }
@@ -0,0 +1,100 @@
1
+ #include "shape/wire.h"
2
+ #include "shape.h"
3
+
4
+ VALUE sr_cWire;
5
+
6
+ SR_SHAPE_GET(Wire, wire)
7
+ SR_SHAPE_CHECK(Wire, wire)
8
+
9
+ bool siren_wire_install()
10
+ {
11
+ SR_SHAPE_INIT(Wire)
12
+ rb_define_method(sr_cWire, "initialize", RUBY_METHOD_FUNC(siren_shape_init), -1);
13
+ rb_define_method(sr_cWire, "ordered_edges", RUBY_METHOD_FUNC(siren_wire_ordered_edges), -1);
14
+ rb_define_singleton_method(sr_cWire, "make", RUBY_METHOD_FUNC(siren_wire_make), -1);
15
+ rb_define_singleton_method(sr_cWire, "join", RUBY_METHOD_FUNC(siren_wire_make), -1);
16
+ return true;
17
+ }
18
+
19
+ VALUE siren_wire_ordered_edges(int argc, VALUE* argv, VALUE self)
20
+ {
21
+ TopoDS_Wire wire = siren_wire_get(self);
22
+ VALUE res = rb_ary_new();
23
+ for (BRepTools_WireExplorer exp(wire); exp.More(); exp.Next()) {
24
+ TopoDS_Edge e = exp.Current();
25
+ rb_ary_push(res, siren_shape_new(e));
26
+ }
27
+ return res;
28
+ }
29
+
30
+ VALUE siren_wire_make(int argc, VALUE* argv, VALUE self)
31
+ {
32
+ VALUE objs;
33
+ VALUE tol;
34
+ rb_scan_args(argc, argv, "11", &objs, &tol);
35
+ BRepBuilderAPI_MakeWire api;
36
+ #ifdef USE_WIRE_FIX
37
+ ShapeFix_Wire sfw;
38
+ handle<ShapeExtend_WireData> wd = new ShapeExtend_WireData();
39
+ ShapeFix_ShapeTolerance FTol;
40
+ int osize = RARRAY_LEN(objs);
41
+ for (int i = 0; i < osize ; i++) {
42
+ VALUE obj = RARRAY_AREF(objs, i);
43
+ TopoDS_Shape* s = siren_shape_get(obj);
44
+ if (s->IsNull()) {
45
+ continue;
46
+ }
47
+ TopExp_Explorer exp(*s, TopAbs_EDGE);
48
+ for (; exp.More(); exp.Next()) {
49
+ wd->Add(TopoDS::Edge(exp.Current()));
50
+ }
51
+ }
52
+ if (wd->NbEdges() == 0) {
53
+ return Qnil;
54
+ }
55
+ sfw.Load(wd);
56
+ sfw.Perform();
57
+ for (int i = 1; i <= sfw.NbEdges(); i ++) {
58
+ TopoDS_Edge e = sfw.WireData()->Edge(i);
59
+ FTol.SetTolerance(e, argc == 1 ? 0.01 : NUM2DBL(tol), TopAbs_VERTEX);
60
+ api.Add(e);
61
+ }
62
+ return siren_shape_new(api.Shape());
63
+ #else
64
+ ShapeFix_ShapeTolerance fixtol;
65
+ bool has_tol = argc == 2;
66
+ for (int i = 0; i < RARRAY_LEN(objs); i++) {
67
+ TopoDS_Shape* shape = siren_shape_get(RARRAY_AREF(objs, i));
68
+ if (shape->ShapeType() == TopAbs_EDGE) {
69
+ if (has_tol) {
70
+ fixtol.SetTolerance(*shape, NUM2DBL(tol), TopAbs_VERTEX);
71
+ }
72
+ api.Add(TopoDS::Edge(*shape));
73
+ }
74
+ else if (shape->ShapeType() == TopAbs_WIRE) {
75
+ if (has_tol) {
76
+ fixtol.SetTolerance(*shape, NUM2DBL(tol), TopAbs_VERTEX);
77
+ fixtol.SetTolerance(*shape, NUM2DBL(tol), TopAbs_EDGE);
78
+ }
79
+ api.Add(TopoDS::Wire(*shape));
80
+ }
81
+ }
82
+ api.Build();
83
+ if (!api.IsDone()) {
84
+ switch (api.Error()) {
85
+ case BRepBuilderAPI_EmptyWire:
86
+ rb_raise(Qnil, "Failed to make a wire. (Empty wire)");
87
+ break;
88
+ case BRepBuilderAPI_DisconnectedWire:
89
+ rb_raise(Qnil, "Failed to make a wire. (Disconnected wire)");
90
+ break;
91
+ case BRepBuilderAPI_NonManifoldWire:
92
+ rb_raise(Qnil, "Failed to make a wire. (Non manifold wire)");
93
+ break;
94
+ default: break;
95
+ }
96
+ }
97
+ #endif
98
+ return siren_shape_new(api.Wire());
99
+ }
100
+