rubyscad 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -21
  3. data/Gemfile +4 -4
  4. data/LICENSE.txt +21 -21
  5. data/README.md +322 -322
  6. data/Rakefile +1 -1
  7. data/examples/BasicCube.rb +50 -50
  8. data/examples/ChamferCube.rb +96 -96
  9. data/examples/FilletCube.rb +317 -317
  10. data/examples/example001.rb +33 -33
  11. data/examples/example001.scad +11 -11
  12. data/examples/example002.rb +23 -23
  13. data/examples/example002.scad +18 -18
  14. data/examples/example003.rb +19 -19
  15. data/examples/example003.scad +15 -15
  16. data/examples/example004.rb +11 -11
  17. data/examples/example004.scad +6 -6
  18. data/examples/example005.rb +22 -22
  19. data/examples/example005.scad +31 -31
  20. data/examples/example006.rb +46 -46
  21. data/examples/example006.scad +221 -221
  22. data/examples/example007.dxf +2410 -2410
  23. data/examples/example007.rb +53 -53
  24. data/examples/example007.scad +30 -30
  25. data/examples/example008.dxf +3238 -3238
  26. data/examples/example008.rb +34 -34
  27. data/examples/example008.scad +26 -26
  28. data/examples/example009.dxf +3894 -3894
  29. data/examples/example009.rb +33 -33
  30. data/examples/example009.scad +15 -15
  31. data/examples/example010.dat +51 -51
  32. data/examples/example010.rb +12 -12
  33. data/examples/example010.scad +7 -7
  34. data/examples/example011.rb +22 -22
  35. data/examples/example011.scad +3 -3
  36. data/examples/example012.rb +16 -16
  37. data/examples/example012.scad +8 -8
  38. data/examples/example013.dxf +2276 -2276
  39. data/examples/example013.rb +16 -16
  40. data/examples/example013.scad +12 -12
  41. data/examples/example014.rb +14 -14
  42. data/examples/example014.scad +12 -12
  43. data/examples/example015.rb +33 -33
  44. data/examples/example015.scad +22 -22
  45. data/examples/example016.rb +43 -43
  46. data/examples/example016.scad +49 -49
  47. data/examples/example017.rb +170 -170
  48. data/examples/example017.scad +124 -124
  49. data/examples/example018.rb +29 -29
  50. data/examples/example018.scad +74 -74
  51. data/examples/example019.rb +22 -22
  52. data/examples/example019.scad +84 -84
  53. data/examples/example020.rb +92 -92
  54. data/examples/example020.scad +62 -62
  55. data/examples/example021.rb +42 -42
  56. data/examples/example021.scad +159 -159
  57. data/examples/example022.rb +44 -44
  58. data/examples/example022.scad +103 -103
  59. data/lib/rubyscad.rb +2 -2
  60. data/lib/rubyscad/RubyScad.rb +369 -361
  61. data/lib/rubyscad/version.rb +3 -3
  62. data/rubyscad.gemspec +20 -20
  63. metadata +7 -9
data/Rakefile CHANGED
@@ -1 +1 @@
1
- require "bundler/gem_tasks"
1
+ require "bundler/gem_tasks"
@@ -1,50 +1,50 @@
1
- require 'rubyscad'
2
-
3
- class BasicCube
4
- include RubyScad
5
-
6
- attr_accessor :size, :center
7
-
8
- def initialize(args={})
9
- @size = args.fetch(:size, [1,1,1])
10
- @center = args.fetch(:center, true)
11
- end
12
-
13
- def x()
14
- @size[0]
15
- end
16
-
17
- def x=(value)
18
- @size[0] = value
19
- end
20
-
21
- def y()
22
- @size[1]
23
- end
24
-
25
- def y=(value)
26
- @size[1] = value
27
- end
28
-
29
- def z()
30
- @size[2]
31
- end
32
-
33
- def z=(value)
34
- @size[2] = value
35
- end
36
-
37
- def translate_centered(&block)
38
- unless @center
39
- translate(v:[x/2.0, y/2.0, z/2.0], &block)
40
- else
41
- yield
42
- end
43
- end
44
-
45
- def render(args={})
46
- translate_centered {
47
- cube(size:@size, center: true)
48
- }
49
- end
50
- end
1
+ require 'rubyscad'
2
+
3
+ class BasicCube
4
+ include RubyScad
5
+
6
+ attr_accessor :size, :center
7
+
8
+ def initialize(args={})
9
+ @size = args.fetch(:size, [1,1,1])
10
+ @center = args.fetch(:center, true)
11
+ end
12
+
13
+ def x()
14
+ @size[0]
15
+ end
16
+
17
+ def x=(value)
18
+ @size[0] = value
19
+ end
20
+
21
+ def y()
22
+ @size[1]
23
+ end
24
+
25
+ def y=(value)
26
+ @size[1] = value
27
+ end
28
+
29
+ def z()
30
+ @size[2]
31
+ end
32
+
33
+ def z=(value)
34
+ @size[2] = value
35
+ end
36
+
37
+ def translate_centered(&block)
38
+ unless @center
39
+ translate(v:[x/2.0, y/2.0, z/2.0], &block)
40
+ else
41
+ yield
42
+ end
43
+ end
44
+
45
+ def render(args={})
46
+ translate_centered {
47
+ cube(size:@size, center: true)
48
+ }
49
+ end
50
+ end
@@ -1,96 +1,96 @@
1
- load 'BasicCube.rb'
2
-
3
- class ChamferCube < BasicCube
4
-
5
- def initialize(args={})
6
- super
7
- @chamfer = [].fill(0, 0..11)
8
- end
9
-
10
- def chamfer_edge(edge, value)
11
- @chamfer[edge] = value
12
- end
13
-
14
- def chamfer_edges(array)
15
- array.each { |v| chamfer_edge(v[0], v[1]) }
16
- end
17
-
18
- def chamfer_side(side, value)
19
- case side
20
- when 0
21
- chamfer_edge(0, value)
22
- chamfer_edge(1, value)
23
- chamfer_edge(2, value)
24
- chamfer_edge(3, value)
25
- when 1
26
- chamfer_edge(0, value)
27
- chamfer_edge(4, value)
28
- chamfer_edge(5, value)
29
- chamfer_edge(8, value)
30
- when 2
31
- chamfer_edge(5, value)
32
- chamfer_edge(1, value)
33
- chamfer_edge(6, value)
34
- chamfer_edge(9, value)
35
- when 3
36
- chamfer_edge(2, value)
37
- chamfer_edge(6, value)
38
- chamfer_edge(7, value)
39
- chamfer_edge(10, value)
40
- when 4
41
- chamfer_edge(3, value)
42
- chamfer_edge(4, value)
43
- chamfer_edge(11, value)
44
- chamfer_edge(7, value)
45
- when 5
46
- chamfer_edge(8, value)
47
- chamfer_edge(9, value)
48
- chamfer_edge(10, value)
49
- chamfer_edge(11, value)
50
- end
51
- end
52
-
53
- def chamfer_sides(array)
54
- array.each{ |v| chamfer_side(v[0], v[1]) }
55
- end
56
-
57
- def apply_chamfer(edge, value)
58
- case edge
59
- when 0
60
- translate(y: -y/2.0, z: z/2.0) { rotate(x:45) { chamfer_cube([x+PAD, value, value]) } }
61
- when 1
62
- translate(x: x/2.0, y: -y/2.0) { rotate(z:45) { chamfer_cube([value, value, z+PAD]) } }
63
- when 2
64
- translate(y: -y/2.0, z: -z/2.0) { rotate(x:45) { chamfer_cube([x+PAD, value, value]) } }
65
- when 3
66
- translate(x: -x/2.0, y: -y/2.0) { rotate(z:45) { chamfer_cube([value, value, z+PAD]) } }
67
- when 4
68
- translate(x: -x/2.0, z: z/2.0) { rotate(y:45) { chamfer_cube([value, y+PAD, value]) } }
69
- when 5
70
- translate(x: x/2.0, z: z/2.0) { rotate(y:45) { chamfer_cube([value, y+PAD, value]) } }
71
- when 6
72
- translate(x: x/2.0, z: -z/2.0) { rotate(y:45) { chamfer_cube([value, y+PAD, value]) } }
73
- when 7
74
- translate(x: -x/2.0, z: -z/2.0) { rotate(y:45) { chamfer_cube([value, y+PAD, value]) } }
75
- when 8
76
- translate(y: y/2.0, z: z/2.0) { rotate(x:45) { chamfer_cube([x+PAD, value, value]) } }
77
- when 9
78
- translate(x: x/2.0, y: y/2.0) { rotate(z:45) { chamfer_cube([value, value, z+PAD]) } }
79
- when 10
80
- translate(y: y/2.0, z: -z/2.0) { rotate(x:45) { chamfer_cube([x+PAD, value, value]) } }
81
- when 11
82
- translate(x: -x/2.0, y: y/2.0) { rotate(z:45) { chamfer_cube([value, value, z+PAD]) } }
83
- end
84
- end
85
-
86
- def chamfer_cube(size)
87
- cube(size: size, center: true)
88
- end
89
-
90
- def render(args={})
91
- difference {
92
- super
93
- @chamfer.each_with_index { |v, i| apply_chamfer(i, v) if v > 0 }
94
- }
95
- end
96
- end
1
+ load 'BasicCube.rb'
2
+
3
+ class ChamferCube < BasicCube
4
+
5
+ def initialize(args={})
6
+ super
7
+ @chamfer = [].fill(0, 0..11)
8
+ end
9
+
10
+ def chamfer_edge(edge, value)
11
+ @chamfer[edge] = value
12
+ end
13
+
14
+ def chamfer_edges(array)
15
+ array.each { |v| chamfer_edge(v[0], v[1]) }
16
+ end
17
+
18
+ def chamfer_side(side, value)
19
+ case side
20
+ when 0
21
+ chamfer_edge(0, value)
22
+ chamfer_edge(1, value)
23
+ chamfer_edge(2, value)
24
+ chamfer_edge(3, value)
25
+ when 1
26
+ chamfer_edge(0, value)
27
+ chamfer_edge(4, value)
28
+ chamfer_edge(5, value)
29
+ chamfer_edge(8, value)
30
+ when 2
31
+ chamfer_edge(5, value)
32
+ chamfer_edge(1, value)
33
+ chamfer_edge(6, value)
34
+ chamfer_edge(9, value)
35
+ when 3
36
+ chamfer_edge(2, value)
37
+ chamfer_edge(6, value)
38
+ chamfer_edge(7, value)
39
+ chamfer_edge(10, value)
40
+ when 4
41
+ chamfer_edge(3, value)
42
+ chamfer_edge(4, value)
43
+ chamfer_edge(11, value)
44
+ chamfer_edge(7, value)
45
+ when 5
46
+ chamfer_edge(8, value)
47
+ chamfer_edge(9, value)
48
+ chamfer_edge(10, value)
49
+ chamfer_edge(11, value)
50
+ end
51
+ end
52
+
53
+ def chamfer_sides(array)
54
+ array.each{ |v| chamfer_side(v[0], v[1]) }
55
+ end
56
+
57
+ def apply_chamfer(edge, value)
58
+ case edge
59
+ when 0
60
+ translate(y: -y/2.0, z: z/2.0) { rotate(x:45) { chamfer_cube([x+PAD, value, value]) } }
61
+ when 1
62
+ translate(x: x/2.0, y: -y/2.0) { rotate(z:45) { chamfer_cube([value, value, z+PAD]) } }
63
+ when 2
64
+ translate(y: -y/2.0, z: -z/2.0) { rotate(x:45) { chamfer_cube([x+PAD, value, value]) } }
65
+ when 3
66
+ translate(x: -x/2.0, y: -y/2.0) { rotate(z:45) { chamfer_cube([value, value, z+PAD]) } }
67
+ when 4
68
+ translate(x: -x/2.0, z: z/2.0) { rotate(y:45) { chamfer_cube([value, y+PAD, value]) } }
69
+ when 5
70
+ translate(x: x/2.0, z: z/2.0) { rotate(y:45) { chamfer_cube([value, y+PAD, value]) } }
71
+ when 6
72
+ translate(x: x/2.0, z: -z/2.0) { rotate(y:45) { chamfer_cube([value, y+PAD, value]) } }
73
+ when 7
74
+ translate(x: -x/2.0, z: -z/2.0) { rotate(y:45) { chamfer_cube([value, y+PAD, value]) } }
75
+ when 8
76
+ translate(y: y/2.0, z: z/2.0) { rotate(x:45) { chamfer_cube([x+PAD, value, value]) } }
77
+ when 9
78
+ translate(x: x/2.0, y: y/2.0) { rotate(z:45) { chamfer_cube([value, value, z+PAD]) } }
79
+ when 10
80
+ translate(y: y/2.0, z: -z/2.0) { rotate(x:45) { chamfer_cube([x+PAD, value, value]) } }
81
+ when 11
82
+ translate(x: -x/2.0, y: y/2.0) { rotate(z:45) { chamfer_cube([value, value, z+PAD]) } }
83
+ end
84
+ end
85
+
86
+ def chamfer_cube(size)
87
+ cube(size: size, center: true)
88
+ end
89
+
90
+ def render(args={})
91
+ difference {
92
+ super
93
+ @chamfer.each_with_index { |v, i| apply_chamfer(i, v) if v > 0 }
94
+ }
95
+ end
96
+ end
@@ -1,317 +1,317 @@
1
- load "ChamferCube.rb"
2
-
3
- class FilletCube < ChamferCube
4
-
5
- attr_accessor :smooth
6
-
7
- def initialize(args={})
8
- super
9
- @smooth = 30
10
- @fillet = [].fill(0, 0..11)
11
- end
12
-
13
- def fillet_edge(edge, value)
14
- @fillet[edge] = value
15
- end
16
-
17
- def fillet_edges(array)
18
- array.each { |v| fillet_edge(v[0], v[1]) }
19
- end
20
-
21
- def fillet_side(side, value)
22
- case side
23
- when 0
24
- fillet_edge(0, value)
25
- fillet_edge(1, value)
26
- fillet_edge(2, value)
27
- fillet_edge(3, value)
28
- when 1
29
- fillet_edge(0, value)
30
- fillet_edge(4, value)
31
- fillet_edge(5, value)
32
- fillet_edge(8, value)
33
- when 2
34
- fillet_edge(5, value)
35
- fillet_edge(1, value)
36
- fillet_edge(6, value)
37
- fillet_edge(9, value)
38
- when 3
39
- fillet_edge(2, value)
40
- fillet_edge(6, value)
41
- fillet_edge(7, value)
42
- fillet_edge(10, value)
43
- when 4
44
- fillet_edge(3, value)
45
- fillet_edge(4, value)
46
- fillet_edge(11, value)
47
- fillet_edge(7, value)
48
- when 5
49
- fillet_edge(8, value)
50
- fillet_edge(9, value)
51
- fillet_edge(10, value)
52
- fillet_edge(11, value)
53
- end
54
- end
55
-
56
- def fillet_sides(array)
57
- array.each{ |v| fillet_side(v[0], v[1]) }
58
- end
59
-
60
- def apply_fillet(edge, value)
61
- case edge
62
- when 0
63
- translate(y: -y/2.0+value, z: z/2.0-value) {
64
- difference() {
65
- translate(y:-value-PAD, z: value+PAD) {
66
- fillet_cube([x+2.0*PAD, value*2.0+PAD, value*2.0+PAD])
67
- }
68
- rotate(y: 90) { fillet_cylinder(x+4*PAD, value) }
69
- }
70
- }
71
- when 1
72
- translate(x: x/2.0-value, y: -y/2.0+value) {
73
- difference() {
74
- translate(x: value+PAD, y: -value-PAD) {
75
- fillet_cube([value*2.0+PAD, value*2.0+PAD, z+2.0*PAD])
76
- }
77
- fillet_cylinder(z+4*PAD,value)
78
- }
79
- }
80
- when 2
81
- translate(y: -y/2.0+value, z: -z/2.0+value) {
82
- difference() {
83
- translate(y: -value-PAD, z: -value-PAD) {
84
- fillet_cube([x+2.0*PAD, value*2.0+PAD, value*2.0+PAD])
85
- }
86
- rotate(y: 90) { fillet_cylinder(x+4*PAD,value) }
87
- }
88
- }
89
- when 3
90
- translate(x: -x/2.0+value, y: -y/2.0+value) {
91
- difference() {
92
- translate(x: -value-PAD, y: -value-PAD) {
93
- fillet_cube([value*2.0+PAD, value*2.0+PAD, z+2.0*PAD])
94
- }
95
- fillet_cylinder(z+4*PAD,value)
96
- }
97
- }
98
- when 4
99
- translate(x: -x/2.0+value, z: z/2.0-value) {
100
- difference() {
101
- translate(x: -value-PAD, z: value+PAD) {
102
- fillet_cube([value*2.0+PAD, y+2.0*PAD, value*2.0+PAD])
103
- }
104
- rotate(y: 90, z: 90) { fillet_cylinder(y+4*PAD, value) }
105
- }
106
- }
107
- when 5
108
- translate(x: x/2.0-value, z: z/2.0-value) {
109
- difference() {
110
- translate(x: value+PAD, z: value+PAD) {
111
- fillet_cube([value*2.0+PAD, y+2.0*PAD, value*2.0+PAD])
112
- }
113
- rotate(y: 90, z: 90) { fillet_cylinder(y+4*PAD, value) }
114
- }
115
- }
116
- when 6
117
- translate(x: x/2.0-value, z: -z/2.0+value) {
118
- difference() {
119
- translate(x: value+PAD, z: -value-PAD) {
120
- fillet_cube([value*2.0+PAD, y+2.0*PAD, value*2.0+PAD])
121
- }
122
- rotate(y: 90, z: 90) { fillet_cylinder(y+4*PAD, value) }
123
- }
124
- }
125
- when 7
126
- translate(x: -x/2.0+value, z: -z/2.0+value) {
127
- difference() {
128
- translate(x: -value-PAD, z: -value-PAD) {
129
- fillet_cube([value*2.0+PAD, y+2.0*PAD, value*2.0+PAD])
130
- }
131
- rotate(y: 90, z: 90) { fillet_cylinder(y+4*PAD, value) }
132
- }
133
- }
134
- when 8
135
- translate(y: y/2.0-value, z: z/2.0-value) {
136
- difference() {
137
- translate(y: value+PAD, z: value+PAD) {
138
- fillet_cube([x+2.0*PAD, value*2.0+PAD, value*2.0+PAD])
139
- }
140
- rotate(x: 90) { fillet_cylinder(x+4*PAD,value) }
141
- }
142
- }
143
- when 9
144
- translate(x: x/2.0-value, y: y/2.0-value) {
145
- difference() {
146
- translate(x: value+PAD, y: value+PAD) {
147
- fillet_cube([value*2+PAD, value*2+PAD, z+2*PAD])
148
- }
149
- fillet_cylinder(z+4*PAD, value)
150
- }
151
- }
152
- when 10
153
- translate(y: y/2.0-value, z: -z/2.0+value) {
154
- difference() {
155
- translate(y: value+PAD, z: -value-PAD) {
156
- fillet_cube([x+2.0*PAD, value*2.0+PAD, value*2.0+PAD])
157
- }
158
- rotate(x: 90) { fillet_cylinder(x+4*PAD,value) }
159
- }
160
- }
161
- when 11
162
- translate(x: -x/2.0+value, y: y/2.0-value) {
163
- difference() {
164
- translate(x: -value-PAD, y: value+PAD) {
165
- fillet_cube([value*2.0+PAD, value*2.0+PAD, z+2.0*PAD])
166
- }
167
- fillet_cylinder(z+4*PAD, value)
168
- }
169
- }
170
- end
171
- end
172
-
173
- def fillet_corner(corner, value)
174
- case corner
175
- when 0
176
- translate(v:[-x/2.0+value, -y/2.0+value, z/2.0-value]) {
177
- difference() {
178
- translate(v:[-value-PAD, -value-PAD, value+PAD]) {
179
- fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
180
- }
181
- fillet_sphere(value)
182
- }
183
- }
184
- when 1
185
- translate(v:[x/2.0-value, -y/2.0+value, z/2.0-value]) {
186
- difference() {
187
- translate(v:[value+PAD, -value-PAD, value+PAD]) {
188
- fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
189
- }
190
- fillet_sphere(value)
191
- }
192
- }
193
- when 2
194
- translate(v:[x/2.0-value, -y/2.0+value, -z/2.0+value]) {
195
- difference() {
196
- translate(v:[value+PAD, -value-PAD, -value-PAD]) {
197
- fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
198
- }
199
- fillet_sphere(value)
200
- }
201
- }
202
- when 3
203
- translate(v:[-x/2.0+value, -y/2.0+value, -z/2.0+value]) {
204
- difference() {
205
- translate(v:[-value-PAD, -value-PAD, -value-PAD]) {
206
- fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
207
- }
208
- fillet_sphere(value)
209
- }
210
- }
211
- when 4
212
- translate(v:[-x/2.0+value, y/2.0-value, z/2.0-value]) {
213
- difference() {
214
- translate(v:[-value-PAD, value+PAD, value+PAD]) {
215
- fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
216
- }
217
- fillet_sphere(value)
218
- }
219
- }
220
- when 5
221
- translate(v:[x/2.0-value, y/2.0-value, z/2.0-value]) {
222
- difference() {
223
- translate(v: [value+PAD, value+PAD, value+PAD]) {
224
- fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
225
- }
226
- fillet_sphere(value)
227
- }
228
- }
229
- when 6
230
- translate(v:[x/2.0-value, y/2.0-value, -z/2.0+value]) {
231
- difference() {
232
- translate(v:[value+PAD, value+PAD, -value-PAD]) {
233
- fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
234
- }
235
- fillet_sphere(value)
236
- }
237
- }
238
- when 7
239
- translate(v:[-x/2.0+value, y/2.0-value, -z/2.0+value]) {
240
- difference() {
241
- translate(v:[-value-PAD, value+PAD, -value-PAD]) {
242
- fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
243
- }
244
- fillet_sphere(value)
245
- }
246
- }
247
- end
248
- end
249
-
250
- def fillet_sphere(r)
251
- sphere(r: r, fn: @smooth)
252
- end
253
-
254
- def fillet_cylinder(height, radius)
255
- cylinder(r: radius, h: height, center: true, fn: @smooth)
256
- end
257
-
258
- def fillet_cube(size)
259
- cube(size: size, center:true)
260
- end
261
-
262
- def greater_than_0(*args)
263
- args.each { |v| return nil if v <= 0 }
264
- return true
265
- end
266
-
267
- def auto_corner_fillet()
268
- if greater_than_0(@fillet[0], @fillet[3], @fillet[4])
269
- fillet = average(@fillet[0], @fillet[3], @fillet[4])
270
- fillet_corner(0, fillet)
271
- end
272
- if greater_than_0(@fillet[0], @fillet[1], @fillet[5])
273
- fillet = average(@fillet[0], @fillet[1], @fillet[5])
274
- fillet_corner(1, fillet)
275
- end
276
- if greater_than_0(@fillet[1], @fillet[2], @fillet[6])
277
- fillet = average(@fillet[1], @fillet[2], @fillet[6])
278
- fillet_corner(2, fillet)
279
- end
280
- if greater_than_0(@fillet[2], @fillet[3], @fillet[7])
281
- fillet = average(@fillet[2], @fillet[3], @fillet[7])
282
- fillet_corner(3, fillet)
283
- end
284
- if greater_than_0(@fillet[4], @fillet[8], @fillet[11])
285
- fillet = average(@fillet[4], @fillet[8], @fillet[11])
286
- fillet_corner(4, fillet)
287
- end
288
- if greater_than_0(@fillet[5], @fillet[8], @fillet[9])
289
- fillet = average(@fillet[5], @fillet[8], @fillet[9])
290
- fillet_corner(5, fillet)
291
- end
292
- if greater_than_0(@fillet[6], @fillet[9], @fillet[10])
293
- fillet = average(@fillet[6], @fillet[9], @fillet[10])
294
- fillet_corner(6, fillet)
295
- end
296
- if greater_than_0(@fillet[7], @fillet[10], @fillet[11])
297
- fillet = average(@fillet[7], @fillet[10], @fillet[11])
298
- fillet_corner(7, fillet)
299
- end
300
- end
301
-
302
- def average(*args)
303
- args.inject(0.0) { |sum, el| sum + el } / args.size
304
- end
305
-
306
- def render(args={})
307
- difference {
308
- super
309
- @fillet.each_with_index { |v, i| apply_fillet(i, v) if v > 0 }
310
- auto_corner_fillet()
311
- }
312
- end
313
- end
314
-
315
- #cube = FilletCube.new(size:[5, 7, 8], center: true)
316
- #cube.fillet_sides([[0,1], [1,1], [2,1], [3,1], [4,1], [5,1]])
317
- #cube.render
1
+ load "ChamferCube.rb"
2
+
3
+ class FilletCube < ChamferCube
4
+
5
+ attr_accessor :smooth
6
+
7
+ def initialize(args={})
8
+ super
9
+ @smooth = 30
10
+ @fillet = [].fill(0, 0..11)
11
+ end
12
+
13
+ def fillet_edge(edge, value)
14
+ @fillet[edge] = value
15
+ end
16
+
17
+ def fillet_edges(array)
18
+ array.each { |v| fillet_edge(v[0], v[1]) }
19
+ end
20
+
21
+ def fillet_side(side, value)
22
+ case side
23
+ when 0
24
+ fillet_edge(0, value)
25
+ fillet_edge(1, value)
26
+ fillet_edge(2, value)
27
+ fillet_edge(3, value)
28
+ when 1
29
+ fillet_edge(0, value)
30
+ fillet_edge(4, value)
31
+ fillet_edge(5, value)
32
+ fillet_edge(8, value)
33
+ when 2
34
+ fillet_edge(5, value)
35
+ fillet_edge(1, value)
36
+ fillet_edge(6, value)
37
+ fillet_edge(9, value)
38
+ when 3
39
+ fillet_edge(2, value)
40
+ fillet_edge(6, value)
41
+ fillet_edge(7, value)
42
+ fillet_edge(10, value)
43
+ when 4
44
+ fillet_edge(3, value)
45
+ fillet_edge(4, value)
46
+ fillet_edge(11, value)
47
+ fillet_edge(7, value)
48
+ when 5
49
+ fillet_edge(8, value)
50
+ fillet_edge(9, value)
51
+ fillet_edge(10, value)
52
+ fillet_edge(11, value)
53
+ end
54
+ end
55
+
56
+ def fillet_sides(array)
57
+ array.each{ |v| fillet_side(v[0], v[1]) }
58
+ end
59
+
60
+ def apply_fillet(edge, value)
61
+ case edge
62
+ when 0
63
+ translate(y: -y/2.0+value, z: z/2.0-value) {
64
+ difference() {
65
+ translate(y:-value-PAD, z: value+PAD) {
66
+ fillet_cube([x+2.0*PAD, value*2.0+PAD, value*2.0+PAD])
67
+ }
68
+ rotate(y: 90) { fillet_cylinder(x+4*PAD, value) }
69
+ }
70
+ }
71
+ when 1
72
+ translate(x: x/2.0-value, y: -y/2.0+value) {
73
+ difference() {
74
+ translate(x: value+PAD, y: -value-PAD) {
75
+ fillet_cube([value*2.0+PAD, value*2.0+PAD, z+2.0*PAD])
76
+ }
77
+ fillet_cylinder(z+4*PAD,value)
78
+ }
79
+ }
80
+ when 2
81
+ translate(y: -y/2.0+value, z: -z/2.0+value) {
82
+ difference() {
83
+ translate(y: -value-PAD, z: -value-PAD) {
84
+ fillet_cube([x+2.0*PAD, value*2.0+PAD, value*2.0+PAD])
85
+ }
86
+ rotate(y: 90) { fillet_cylinder(x+4*PAD,value) }
87
+ }
88
+ }
89
+ when 3
90
+ translate(x: -x/2.0+value, y: -y/2.0+value) {
91
+ difference() {
92
+ translate(x: -value-PAD, y: -value-PAD) {
93
+ fillet_cube([value*2.0+PAD, value*2.0+PAD, z+2.0*PAD])
94
+ }
95
+ fillet_cylinder(z+4*PAD,value)
96
+ }
97
+ }
98
+ when 4
99
+ translate(x: -x/2.0+value, z: z/2.0-value) {
100
+ difference() {
101
+ translate(x: -value-PAD, z: value+PAD) {
102
+ fillet_cube([value*2.0+PAD, y+2.0*PAD, value*2.0+PAD])
103
+ }
104
+ rotate(y: 90, z: 90) { fillet_cylinder(y+4*PAD, value) }
105
+ }
106
+ }
107
+ when 5
108
+ translate(x: x/2.0-value, z: z/2.0-value) {
109
+ difference() {
110
+ translate(x: value+PAD, z: value+PAD) {
111
+ fillet_cube([value*2.0+PAD, y+2.0*PAD, value*2.0+PAD])
112
+ }
113
+ rotate(y: 90, z: 90) { fillet_cylinder(y+4*PAD, value) }
114
+ }
115
+ }
116
+ when 6
117
+ translate(x: x/2.0-value, z: -z/2.0+value) {
118
+ difference() {
119
+ translate(x: value+PAD, z: -value-PAD) {
120
+ fillet_cube([value*2.0+PAD, y+2.0*PAD, value*2.0+PAD])
121
+ }
122
+ rotate(y: 90, z: 90) { fillet_cylinder(y+4*PAD, value) }
123
+ }
124
+ }
125
+ when 7
126
+ translate(x: -x/2.0+value, z: -z/2.0+value) {
127
+ difference() {
128
+ translate(x: -value-PAD, z: -value-PAD) {
129
+ fillet_cube([value*2.0+PAD, y+2.0*PAD, value*2.0+PAD])
130
+ }
131
+ rotate(y: 90, z: 90) { fillet_cylinder(y+4*PAD, value) }
132
+ }
133
+ }
134
+ when 8
135
+ translate(y: y/2.0-value, z: z/2.0-value) {
136
+ difference() {
137
+ translate(y: value+PAD, z: value+PAD) {
138
+ fillet_cube([x+2.0*PAD, value*2.0+PAD, value*2.0+PAD])
139
+ }
140
+ rotate(x: 90) { fillet_cylinder(x+4*PAD,value) }
141
+ }
142
+ }
143
+ when 9
144
+ translate(x: x/2.0-value, y: y/2.0-value) {
145
+ difference() {
146
+ translate(x: value+PAD, y: value+PAD) {
147
+ fillet_cube([value*2+PAD, value*2+PAD, z+2*PAD])
148
+ }
149
+ fillet_cylinder(z+4*PAD, value)
150
+ }
151
+ }
152
+ when 10
153
+ translate(y: y/2.0-value, z: -z/2.0+value) {
154
+ difference() {
155
+ translate(y: value+PAD, z: -value-PAD) {
156
+ fillet_cube([x+2.0*PAD, value*2.0+PAD, value*2.0+PAD])
157
+ }
158
+ rotate(x: 90) { fillet_cylinder(x+4*PAD,value) }
159
+ }
160
+ }
161
+ when 11
162
+ translate(x: -x/2.0+value, y: y/2.0-value) {
163
+ difference() {
164
+ translate(x: -value-PAD, y: value+PAD) {
165
+ fillet_cube([value*2.0+PAD, value*2.0+PAD, z+2.0*PAD])
166
+ }
167
+ fillet_cylinder(z+4*PAD, value)
168
+ }
169
+ }
170
+ end
171
+ end
172
+
173
+ def fillet_corner(corner, value)
174
+ case corner
175
+ when 0
176
+ translate(v:[-x/2.0+value, -y/2.0+value, z/2.0-value]) {
177
+ difference() {
178
+ translate(v:[-value-PAD, -value-PAD, value+PAD]) {
179
+ fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
180
+ }
181
+ fillet_sphere(value)
182
+ }
183
+ }
184
+ when 1
185
+ translate(v:[x/2.0-value, -y/2.0+value, z/2.0-value]) {
186
+ difference() {
187
+ translate(v:[value+PAD, -value-PAD, value+PAD]) {
188
+ fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
189
+ }
190
+ fillet_sphere(value)
191
+ }
192
+ }
193
+ when 2
194
+ translate(v:[x/2.0-value, -y/2.0+value, -z/2.0+value]) {
195
+ difference() {
196
+ translate(v:[value+PAD, -value-PAD, -value-PAD]) {
197
+ fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
198
+ }
199
+ fillet_sphere(value)
200
+ }
201
+ }
202
+ when 3
203
+ translate(v:[-x/2.0+value, -y/2.0+value, -z/2.0+value]) {
204
+ difference() {
205
+ translate(v:[-value-PAD, -value-PAD, -value-PAD]) {
206
+ fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
207
+ }
208
+ fillet_sphere(value)
209
+ }
210
+ }
211
+ when 4
212
+ translate(v:[-x/2.0+value, y/2.0-value, z/2.0-value]) {
213
+ difference() {
214
+ translate(v:[-value-PAD, value+PAD, value+PAD]) {
215
+ fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
216
+ }
217
+ fillet_sphere(value)
218
+ }
219
+ }
220
+ when 5
221
+ translate(v:[x/2.0-value, y/2.0-value, z/2.0-value]) {
222
+ difference() {
223
+ translate(v: [value+PAD, value+PAD, value+PAD]) {
224
+ fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
225
+ }
226
+ fillet_sphere(value)
227
+ }
228
+ }
229
+ when 6
230
+ translate(v:[x/2.0-value, y/2.0-value, -z/2.0+value]) {
231
+ difference() {
232
+ translate(v:[value+PAD, value+PAD, -value-PAD]) {
233
+ fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
234
+ }
235
+ fillet_sphere(value)
236
+ }
237
+ }
238
+ when 7
239
+ translate(v:[-x/2.0+value, y/2.0-value, -z/2.0+value]) {
240
+ difference() {
241
+ translate(v:[-value-PAD, value+PAD, -value-PAD]) {
242
+ fillet_cube([value*2.0+PAD, value*2.0+PAD, value*2.0+PAD])
243
+ }
244
+ fillet_sphere(value)
245
+ }
246
+ }
247
+ end
248
+ end
249
+
250
+ def fillet_sphere(r)
251
+ sphere(r: r, fn: @smooth)
252
+ end
253
+
254
+ def fillet_cylinder(height, radius)
255
+ cylinder(r: radius, h: height, center: true, fn: @smooth)
256
+ end
257
+
258
+ def fillet_cube(size)
259
+ cube(size: size, center:true)
260
+ end
261
+
262
+ def greater_than_0(*args)
263
+ args.each { |v| return nil if v <= 0 }
264
+ return true
265
+ end
266
+
267
+ def auto_corner_fillet()
268
+ if greater_than_0(@fillet[0], @fillet[3], @fillet[4])
269
+ fillet = average(@fillet[0], @fillet[3], @fillet[4])
270
+ fillet_corner(0, fillet)
271
+ end
272
+ if greater_than_0(@fillet[0], @fillet[1], @fillet[5])
273
+ fillet = average(@fillet[0], @fillet[1], @fillet[5])
274
+ fillet_corner(1, fillet)
275
+ end
276
+ if greater_than_0(@fillet[1], @fillet[2], @fillet[6])
277
+ fillet = average(@fillet[1], @fillet[2], @fillet[6])
278
+ fillet_corner(2, fillet)
279
+ end
280
+ if greater_than_0(@fillet[2], @fillet[3], @fillet[7])
281
+ fillet = average(@fillet[2], @fillet[3], @fillet[7])
282
+ fillet_corner(3, fillet)
283
+ end
284
+ if greater_than_0(@fillet[4], @fillet[8], @fillet[11])
285
+ fillet = average(@fillet[4], @fillet[8], @fillet[11])
286
+ fillet_corner(4, fillet)
287
+ end
288
+ if greater_than_0(@fillet[5], @fillet[8], @fillet[9])
289
+ fillet = average(@fillet[5], @fillet[8], @fillet[9])
290
+ fillet_corner(5, fillet)
291
+ end
292
+ if greater_than_0(@fillet[6], @fillet[9], @fillet[10])
293
+ fillet = average(@fillet[6], @fillet[9], @fillet[10])
294
+ fillet_corner(6, fillet)
295
+ end
296
+ if greater_than_0(@fillet[7], @fillet[10], @fillet[11])
297
+ fillet = average(@fillet[7], @fillet[10], @fillet[11])
298
+ fillet_corner(7, fillet)
299
+ end
300
+ end
301
+
302
+ def average(*args)
303
+ args.inject(0.0) { |sum, el| sum + el } / args.size
304
+ end
305
+
306
+ def render(args={})
307
+ difference {
308
+ super
309
+ @fillet.each_with_index { |v, i| apply_fillet(i, v) if v > 0 }
310
+ auto_corner_fillet()
311
+ }
312
+ end
313
+ end
314
+
315
+ #cube = FilletCube.new(size:[5, 7, 8], center: true)
316
+ #cube.fillet_sides([[0,1], [1,1], [2,1], [3,1], [4,1], [5,1]])
317
+ #cube.render