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,65 @@
1
+ #ifdef SR_ENABLE_CHUNK
2
+
3
+ #include "shape/chunk.h"
4
+
5
+ VALUE sr_cChunk;
6
+
7
+ SR_SHAPE_GET(CompSolid, chunk)
8
+ SR_SHAPE_CHECK(CompSolid, chunk)
9
+
10
+ bool siren_chunk_install()
11
+ {
12
+ SR_SHAPE_INIT(CompSolid)
13
+ rb_define_method(sr_cChunk, "initialize", RUBY_METHOD_FUNC(siren_chunk_init), -1);
14
+ rb_define_method(sr_cChunk, "to_solid", RUBY_METHOD_FUNC(siren_chunk_to_solid), -1);
15
+ return true;
16
+ }
17
+
18
+ struct RClass* siren_chunk_rclass()
19
+ {
20
+ struct RClass* sr_mSiren = rb_module_get("Siren");
21
+ return rb_class_ptr(_const_get(rb_obj_value(sr_mSiren), rb_intern_lit("Chunk")));
22
+ }
23
+
24
+ VALUE siren_chunk_obj()
25
+ {
26
+ struct RClass* sr_mSiren = rb_module_get("Siren");
27
+ return rb_const_get(rb_obj_value(sr_mSiren), rb_intern_lit("Chunk"));
28
+ }
29
+
30
+ VALUE siren_chunk_init(int argc, VALUE* argv, VALUE self)
31
+ {
32
+ VALUE* a;
33
+ rb_scan_args(argc, argv, "1", &a);
34
+ int len = RARRAY_LEN(a);
35
+
36
+ TopoDS_CompSolid cs;
37
+ TopoDS_Builder builder;
38
+ builder.MakeCompSolid(cs);
39
+
40
+ for (int i = 0; i < len; i++) {
41
+ if (_array_p(a[i])) {
42
+ for (int j = 0; j < RARRAY_LEN(a[i]); j++) {
43
+ auto solid = siren_solid_get(RARRAY_AREF(a[i], j));
44
+ builder.Add(cs, solid);
45
+ }
46
+ }
47
+ else {
48
+ auto solid = siren_solid_get(a[i]);
49
+ builder.Add(cs, solid);
50
+ }
51
+ }
52
+
53
+ auto p = siren_shape_get(self);
54
+ *p = cs;
55
+ return self;
56
+ }
57
+
58
+ VALUE siren_chunk_to_solid(int argc, VALUE* argv, VALUE self)
59
+ {
60
+ auto cs = siren_chunk_get(self);
61
+ auto solid = BRepBuilderAPI_MakeSolid(cs);
62
+ return siren_shape_new(solid);
63
+ }
64
+
65
+ #endif
@@ -0,0 +1,96 @@
1
+ #include "shape/compound.h"
2
+
3
+ #define rb_array_p(x) RB_TYPE_P(x, T_ARRAY)
4
+
5
+ VALUE sr_cCompound;
6
+
7
+ SR_SHAPE_GET(Compound, compound)
8
+ SR_SHAPE_CHECK(Compound, compound)
9
+
10
+ bool siren_compound_install()
11
+ {
12
+ SR_SHAPE_INIT(Compound)
13
+ rb_define_method(sr_cCompound, "initialize", RUBY_METHOD_FUNC(siren_compound_init), -1);
14
+ rb_define_method(sr_cCompound, "push", RUBY_METHOD_FUNC(siren_compound_push), -1);
15
+ rb_define_method(sr_cCompound, "<<", RUBY_METHOD_FUNC(siren_compound_push), -1);
16
+ rb_define_method(sr_cCompound, "delete", RUBY_METHOD_FUNC(siren_compound_delete), -1);
17
+ return true;
18
+ }
19
+
20
+ VALUE siren_compound_init(int argc, VALUE* argv, VALUE self)
21
+ {
22
+ VALUE* a;
23
+ VALUE len;
24
+ rb_scan_args(argc, argv, "*", &a, &len);
25
+
26
+ TopoDS_Compound comp;
27
+ BRep_Builder B;
28
+ B.MakeCompound(comp);
29
+
30
+ for (int i = 0; i < len; i++) {
31
+ VALUE arg = *(a + i);
32
+ if (rb_array_p(arg)) {
33
+ VALUE subary = rb_funcall(arg, rb_intern("flatten"), 0);
34
+ for (int j = 0; j < RARRAY_LEN(subary); j++) {
35
+ TopoDS_Shape* shape = siren_shape_get(RARRAY_AREF(subary, j));
36
+ B.Add(comp, *shape);
37
+ }
38
+ }
39
+ else {
40
+ TopoDS_Shape* shape = siren_shape_get(arg);
41
+ B.Add(comp, *shape);
42
+ }
43
+ }
44
+
45
+ auto p = siren_shape_get(self);
46
+ *p = comp;
47
+ return self;
48
+ }
49
+
50
+ VALUE siren_compound_push(int argc, VALUE* argv, VALUE self)
51
+ {
52
+ VALUE* a;
53
+ VALUE len;
54
+ rb_scan_args(argc, argv, "*", &a, &len);
55
+ TopoDS_Compound comp = siren_compound_get(self);
56
+ BRep_Builder B;
57
+ for (int i = 0; i < len; i++) {
58
+ VALUE arg = *(a + i);
59
+ if (rb_array_p(arg)) {
60
+ VALUE subary = rb_funcall(arg, rb_intern("flatten"), 0);
61
+ for (int j = 0; j < RARRAY_LEN(subary); j++) {
62
+ TopoDS_Shape* shape = siren_shape_get(RARRAY_AREF(subary, j));
63
+ B.Add(comp, *shape);
64
+ }
65
+ }
66
+ else {
67
+ TopoDS_Shape* shape = siren_shape_get(arg);
68
+ B.Add(comp, *shape);
69
+ }
70
+ }
71
+ return self;
72
+ }
73
+
74
+ VALUE siren_compound_delete(int argc, VALUE* argv, VALUE self)
75
+ {
76
+ VALUE* a;
77
+ VALUE len;
78
+ rb_scan_args(argc, argv, "*", &a, &len);
79
+ TopoDS_Compound comp = siren_compound_get(self);
80
+ BRep_Builder B;
81
+ for (int i = 0; i < len; i++) {
82
+ VALUE arg = *(a + i);
83
+ if (rb_array_p(arg)) {
84
+ VALUE subary = rb_funcall(arg, rb_intern("flatten"), 0);
85
+ for (int j = 0; j < RARRAY_LEN(subary); j++) {
86
+ TopoDS_Shape* shape = siren_shape_get(RARRAY_AREF(subary, j));
87
+ B.Remove(comp, *shape);
88
+ }
89
+ }
90
+ else {
91
+ TopoDS_Shape* shape = siren_shape_get(arg);
92
+ B.Remove(comp, *shape);
93
+ }
94
+ }
95
+ return self;
96
+ }
@@ -0,0 +1,254 @@
1
+ #include "shape/edge.h"
2
+
3
+ VALUE sr_cEdge;
4
+
5
+ SR_SHAPE_GET(Edge, edge)
6
+ SR_SHAPE_CHECK(Edge, edge)
7
+
8
+ bool siren_edge_install()
9
+ {
10
+ SR_SHAPE_INIT(Edge)
11
+ rb_define_method(sr_cEdge, "initialize", RUBY_METHOD_FUNC(siren_edge_init), -1);
12
+ rb_define_method(sr_cEdge, "sp", RUBY_METHOD_FUNC(siren_edge_sp), -1);
13
+ rb_define_method(sr_cEdge, "tp", RUBY_METHOD_FUNC(siren_edge_tp), -1);
14
+ rb_define_method(sr_cEdge, "to_pts", RUBY_METHOD_FUNC(siren_edge_to_pts), -1);
15
+ rb_define_method(sr_cEdge, "param", RUBY_METHOD_FUNC(siren_edge_param), -1);
16
+ rb_define_method(sr_cEdge, "to_xyz", RUBY_METHOD_FUNC(siren_edge_to_xyz), -1);
17
+ rb_define_method(sr_cEdge, "curvature", RUBY_METHOD_FUNC(siren_edge_curvature), -1);
18
+ rb_define_method(sr_cEdge, "tangent", RUBY_METHOD_FUNC(siren_edge_tangent), -1);
19
+ rb_define_method(sr_cEdge, "extrema", RUBY_METHOD_FUNC(siren_edge_extrema), -1);
20
+ rb_define_method(sr_cEdge, "split", RUBY_METHOD_FUNC(siren_edge_split), -1);
21
+ rb_define_method(sr_cEdge, "trim", RUBY_METHOD_FUNC(siren_edge_trim), -1);
22
+ rb_define_method(sr_cEdge, "terms", RUBY_METHOD_FUNC(siren_edge_terms), -1);
23
+ rb_define_method(sr_cEdge, "curve", RUBY_METHOD_FUNC(siren_edge_curve), -1);
24
+ return true;
25
+ }
26
+
27
+ VALUE siren_edge_init(int argc, VALUE* argv, VALUE self)
28
+ {
29
+ VALUE curve;
30
+ VALUE sp = DBL2NUM(0.0), tp = DBL2NUM(1.0);
31
+ rb_scan_args(argc, argv, "12", &curve, &sp, &tp);
32
+ auto phgcurve = siren_curve_get(curve);
33
+ TopoDS_Shape edge;
34
+ if (argc == 1) {
35
+ edge = BRepBuilderAPI_MakeEdge(*phgcurve);
36
+ }
37
+ else if (argc == 2) {
38
+ rb_raise(Qnil,
39
+ "The start parameter specified without a terminal parameter.");
40
+ }
41
+ else {
42
+ Check_Type(sp, T_FLOAT);
43
+ Check_Type(tp, T_FLOAT);
44
+ try {
45
+ edge = BRepBuilderAPI_MakeEdge(*phgcurve, NUM2DBL(sp), NUM2DBL(tp));
46
+ if (edge.IsNull()) {
47
+ rb_raise(Qnil, "Failed to make Edge from the Curve.");
48
+ }
49
+ }
50
+ catch (...) {
51
+ rb_raise(Qnil, "Failed to make Edge from the Curve.");
52
+ }
53
+ }
54
+ auto p = siren_shape_get(self);
55
+ *p = edge;
56
+ return self;
57
+ }
58
+
59
+ VALUE siren_edge_sp(int argc, VALUE* argv, VALUE self)
60
+ {
61
+ BRepAdaptor_Curve bracurve(siren_edge_get(self));
62
+ gp_Pnt sp = bracurve.Value(bracurve.FirstParameter());
63
+ return siren_pnt_to_ary(sp);
64
+ }
65
+
66
+ VALUE siren_edge_tp(int argc, VALUE* argv, VALUE self)
67
+ {
68
+ BRepAdaptor_Curve bracurve(siren_edge_get(self));
69
+ gp_Pnt tp = bracurve.Value(bracurve.LastParameter());
70
+ return siren_pnt_to_ary(tp);
71
+ }
72
+
73
+ VALUE siren_edge_to_pts(int argc, VALUE* argv, VALUE self)
74
+ {
75
+ VALUE deflect;
76
+ VALUE lintol;
77
+ rb_scan_args(argc, argv, "02", &deflect, &lintol);
78
+ if (argc < 1) {
79
+ deflect = DBL2NUM(1.0e-7);
80
+ }
81
+ if (argc < 2) {
82
+ lintol = DBL2NUM(1.0e-7);
83
+ }
84
+ TopoDS_Edge edge = siren_edge_get(self);
85
+ BRepAdaptor_Curve adaptor(edge);
86
+ double first_param, last_param;
87
+ first_param = adaptor.FirstParameter();
88
+ last_param = adaptor.LastParameter();
89
+
90
+ VALUE line = rb_ary_new();
91
+
92
+ GCPnts_UniformDeflection unidef(adaptor, NUM2DBL(deflect));
93
+ if (unidef.IsDone()) {
94
+ // first point
95
+ gp_Pnt p = adaptor.Value(first_param);
96
+ rb_ary_push(line, siren_pnt_to_ary(p));
97
+ gp_Pnt prev = p;
98
+
99
+ for (int i=1; i<=unidef.NbPoints(); i++) {
100
+ p = unidef.Value(i);
101
+ if (prev.IsEqual(p, NUM2DBL(lintol))) {
102
+ continue;
103
+ }
104
+ rb_ary_push(line, siren_pnt_to_ary(p));
105
+ prev = p;
106
+ }
107
+ // last point
108
+ p = adaptor.Value(last_param);
109
+ if (!prev.IsEqual(p, NUM2DBL(lintol))) {
110
+ rb_ary_push(line, siren_pnt_to_ary(p));
111
+ }
112
+ }
113
+ return line;
114
+ }
115
+
116
+ VALUE siren_edge_param(int argc, VALUE* argv, VALUE self)
117
+ {
118
+ VALUE xyz;
119
+ VALUE tol = DBL2NUM(1.0e-7);
120
+ rb_scan_args(argc, argv, "11", &xyz, &tol);
121
+
122
+ TopoDS_Edge edge = siren_edge_get(self);
123
+
124
+ ShapeAnalysis_Curve ana;
125
+ BRepAdaptor_Curve gcurve(edge);
126
+ gp_Pnt p = siren_ary_to_pnt(xyz);
127
+ gp_Pnt pp;
128
+ Standard_Real param;
129
+ Standard_Real distance = ana.Project(gcurve, p, NUM2DBL(tol), pp, param);
130
+
131
+ if (fabs(distance) > tol) {
132
+ rb_raise(Qnil, "Specified position is not on the edge.");
133
+ }
134
+
135
+ return (param);
136
+ }
137
+
138
+ VALUE siren_edge_to_xyz(int argc, VALUE* argv, VALUE self)
139
+ {
140
+ VALUE param;
141
+ rb_scan_args(argc, argv, "1", &param);
142
+ Check_Type(param, T_FLOAT);
143
+ BRepAdaptor_Curve C(siren_edge_get(self));
144
+ gp_Pnt p;
145
+ gp_Vec v1, v2;
146
+ C.D2(NUM2DBL(param), p, v1, v2);
147
+ return siren_pnt_to_ary(p);
148
+ }
149
+
150
+ VALUE siren_edge_curvature(int argc, VALUE* argv, VALUE self)
151
+ {
152
+ VALUE param;
153
+ rb_scan_args(argc, argv, "1", &param);
154
+ Check_Type(param, T_FLOAT);
155
+ BRepAdaptor_Curve C(siren_edge_get(self));
156
+ gp_Pnt p;
157
+ gp_Vec v1, v2;
158
+ C.D2(NUM2DBL(param), p, v1, v2);
159
+ return siren_vec_new(v2.X(), v2.Y(), v2.Z());
160
+ }
161
+
162
+ VALUE siren_edge_tangent(int argc, VALUE* argv, VALUE self)
163
+ {
164
+ VALUE param;
165
+ rb_scan_args(argc, argv, "1", &param);
166
+ Check_Type(param, T_FLOAT);
167
+ BRepAdaptor_Curve C(siren_edge_get(self));
168
+ gp_Pnt p;
169
+ gp_Vec v1, v2;
170
+ C.D2(NUM2DBL(param), p, v1, v2);
171
+ return siren_vec_new(v1.X(), v1.Y(), v1.Z());
172
+ }
173
+
174
+ VALUE siren_edge_terms(int argc, VALUE* argv, VALUE self)
175
+ {
176
+ TopoDS_Edge edge = siren_edge_get(self);
177
+ Standard_Real first, last;
178
+ BRep_Tool::Curve(edge, first, last);
179
+ VALUE res = rb_ary_new();
180
+ rb_ary_push(res, DBL2NUM(first));
181
+ rb_ary_push(res, DBL2NUM(last));
182
+ return res;
183
+ }
184
+
185
+ VALUE siren_edge_curve(int argc, VALUE* argv, VALUE self)
186
+ {
187
+ TopoDS_Edge edge = siren_edge_get(self);
188
+ // // set property
189
+ // Standard_Real first, last;
190
+ // handle<Geom_Curve> hgcurve = BRep_Tool::Curve(edge, first, last);
191
+ // rb_obj_iv_set(rb_obj_value(cls_edge), rb_intern_lit("@curve"), siren_curve_new(&hgcurve));
192
+ // // get property
193
+ // return rb_iv_get(self, rb_intern_lit("@curve"));
194
+ Standard_Real first, last;
195
+ handle<Geom_Curve> hgcurve = BRep_Tool::Curve(edge, first, last);
196
+ return siren_curve_new(hgcurve);
197
+ }
198
+
199
+ VALUE siren_edge_extrema(int argc, VALUE* argv, VALUE self)
200
+ {
201
+ VALUE other;
202
+ rb_scan_args(argc, argv, "1", &other);
203
+ siren_edge_check(other);
204
+ TopoDS_Edge e1 = siren_edge_get(self);
205
+ TopoDS_Edge e2 = siren_edge_get(other);
206
+ BRepExtrema_ExtCC ext(e1, e2);
207
+ if (!ext.IsDone()) {
208
+ rb_raise(Qnil, "Failed to get extrema points.");
209
+ }
210
+ else if (ext.IsParallel()) {
211
+ return Qnil;
212
+ }
213
+ VALUE p1s = rb_ary_new();
214
+ VALUE p2s = rb_ary_new();
215
+ for (int i = 1; i <= ext.NbExt(); i++) {
216
+ rb_ary_push(p1s, DBL2NUM(ext.ParameterOnE1(i)));
217
+ rb_ary_push(p2s, DBL2NUM(ext.ParameterOnE2(i)));
218
+ }
219
+ VALUE res[2] = { p1s, p2s };
220
+ return rb_ary_new_from_values(2, res);
221
+ }
222
+
223
+ VALUE siren_edge_split(int argc, VALUE* argv, VALUE self)
224
+ {
225
+ VALUE param;
226
+ rb_scan_args(argc, argv, "1", &param);
227
+ Check_Type(param, T_FLOAT);
228
+ Standard_Real first, last;
229
+ TopoDS_Edge e = siren_edge_get(self);
230
+ handle<Geom_Curve> gc = BRep_Tool::Curve(e, first, last);
231
+ if (NUM2DBL(param) <= first || NUM2DBL(param) >= last) {
232
+ rb_raise(Qnil, "Specified parameter is out of range of curve parameter.");
233
+ }
234
+ TopoDS_Edge e1 = BRepBuilderAPI_MakeEdge(gc, first, NUM2DBL(param));
235
+ TopoDS_Edge e2 = BRepBuilderAPI_MakeEdge(gc, NUM2DBL(param), last);
236
+ VALUE res[] = { siren_shape_new(e1), siren_shape_new(e2) };
237
+ return rb_ary_new_from_values(2, res);
238
+ }
239
+
240
+ VALUE siren_edge_trim(int argc, VALUE* argv, VALUE self)
241
+ {
242
+ VALUE first2, last2;
243
+ rb_scan_args(argc, argv, "2", &first2, &last2);
244
+ Check_Type(first2, T_FLOAT);
245
+ Check_Type(last2, T_FLOAT);
246
+ if (NUM2DBL(first2) == NUM2DBL(last2)) {
247
+ rb_raise(Qnil, "Specified parameter has same value.");
248
+ }
249
+ Standard_Real first, last;
250
+ TopoDS_Edge e = siren_edge_get(self);
251
+ handle<Geom_Curve> gc = BRep_Tool::Curve(e, first, last);
252
+ TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(gc, NUM2DBL(first2), NUM2DBL(last2));
253
+ return siren_shape_new(edge);
254
+ }
@@ -0,0 +1,366 @@
1
+ #include "shape/face.h"
2
+
3
+ VALUE sr_cFace;
4
+
5
+ SR_SHAPE_GET(Face, face)
6
+ SR_SHAPE_CHECK(Face, face)
7
+
8
+ bool siren_face_install()
9
+ {
10
+ SR_SHAPE_INIT(Face)
11
+ rb_define_method(sr_cFace, "initialize", RUBY_METHOD_FUNC(siren_shape_init), -1);
12
+ rb_define_method(sr_cFace, "normal", RUBY_METHOD_FUNC(siren_face_normal), -1);
13
+ rb_define_method(sr_cFace, "to_bezier", RUBY_METHOD_FUNC(siren_face_to_bezier), -1);
14
+ rb_define_method(sr_cFace, "split", RUBY_METHOD_FUNC(siren_face_split), -1);
15
+ rb_define_method(sr_cFace, "triangle", RUBY_METHOD_FUNC(siren_face_triangle), -1);
16
+ rb_define_singleton_method(sr_cFace, "plane", RUBY_METHOD_FUNC(siren_face_plane), -1);
17
+ rb_define_singleton_method(sr_cFace, "face", RUBY_METHOD_FUNC(siren_face_face), -1);
18
+ rb_define_singleton_method(sr_cFace, "infplane", RUBY_METHOD_FUNC(siren_face_infplane), -1);
19
+ rb_define_singleton_method(sr_cFace, "polygon", RUBY_METHOD_FUNC(siren_face_polygon), -1);
20
+ rb_define_singleton_method(sr_cFace, "bzsurf", RUBY_METHOD_FUNC(siren_face_bzsurf), -1);
21
+ rb_define_singleton_method(sr_cFace, "bssurf", RUBY_METHOD_FUNC(siren_face_bssurf), -1);
22
+ return true;
23
+ }
24
+
25
+ VALUE siren_face_normal(int argc, VALUE* argv, VALUE self)
26
+ {
27
+ TopoDS_Face f = siren_face_get(self);
28
+ Standard_Real umin, umax, vmin, vmax;
29
+ BRepTools::UVBounds(f, umin, umax, vmin, vmax);
30
+ handle<Geom_Surface> gsurf = BRep_Tool::Surface(f);
31
+ GeomLProp_SLProps props(gsurf, umin, vmin, 1, 0.01);
32
+ gp_Dir n = props.Normal();
33
+ return siren_vec_new(n.X(), n.Y(), n.Z());
34
+ }
35
+
36
+ VALUE siren_face_to_bezier(int argc, VALUE* argv, VALUE self)
37
+ {
38
+ TopoDS_Face face = siren_face_get(self);
39
+ handle<Geom_Surface> gsurf = BRep_Tool::Surface(face);
40
+ handle<Geom_BSplineSurface> gbssurf = handle<Geom_BSplineSurface>::DownCast(gsurf);
41
+ if (gbssurf.IsNull()) {
42
+ rb_raise(Qnil, "Specified shape is not B-Spline surface.");
43
+ }
44
+
45
+ TopoDS_Compound comp;
46
+ BRep_Builder B;
47
+ B.MakeCompound(comp);
48
+
49
+ GeomConvert_BSplineSurfaceToBezierSurface converter(gbssurf);
50
+
51
+ TColGeom_Array2OfBezierSurface ary(1, converter.NbUPatches(), 1, converter.NbVPatches());
52
+ converter.Patches(ary);
53
+
54
+ for (int r = ary.LowerRow(); r <= ary.UpperRow(); r++) {
55
+ for (int c = ary.LowerCol(); c <= ary.UpperCol(); c++) {
56
+ handle<Geom_BezierSurface> gbzsurf = ary.Value(r, c);
57
+ TopoDS_Face patch = BRepBuilderAPI_MakeFace(gbzsurf, 1.0e-1);
58
+ B.Add(comp, patch);
59
+ }
60
+ }
61
+
62
+ return siren_shape_new(comp);
63
+ }
64
+
65
+ VALUE siren_face_split(int argc, VALUE* argv, VALUE self)
66
+ {
67
+ VALUE obj;
68
+ rb_scan_args(argc, argv, "o", &obj);
69
+
70
+ TopoDS_Face face = siren_face_get(self);
71
+ BRepFeat_SplitShape splitter(face);
72
+
73
+ TopoDS_Shape shape = *siren_shape_get(obj);
74
+ switch (shape.ShapeType()) {
75
+ case TopAbs_WIRE:
76
+ splitter.Add(TopoDS::Wire(shape), face);
77
+ break;
78
+ case TopAbs_EDGE:
79
+ splitter.Add(TopoDS::Edge(shape), face);
80
+ break;
81
+ case TopAbs_COMPOUND:
82
+ splitter.Add(TopoDS::Compound(shape), face);
83
+ break;
84
+ default:
85
+ rb_raise(Qnil, "Incorrect argument specified.");
86
+ }
87
+ try {
88
+ splitter.Build();
89
+ }
90
+ catch (...) {
91
+ rb_raise(Qnil, "Failed to split the face.");
92
+ }
93
+ if (!splitter.IsDone()) {
94
+ rb_raise(Qnil, "Failed to split the face.");
95
+ }
96
+ return siren_shape_new(splitter.Shape());
97
+ }
98
+
99
+ VALUE siren_face_triangle(int argc, VALUE* argv, VALUE self)
100
+ {
101
+ VALUE deflection, angle;
102
+ rb_scan_args(argc, argv, "11", &deflection, &angle);
103
+
104
+ Check_Type(deflection, T_FLOAT);
105
+ Check_Type(angle, T_FLOAT);
106
+
107
+ VALUE result = rb_ary_new();
108
+
109
+ TopoDS_Face face = siren_face_get(self);
110
+ BRepTools::Update(face);
111
+
112
+ BRepMesh_IncrementalMesh imesh(face, NUM2DBL(deflection), Standard_False, NUM2DBL(angle));
113
+ imesh.Perform();
114
+ if (!imesh.IsDone()) {
115
+ rb_raise(Qnil, "Failed to incremantal mesh.");
116
+ }
117
+
118
+ TopoDS_Face face2 = TopoDS::Face(imesh.Shape());
119
+
120
+ TopLoc_Location loc;
121
+ // Do triangulation
122
+ handle<Poly_Triangulation> poly = BRep_Tool::Triangulation(face2, loc);
123
+ if (poly.IsNull()) {
124
+ rb_raise(Qnil, "Failed to triangulation.");
125
+ }
126
+
127
+ const Poly_Array1OfTriangle& tris = poly->Triangles();
128
+
129
+ for (Standard_Integer i = tris.Lower(); i <= tris.Upper(); i++) {
130
+
131
+ const Poly_Triangle& tri = tris.Value(i);
132
+
133
+ // Node indexes
134
+ Standard_Integer n1, n2, n3;
135
+ if (face2.Orientation() != TopAbs_REVERSED) {
136
+ tri.Get(n1, n2, n3);
137
+ }
138
+ else {
139
+ tri.Get(n3, n2, n1);
140
+ }
141
+
142
+ gp_Pnt p1 = poly->Nodes().Value(n1);
143
+ gp_Pnt p2 = poly->Nodes().Value(n2);
144
+ gp_Pnt p3 = poly->Nodes().Value(n3);
145
+
146
+ p1.Transform(loc);
147
+ p2.Transform(loc);
148
+ p3.Transform(loc);
149
+
150
+ gp_Vec u = gp_Vec(p2.XYZ() - p1.XYZ());
151
+ gp_Vec v = gp_Vec(p3.XYZ() - p1.XYZ());
152
+
153
+ gp_Vec norm(
154
+ u.Y() * v.Z() - u.Z() * v.Y(),
155
+ u.Z() * v.X() - u.X() * v.Z(),
156
+ u.X() * v.Y() - u.Y() * v.X());
157
+ if (norm.Magnitude() <= 0) {
158
+ continue;
159
+ }
160
+ norm.Normalize();
161
+
162
+ VALUE trimesh = rb_ary_new();
163
+ rb_ary_push(trimesh, siren_pnt_to_ary(p1));
164
+ rb_ary_push(trimesh, siren_pnt_to_ary(p2));
165
+ rb_ary_push(trimesh, siren_pnt_to_ary(p3));
166
+ rb_ary_push(trimesh, siren_vec_to_ary(u));
167
+ rb_ary_push(trimesh, siren_vec_to_ary(v));
168
+ rb_ary_push(trimesh, siren_vec_to_ary(norm));
169
+
170
+ rb_ary_push(result, trimesh);
171
+ }
172
+
173
+ return result;
174
+ }
175
+
176
+ VALUE siren_face_plane(int argc, VALUE* argv, VALUE self)
177
+ {
178
+ VALUE pos, norm, vx;
179
+ VALUE umin, umax, vmin, vmax;
180
+ rb_scan_args(argc, argv, "7", &pos, &norm, &vx, &umin, &umax, &vmin, &vmax);
181
+ Check_Type(umin, T_FLOAT);
182
+ Check_Type(umax, T_FLOAT);
183
+ Check_Type(vmin, T_FLOAT);
184
+ Check_Type(vmax, T_FLOAT);
185
+ try {
186
+ gp_Pln _pln(siren_ary_to_ax2(pos, norm, vx));
187
+ BRepBuilderAPI_MakeFace face(_pln, NUM2DBL(umin), NUM2DBL(umax), NUM2DBL(vmin), NUM2DBL(vmax));
188
+ return siren_shape_new(face.Shape());
189
+ }
190
+ catch (...) {
191
+ rb_raise(Qnil, "Failed to make a plane. "
192
+ "vx has same value with the normal vector.");
193
+ return Qnil;
194
+ }
195
+ }
196
+
197
+ VALUE siren_face_face(int argc, VALUE* argv, VALUE self)
198
+ {
199
+ VALUE wire;
200
+ VALUE force_plane;
201
+ rb_scan_args(argc, argv, "2", &wire, &force_plane);
202
+
203
+ siren_wire_check(wire);
204
+
205
+ TopoDS_Shape* s = siren_shape_get(wire);
206
+ TopoDS_Wire w = TopoDS::Wire(*s);
207
+ TopoDS_Face face = BRepBuilderAPI_MakeFace(w, (Standard_Boolean)(force_plane == Qtrue));
208
+ return siren_shape_new(face);
209
+ }
210
+
211
+ VALUE siren_face_infplane(int argc, VALUE* argv, VALUE self)
212
+ {
213
+ VALUE orig, dir;
214
+ rb_scan_args(argc, argv, "2", &orig, &dir);
215
+ gp_Pln pln(siren_ary_to_pnt(orig), siren_ary_to_dir(dir));
216
+ TopoDS_Face face = BRepBuilderAPI_MakeFace(pln);
217
+ return siren_shape_new(face);
218
+ }
219
+
220
+ VALUE siren_face_polygon(int argc, VALUE* argv, VALUE self)
221
+ {
222
+ VALUE pts;
223
+ VALUE force_plane = Qfalse;
224
+ rb_scan_args(argc, argv, "11", &pts, &force_plane);
225
+
226
+ BRepBuilderAPI_MakePolygon mp;
227
+
228
+ for (int i=0; i<RARRAY_LEN(pts); i++) {
229
+ mp.Add(siren_ary_to_pnt(RARRAY_AREF(pts, i)));
230
+ }
231
+
232
+ mp.Close();
233
+ BRepBuilderAPI_MakeFace mf(mp.Wire(), (Standard_Boolean)(force_plane == Qtrue));
234
+ mf.Build();
235
+
236
+ if (!mf.IsDone()) {
237
+ rb_raise(Qnil, "Failed to make a polygon.");
238
+ }
239
+
240
+ return siren_shape_new(mf.Shape());
241
+ }
242
+
243
+ VALUE siren_face_bzsurf(int argc, VALUE* argv, VALUE self)
244
+ {
245
+ VALUE ptary, wtary;
246
+ rb_scan_args(argc, argv, "11", &ptary, &wtary);
247
+
248
+ int rlen = RARRAY_LEN(ptary);
249
+ int clen = RARRAY_LEN(RARRAY_AREF(ptary, 0));
250
+
251
+ TColgp_Array2OfPnt poles(0, rlen-1, 0, clen-1);
252
+
253
+ for (int r=0; r<rlen; r++) {
254
+ VALUE ar = RARRAY_AREF(ptary, r);
255
+ for (int c=0; c<clen; c++) {
256
+ poles.SetValue(r, c, siren_ary_to_pnt(RARRAY_AREF(ar, c)));
257
+ }
258
+ }
259
+
260
+ opencascade::handle<Geom_BezierSurface> s = nullptr;
261
+
262
+ if (argc == 2) {
263
+ TColStd_Array2OfReal weights(0, rlen-1, 0, clen-1);
264
+ for (int r=0; r<rlen; r++) {
265
+ VALUE ar = RARRAY_AREF(wtary, r);
266
+ for (int c=0; c<clen; c++) {
267
+ VALUE val = RARRAY_AREF(ar, c);
268
+ weights.SetValue(r, c, NUM2DBL(val));
269
+ }
270
+ }
271
+ s = new Geom_BezierSurface(poles, weights);
272
+ }
273
+ else {
274
+ s = new Geom_BezierSurface(poles);
275
+ }
276
+
277
+ return siren_shape_new(BRepBuilderAPI_MakeFace(s, 1.0e-7));
278
+ }
279
+
280
+ VALUE siren_face_bssurf(int argc, VALUE* argv, VALUE self)
281
+ {
282
+ VALUE _udeg, _vdeg;
283
+ VALUE _ar_ukm, _ar_vkm;
284
+ VALUE _pol;
285
+ VALUE _wire;
286
+ rb_scan_args(argc, argv, "51", &_udeg, &_ar_ukm, &_vdeg, &_ar_vkm, &_pol, &_wire);
287
+
288
+ bool has_contour = argc == 6;
289
+ if (has_contour) {
290
+ siren_wire_check(_wire);
291
+ }
292
+
293
+ Standard_Integer udeg = NUM2INT(_udeg);
294
+ Standard_Integer nbuknots = RARRAY_LEN(_ar_ukm);
295
+ Standard_Integer nbuknots_pure = 0;
296
+ TColStd_Array1OfReal uknots(1, nbuknots);
297
+ TColStd_Array1OfInteger umults(1, nbuknots);
298
+ for (int i=1; i<=nbuknots; i++) {
299
+ VALUE item = RARRAY_AREF(_ar_ukm, i - 1);
300
+ VALUE knot = RARRAY_AREF(item, 0);
301
+ VALUE mult = RARRAY_AREF(item, 1);
302
+ uknots(i) = NUM2DBL(knot);
303
+ umults(i) = NUM2INT(mult);
304
+ nbuknots_pure += umults(i);
305
+ }
306
+ Standard_Integer nbupoles = nbuknots_pure - udeg - 1;
307
+
308
+ Standard_Integer vdeg = NUM2INT(_vdeg);
309
+ Standard_Integer nbvknots = RARRAY_LEN(_ar_vkm);
310
+ Standard_Integer nbvknots_pure = 0;
311
+ TColStd_Array1OfReal vknots(1, nbvknots);
312
+ TColStd_Array1OfInteger vmults(1, nbvknots);
313
+ for (int i=1; i<=nbvknots; i++) {
314
+ VALUE item = RARRAY_AREF(_ar_vkm, i - 1);
315
+ VALUE knot = RARRAY_AREF(item, 0);
316
+ VALUE mult = RARRAY_AREF(item, 1);
317
+ vknots(i) = NUM2DBL(knot);
318
+ vmults(i) = NUM2INT(mult);
319
+ nbvknots_pure += vmults(i);
320
+ }
321
+ Standard_Integer nbvpoles = nbvknots_pure - vdeg - 1;
322
+
323
+ TColgp_Array2OfPnt poles (1, nbupoles, 1, nbvpoles);
324
+ TColStd_Array2OfReal weights(1, nbupoles, 1, nbvpoles);
325
+
326
+ for (int v=1; v <= nbvpoles; v++) {
327
+ VALUE vitem = RARRAY_AREF(_pol, v - 1);
328
+ for (int u=1; u <= nbupoles; u++) {
329
+ VALUE uitem = RARRAY_AREF(vitem, u - 1);
330
+ poles.SetValue(u, v, siren_ary_to_pnt(RARRAY_AREF(uitem, 0)));
331
+ weights.SetValue(u, v, NUM2DBL(RARRAY_AREF(uitem, 1)));
332
+ }
333
+ }
334
+
335
+ handle<Geom_BSplineSurface> hg_bssurf
336
+ = new Geom_BSplineSurface(poles, weights, uknots, vknots, umults, vmults, udeg, vdeg);
337
+ TopoDS_Shape shape;
338
+ if (has_contour) {
339
+ TopoDS_Shape* s = siren_shape_get(_wire);
340
+ TopoDS_Wire w = TopoDS::Wire(*s);
341
+ shape = BRepBuilderAPI_MakeFace(hg_bssurf, w, Standard_True);
342
+ // Fix a face
343
+ opencascade::handle<ShapeFix_Shape> sfs = new ShapeFix_Shape();
344
+ sfs->Init(shape);
345
+ sfs->FixFaceTool()->FixAddNaturalBoundMode() = 1;
346
+ sfs->FixFaceTool()->FixIntersectingWiresMode() = 1;
347
+ sfs->FixFaceTool()->FixLoopWiresMode() = 1;
348
+ sfs->FixFaceTool()->FixOrientationMode() = 1;
349
+ sfs->FixFaceTool()->FixPeriodicDegeneratedMode() = 1;
350
+ sfs->FixFaceTool()->FixSmallAreaWireMode() = 1;
351
+ sfs->FixFaceTool()->FixSplitFaceMode() = 1;
352
+ sfs->FixFaceTool()->FixWireMode() = 1;
353
+ sfs->SetPrecision(1.0);
354
+ sfs->SetMinTolerance(1.0e-1);
355
+ sfs->SetMaxTolerance(1.0);
356
+ sfs->Perform();
357
+ shape = sfs->Shape();
358
+ // End of fix
359
+ }
360
+ else {
361
+ Standard_Real toldegen = 1.0e-1;
362
+ shape = BRepBuilderAPI_MakeFace(hg_bssurf, toldegen);
363
+ }
364
+
365
+ return siren_shape_new(shape);
366
+ }