siren2 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
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
+