rubyscad 1.0.6 → 1.0.7
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.
- checksums.yaml +7 -0
- data/.gitignore +21 -21
- data/Gemfile +4 -4
- data/LICENSE.txt +21 -21
- data/README.md +322 -322
- data/Rakefile +1 -1
- data/examples/BasicCube.rb +50 -50
- data/examples/ChamferCube.rb +96 -96
- data/examples/FilletCube.rb +317 -317
- data/examples/example001.rb +33 -33
- data/examples/example001.scad +11 -11
- data/examples/example002.rb +23 -23
- data/examples/example002.scad +18 -18
- data/examples/example003.rb +19 -19
- data/examples/example003.scad +15 -15
- data/examples/example004.rb +11 -11
- data/examples/example004.scad +6 -6
- data/examples/example005.rb +22 -22
- data/examples/example005.scad +31 -31
- data/examples/example006.rb +46 -46
- data/examples/example006.scad +221 -221
- data/examples/example007.dxf +2410 -2410
- data/examples/example007.rb +53 -53
- data/examples/example007.scad +30 -30
- data/examples/example008.dxf +3238 -3238
- data/examples/example008.rb +34 -34
- data/examples/example008.scad +26 -26
- data/examples/example009.dxf +3894 -3894
- data/examples/example009.rb +33 -33
- data/examples/example009.scad +15 -15
- data/examples/example010.dat +51 -51
- data/examples/example010.rb +12 -12
- data/examples/example010.scad +7 -7
- data/examples/example011.rb +22 -22
- data/examples/example011.scad +3 -3
- data/examples/example012.rb +16 -16
- data/examples/example012.scad +8 -8
- data/examples/example013.dxf +2276 -2276
- data/examples/example013.rb +16 -16
- data/examples/example013.scad +12 -12
- data/examples/example014.rb +14 -14
- data/examples/example014.scad +12 -12
- data/examples/example015.rb +33 -33
- data/examples/example015.scad +22 -22
- data/examples/example016.rb +43 -43
- data/examples/example016.scad +49 -49
- data/examples/example017.rb +170 -170
- data/examples/example017.scad +124 -124
- data/examples/example018.rb +29 -29
- data/examples/example018.scad +74 -74
- data/examples/example019.rb +22 -22
- data/examples/example019.scad +84 -84
- data/examples/example020.rb +92 -92
- data/examples/example020.scad +62 -62
- data/examples/example021.rb +42 -42
- data/examples/example021.scad +159 -159
- data/examples/example022.rb +44 -44
- data/examples/example022.scad +103 -103
- data/lib/rubyscad.rb +2 -2
- data/lib/rubyscad/RubyScad.rb +369 -361
- data/lib/rubyscad/version.rb +3 -3
- data/rubyscad.gemspec +20 -20
- metadata +7 -9
data/examples/example022.scad
CHANGED
@@ -1,103 +1,103 @@
|
|
1
|
-
//created with rubyscad 1.0
|
2
|
-
|
3
|
-
translate(v = [-15, 0, 0]) {
|
4
|
-
cube(size = [10.000, 30.000, 40.000], center = true);
|
5
|
-
cube(size = [20.000, 20.000, 40.000], center = true);
|
6
|
-
translate(v = [-5.000, -10.000])
|
7
|
-
cylinder(r = 5.000, h = 40.000, center = true);
|
8
|
-
translate(v = [-5.000, 10.000])
|
9
|
-
cylinder(r = 5.000, h = 40.000, center = true);
|
10
|
-
translate(v = [5.000, -10.000])
|
11
|
-
cylinder(r = 5.000, h = 40.000, center = true);
|
12
|
-
translate(v = [5.000, 10.000])
|
13
|
-
cylinder(r = 5.000, h = 40.000, center = true);
|
14
|
-
}
|
15
|
-
translate(v = [15, 0, 0]) {
|
16
|
-
cube(size = [20.000, 20.000, 30.000], center = true);
|
17
|
-
cube(size = [10.000, 30.000, 30.000], center = true);
|
18
|
-
cube(size = [10.000, 20.000, 40.000], center = true);
|
19
|
-
rotate(a = [0, 0, 0])
|
20
|
-
translate(v = [-5.000, -10.000, 0])
|
21
|
-
cylinder(h = 30.000, r = 5, center = true);
|
22
|
-
rotate(a = [0, 0, 0])
|
23
|
-
translate(v = [-5.000, 10.000, 0])
|
24
|
-
cylinder(h = 30.000, r = 5, center = true);
|
25
|
-
rotate(a = [0, 0, 0])
|
26
|
-
translate(v = [5.000, -10.000, 0])
|
27
|
-
cylinder(h = 30.000, r = 5, center = true);
|
28
|
-
rotate(a = [0, 0, 0])
|
29
|
-
translate(v = [5.000, 10.000, 0])
|
30
|
-
cylinder(h = 30.000, r = 5, center = true);
|
31
|
-
translate(v = [-5.000, -10.000, -15.000])
|
32
|
-
sphere(r = 5);
|
33
|
-
translate(v = [-5.000, -10.000, 15.000])
|
34
|
-
sphere(r = 5);
|
35
|
-
translate(v = [-5.000, 10.000, -15.000])
|
36
|
-
sphere(r = 5);
|
37
|
-
translate(v = [-5.000, 10.000, 15.000])
|
38
|
-
sphere(r = 5);
|
39
|
-
translate(v = [5.000, -10.000, -15.000])
|
40
|
-
sphere(r = 5);
|
41
|
-
translate(v = [5.000, -10.000, 15.000])
|
42
|
-
sphere(r = 5);
|
43
|
-
translate(v = [5.000, 10.000, -15.000])
|
44
|
-
sphere(r = 5);
|
45
|
-
translate(v = [5.000, 10.000, 15.000])
|
46
|
-
sphere(r = 5);
|
47
|
-
rotate(a = [90, 0, 90])
|
48
|
-
translate(v = [-10.000, -15.000, 0])
|
49
|
-
cylinder(h = 10.000, r = 5, center = true);
|
50
|
-
rotate(a = [90, 0, 90])
|
51
|
-
translate(v = [-10.000, 15.000, 0])
|
52
|
-
cylinder(h = 10.000, r = 5, center = true);
|
53
|
-
rotate(a = [90, 0, 90])
|
54
|
-
translate(v = [10.000, -15.000, 0])
|
55
|
-
cylinder(h = 10.000, r = 5, center = true);
|
56
|
-
rotate(a = [90, 0, 90])
|
57
|
-
translate(v = [10.000, 15.000, 0])
|
58
|
-
cylinder(h = 10.000, r = 5, center = true);
|
59
|
-
translate(v = [-5.000, -10.000, -15.000])
|
60
|
-
sphere(r = 5);
|
61
|
-
translate(v = [-5.000, -10.000, 15.000])
|
62
|
-
sphere(r = 5);
|
63
|
-
translate(v = [-5.000, 10.000, -15.000])
|
64
|
-
sphere(r = 5);
|
65
|
-
translate(v = [-5.000, 10.000, 15.000])
|
66
|
-
sphere(r = 5);
|
67
|
-
translate(v = [5.000, -10.000, -15.000])
|
68
|
-
sphere(r = 5);
|
69
|
-
translate(v = [5.000, -10.000, 15.000])
|
70
|
-
sphere(r = 5);
|
71
|
-
translate(v = [5.000, 10.000, -15.000])
|
72
|
-
sphere(r = 5);
|
73
|
-
translate(v = [5.000, 10.000, 15.000])
|
74
|
-
sphere(r = 5);
|
75
|
-
rotate(a = [90, 90, 0])
|
76
|
-
translate(v = [-15.000, -5.000, 0])
|
77
|
-
cylinder(h = 20.000, r = 5, center = true);
|
78
|
-
rotate(a = [90, 90, 0])
|
79
|
-
translate(v = [-15.000, 5.000, 0])
|
80
|
-
cylinder(h = 20.000, r = 5, center = true);
|
81
|
-
rotate(a = [90, 90, 0])
|
82
|
-
translate(v = [15.000, -5.000, 0])
|
83
|
-
cylinder(h = 20.000, r = 5, center = true);
|
84
|
-
rotate(a = [90, 90, 0])
|
85
|
-
translate(v = [15.000, 5.000, 0])
|
86
|
-
cylinder(h = 20.000, r = 5, center = true);
|
87
|
-
translate(v = [-5.000, -10.000, -15.000])
|
88
|
-
sphere(r = 5);
|
89
|
-
translate(v = [-5.000, -10.000, 15.000])
|
90
|
-
sphere(r = 5);
|
91
|
-
translate(v = [-5.000, 10.000, -15.000])
|
92
|
-
sphere(r = 5);
|
93
|
-
translate(v = [-5.000, 10.000, 15.000])
|
94
|
-
sphere(r = 5);
|
95
|
-
translate(v = [5.000, -10.000, -15.000])
|
96
|
-
sphere(r = 5);
|
97
|
-
translate(v = [5.000, -10.000, 15.000])
|
98
|
-
sphere(r = 5);
|
99
|
-
translate(v = [5.000, 10.000, -15.000])
|
100
|
-
sphere(r = 5);
|
101
|
-
translate(v = [5.000, 10.000, 15.000])
|
102
|
-
sphere(r = 5);
|
103
|
-
}
|
1
|
+
//created with rubyscad 1.0
|
2
|
+
|
3
|
+
translate(v = [-15, 0, 0]) {
|
4
|
+
cube(size = [10.000, 30.000, 40.000], center = true);
|
5
|
+
cube(size = [20.000, 20.000, 40.000], center = true);
|
6
|
+
translate(v = [-5.000, -10.000])
|
7
|
+
cylinder(r = 5.000, h = 40.000, center = true);
|
8
|
+
translate(v = [-5.000, 10.000])
|
9
|
+
cylinder(r = 5.000, h = 40.000, center = true);
|
10
|
+
translate(v = [5.000, -10.000])
|
11
|
+
cylinder(r = 5.000, h = 40.000, center = true);
|
12
|
+
translate(v = [5.000, 10.000])
|
13
|
+
cylinder(r = 5.000, h = 40.000, center = true);
|
14
|
+
}
|
15
|
+
translate(v = [15, 0, 0]) {
|
16
|
+
cube(size = [20.000, 20.000, 30.000], center = true);
|
17
|
+
cube(size = [10.000, 30.000, 30.000], center = true);
|
18
|
+
cube(size = [10.000, 20.000, 40.000], center = true);
|
19
|
+
rotate(a = [0, 0, 0])
|
20
|
+
translate(v = [-5.000, -10.000, 0])
|
21
|
+
cylinder(h = 30.000, r = 5, center = true);
|
22
|
+
rotate(a = [0, 0, 0])
|
23
|
+
translate(v = [-5.000, 10.000, 0])
|
24
|
+
cylinder(h = 30.000, r = 5, center = true);
|
25
|
+
rotate(a = [0, 0, 0])
|
26
|
+
translate(v = [5.000, -10.000, 0])
|
27
|
+
cylinder(h = 30.000, r = 5, center = true);
|
28
|
+
rotate(a = [0, 0, 0])
|
29
|
+
translate(v = [5.000, 10.000, 0])
|
30
|
+
cylinder(h = 30.000, r = 5, center = true);
|
31
|
+
translate(v = [-5.000, -10.000, -15.000])
|
32
|
+
sphere(r = 5);
|
33
|
+
translate(v = [-5.000, -10.000, 15.000])
|
34
|
+
sphere(r = 5);
|
35
|
+
translate(v = [-5.000, 10.000, -15.000])
|
36
|
+
sphere(r = 5);
|
37
|
+
translate(v = [-5.000, 10.000, 15.000])
|
38
|
+
sphere(r = 5);
|
39
|
+
translate(v = [5.000, -10.000, -15.000])
|
40
|
+
sphere(r = 5);
|
41
|
+
translate(v = [5.000, -10.000, 15.000])
|
42
|
+
sphere(r = 5);
|
43
|
+
translate(v = [5.000, 10.000, -15.000])
|
44
|
+
sphere(r = 5);
|
45
|
+
translate(v = [5.000, 10.000, 15.000])
|
46
|
+
sphere(r = 5);
|
47
|
+
rotate(a = [90, 0, 90])
|
48
|
+
translate(v = [-10.000, -15.000, 0])
|
49
|
+
cylinder(h = 10.000, r = 5, center = true);
|
50
|
+
rotate(a = [90, 0, 90])
|
51
|
+
translate(v = [-10.000, 15.000, 0])
|
52
|
+
cylinder(h = 10.000, r = 5, center = true);
|
53
|
+
rotate(a = [90, 0, 90])
|
54
|
+
translate(v = [10.000, -15.000, 0])
|
55
|
+
cylinder(h = 10.000, r = 5, center = true);
|
56
|
+
rotate(a = [90, 0, 90])
|
57
|
+
translate(v = [10.000, 15.000, 0])
|
58
|
+
cylinder(h = 10.000, r = 5, center = true);
|
59
|
+
translate(v = [-5.000, -10.000, -15.000])
|
60
|
+
sphere(r = 5);
|
61
|
+
translate(v = [-5.000, -10.000, 15.000])
|
62
|
+
sphere(r = 5);
|
63
|
+
translate(v = [-5.000, 10.000, -15.000])
|
64
|
+
sphere(r = 5);
|
65
|
+
translate(v = [-5.000, 10.000, 15.000])
|
66
|
+
sphere(r = 5);
|
67
|
+
translate(v = [5.000, -10.000, -15.000])
|
68
|
+
sphere(r = 5);
|
69
|
+
translate(v = [5.000, -10.000, 15.000])
|
70
|
+
sphere(r = 5);
|
71
|
+
translate(v = [5.000, 10.000, -15.000])
|
72
|
+
sphere(r = 5);
|
73
|
+
translate(v = [5.000, 10.000, 15.000])
|
74
|
+
sphere(r = 5);
|
75
|
+
rotate(a = [90, 90, 0])
|
76
|
+
translate(v = [-15.000, -5.000, 0])
|
77
|
+
cylinder(h = 20.000, r = 5, center = true);
|
78
|
+
rotate(a = [90, 90, 0])
|
79
|
+
translate(v = [-15.000, 5.000, 0])
|
80
|
+
cylinder(h = 20.000, r = 5, center = true);
|
81
|
+
rotate(a = [90, 90, 0])
|
82
|
+
translate(v = [15.000, -5.000, 0])
|
83
|
+
cylinder(h = 20.000, r = 5, center = true);
|
84
|
+
rotate(a = [90, 90, 0])
|
85
|
+
translate(v = [15.000, 5.000, 0])
|
86
|
+
cylinder(h = 20.000, r = 5, center = true);
|
87
|
+
translate(v = [-5.000, -10.000, -15.000])
|
88
|
+
sphere(r = 5);
|
89
|
+
translate(v = [-5.000, -10.000, 15.000])
|
90
|
+
sphere(r = 5);
|
91
|
+
translate(v = [-5.000, 10.000, -15.000])
|
92
|
+
sphere(r = 5);
|
93
|
+
translate(v = [-5.000, 10.000, 15.000])
|
94
|
+
sphere(r = 5);
|
95
|
+
translate(v = [5.000, -10.000, -15.000])
|
96
|
+
sphere(r = 5);
|
97
|
+
translate(v = [5.000, -10.000, 15.000])
|
98
|
+
sphere(r = 5);
|
99
|
+
translate(v = [5.000, 10.000, -15.000])
|
100
|
+
sphere(r = 5);
|
101
|
+
translate(v = [5.000, 10.000, 15.000])
|
102
|
+
sphere(r = 5);
|
103
|
+
}
|
data/lib/rubyscad.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
require 'rubyscad/version'
|
2
|
-
require 'rubyscad/RubyScad'
|
1
|
+
require 'rubyscad/version'
|
2
|
+
require 'rubyscad/RubyScad'
|
data/lib/rubyscad/RubyScad.rb
CHANGED
@@ -1,361 +1,369 @@
|
|
1
|
-
require 'rubyscad/version'
|
2
|
-
require 'matrix'
|
3
|
-
|
4
|
-
class Numeric
|
5
|
-
def radians
|
6
|
-
self * Math::PI / 180
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
class Float
|
11
|
-
FP_P = 3
|
12
|
-
def to_s
|
13
|
-
"%.#{FP_P}f" % self.round(FP_P)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
module RubyScad
|
18
|
-
START_BLOCK = "{"
|
19
|
-
END_BLOCK = "}"
|
20
|
-
TAB_SIZE = 3
|
21
|
-
PAD = 0.01
|
22
|
-
|
23
|
-
CUBE_STR = "cube(%<args>s);"
|
24
|
-
SPHERE_STR = "sphere(%<args>s);"
|
25
|
-
CYLINDER_STR = "cylinder(%<args>s);"
|
26
|
-
POLYHEDRON_STR = "polyhedron(%<args>s);"
|
27
|
-
SQUARE_STR = "square(%<args>s);"
|
28
|
-
CIRCLE_STR = "circle(%<args>s);"
|
29
|
-
POLYGON_STR = "polygon(%<args>s);"
|
30
|
-
TRANSLATE_STR = "translate(%<args>s)"
|
31
|
-
ROTATE_STR = "rotate(%<args>s)"
|
32
|
-
SCALE_STR = "scale(%<args>s)"
|
33
|
-
MIRROR_STR = "mirror(%<args>s)"
|
34
|
-
MULTMATRIX_STR = "multmatrix(%<args>s)"
|
35
|
-
COLOR_STR = "color(%<args>s)"
|
36
|
-
UNION_STR = "union(%<args>s)"
|
37
|
-
DIFFERENCE_STR = "difference(%<args>s)"
|
38
|
-
INTERSECTION_STR = "intersection(%<args>s)"
|
39
|
-
RENDER_STR = "render(%<args>s)"
|
40
|
-
MINKOWSKI_STR = "minkowski(%<args>s)"
|
41
|
-
HULL_STR = "hull(%<args>s)"
|
42
|
-
BACKGROUND_STR = '%'
|
43
|
-
DEBUG_STR = '#'
|
44
|
-
ROOT_STR = '!'
|
45
|
-
DISABLE_STR = '*'
|
46
|
-
IMPORT_STR = "import(%<args>s);"
|
47
|
-
SURFACE_STR = "surface(%<args>s);"
|
48
|
-
LINEAR_EXTRUDE_STR = "linear_extrude(%<args>s)"
|
49
|
-
ROTATE_EXTRUDE_STR = "rotate_extrude(%<args>s)"
|
50
|
-
PROJECTION_STR = "projection(%<args>s)"
|
51
|
-
|
52
|
-
INCLUDE_STR = "include <%<file>s>"
|
53
|
-
USE_STR = "use <%<file>s>"
|
54
|
-
ECHO_STR = "echo(%<string>s);"
|
55
|
-
FA_STR = "$fa = %<value>s;"
|
56
|
-
FS_STR = "$fs = %<value>s;"
|
57
|
-
FN_STR = "$fn = %<value>s;"
|
58
|
-
|
59
|
-
def fa(value)
|
60
|
-
format_output FA_STR % {value: value}
|
61
|
-
end
|
62
|
-
|
63
|
-
def fs(value)
|
64
|
-
format_output FS_STR % {value: value}
|
65
|
-
end
|
66
|
-
|
67
|
-
def fn(value)
|
68
|
-
format_output FN_STR % {value: value}
|
69
|
-
end
|
70
|
-
|
71
|
-
def include_scad(file)
|
72
|
-
format_output INCLUDE_STR % {file: file}
|
73
|
-
end
|
74
|
-
|
75
|
-
def use(file)
|
76
|
-
format_output USE_STR % {file: file}
|
77
|
-
end
|
78
|
-
|
79
|
-
def echo(*args)
|
80
|
-
format_output ECHO_STR % {string: args.join(', ')}
|
81
|
-
end
|
82
|
-
|
83
|
-
def projection(args={}, &block)
|
84
|
-
format_command PROJECTION_STR, args, &block
|
85
|
-
end
|
86
|
-
|
87
|
-
def linear_extrude(args={}, &block)
|
88
|
-
str_end = args.include?(:file) ? ";" : ""
|
89
|
-
format_command LINEAR_EXTRUDE_STR.concat(str_end), args, &block
|
90
|
-
end
|
91
|
-
|
92
|
-
def rotate_extrude(args={}, &block)
|
93
|
-
str_end = args.include?(:file) ? ";" : ""
|
94
|
-
format_command ROTATE_EXTRUDE_STR.concat(str_end), args, &block
|
95
|
-
end
|
96
|
-
|
97
|
-
def import(args={})
|
98
|
-
format_command IMPORT_STR, args
|
99
|
-
end
|
100
|
-
|
101
|
-
def difference(&block)
|
102
|
-
format_command DIFFERENCE_STR, &block
|
103
|
-
end
|
104
|
-
|
105
|
-
def union(&block)
|
106
|
-
format_command UNION_STR, &block
|
107
|
-
end
|
108
|
-
|
109
|
-
def intersection(&block)
|
110
|
-
format_command INTERSECTION_STR, &block
|
111
|
-
end
|
112
|
-
|
113
|
-
def render(args={}, &block)
|
114
|
-
format_command RENDER_STR, args, &block
|
115
|
-
end
|
116
|
-
|
117
|
-
def minkowski(&block)
|
118
|
-
format_command MINKOWSKI_STR, &block
|
119
|
-
end
|
120
|
-
|
121
|
-
def hull(&block)
|
122
|
-
format_command HULL_STR, &block
|
123
|
-
end
|
124
|
-
|
125
|
-
def background()
|
126
|
-
format_output BACKGROUND_STR
|
127
|
-
yield if block_given?
|
128
|
-
end
|
129
|
-
|
130
|
-
def debug()
|
131
|
-
format_output DEBUG_STR
|
132
|
-
yield if block_given?
|
133
|
-
end
|
134
|
-
|
135
|
-
def root()
|
136
|
-
format_output ROOT_STR
|
137
|
-
yield if block_given?
|
138
|
-
end
|
139
|
-
|
140
|
-
def disable()
|
141
|
-
format_output DISABLE_STR
|
142
|
-
yield if block_given?
|
143
|
-
end
|
144
|
-
|
145
|
-
def cube(args={})
|
146
|
-
format_command CUBE_STR, args
|
147
|
-
end
|
148
|
-
|
149
|
-
def sphere(args={})
|
150
|
-
if args.include?(:d)
|
151
|
-
args[:r] = args[:d]/2.0
|
152
|
-
args.delete(:d)
|
153
|
-
end
|
154
|
-
format_command SPHERE_STR, args
|
155
|
-
end
|
156
|
-
|
157
|
-
def polyhedron(args={})
|
158
|
-
format_command POLYHEDRON_STR, args
|
159
|
-
end
|
160
|
-
|
161
|
-
def square(args={})
|
162
|
-
format_command SQUARE_STR, args
|
163
|
-
end
|
164
|
-
|
165
|
-
def circle(args={})
|
166
|
-
if args.include?(:d)
|
167
|
-
args[:r] = args[:d]/2.0
|
168
|
-
args.delete(:d)
|
169
|
-
end
|
170
|
-
format_command CIRCLE_STR, args
|
171
|
-
end
|
172
|
-
|
173
|
-
def polygon(args={})
|
174
|
-
format_command POLYGON_STR, args
|
175
|
-
end
|
176
|
-
|
177
|
-
def surface(args={})
|
178
|
-
format_command SURFACE_STR, args
|
179
|
-
end
|
180
|
-
|
181
|
-
def cylinder(args={})
|
182
|
-
if args.include?(:d)
|
183
|
-
args[:r] = args[:d]/2.0
|
184
|
-
args.delete(:d)
|
185
|
-
end
|
186
|
-
if args.include?(:d1)
|
187
|
-
args[:r1] = args[:d1]/2.0
|
188
|
-
args.delete(:d1)
|
189
|
-
end
|
190
|
-
if args.include?(:d2)
|
191
|
-
args[:r2] = args[:d2]/2.0
|
192
|
-
args.delete(:d2)
|
193
|
-
end
|
194
|
-
format_command CYLINDER_STR, args
|
195
|
-
end
|
196
|
-
|
197
|
-
def rotate(args={}, &block)
|
198
|
-
vector_input(args, :a)
|
199
|
-
format_command ROTATE_STR, args, &block
|
200
|
-
end
|
201
|
-
|
202
|
-
def translate(args={}, &block)
|
203
|
-
vector_input(args, :v)
|
204
|
-
format_command TRANSLATE_STR, args, &block
|
205
|
-
end
|
206
|
-
|
207
|
-
def scale(args={}, &block)
|
208
|
-
vector_input(args, :v)
|
209
|
-
format_command SCALE_STR, args, &block
|
210
|
-
end
|
211
|
-
|
212
|
-
def mirror(args={}, &block)
|
213
|
-
vector_input(args, :v)
|
214
|
-
format_command MIRROR_STR, args, &block
|
215
|
-
end
|
216
|
-
|
217
|
-
def multmatrix(args={}, &block)
|
218
|
-
format_command MULTMATRIX_STR, args, &block
|
219
|
-
end
|
220
|
-
|
221
|
-
def color(args={}, &block)
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
end
|
259
|
-
|
260
|
-
def
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
end
|
278
|
-
|
279
|
-
def
|
280
|
-
format_output
|
281
|
-
end
|
282
|
-
|
283
|
-
def
|
284
|
-
|
285
|
-
end
|
286
|
-
|
287
|
-
def
|
288
|
-
|
289
|
-
end
|
290
|
-
|
291
|
-
def
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
end
|
298
|
-
|
299
|
-
def
|
300
|
-
@@
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
@@
|
316
|
-
|
317
|
-
end
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
end
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
return
|
360
|
-
end
|
361
|
-
|
1
|
+
require 'rubyscad/version'
|
2
|
+
require 'matrix'
|
3
|
+
|
4
|
+
class Numeric
|
5
|
+
def radians
|
6
|
+
self * Math::PI / 180
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Float
|
11
|
+
FP_P = 3
|
12
|
+
def to_s
|
13
|
+
"%.#{FP_P}f" % self.round(FP_P)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module RubyScad
|
18
|
+
START_BLOCK = "{"
|
19
|
+
END_BLOCK = "}"
|
20
|
+
TAB_SIZE = 3
|
21
|
+
PAD = 0.01
|
22
|
+
|
23
|
+
CUBE_STR = "cube(%<args>s);"
|
24
|
+
SPHERE_STR = "sphere(%<args>s);"
|
25
|
+
CYLINDER_STR = "cylinder(%<args>s);"
|
26
|
+
POLYHEDRON_STR = "polyhedron(%<args>s);"
|
27
|
+
SQUARE_STR = "square(%<args>s);"
|
28
|
+
CIRCLE_STR = "circle(%<args>s);"
|
29
|
+
POLYGON_STR = "polygon(%<args>s);"
|
30
|
+
TRANSLATE_STR = "translate(%<args>s)"
|
31
|
+
ROTATE_STR = "rotate(%<args>s)"
|
32
|
+
SCALE_STR = "scale(%<args>s)"
|
33
|
+
MIRROR_STR = "mirror(%<args>s)"
|
34
|
+
MULTMATRIX_STR = "multmatrix(%<args>s)"
|
35
|
+
COLOR_STR = "color(%<args>s)"
|
36
|
+
UNION_STR = "union(%<args>s)"
|
37
|
+
DIFFERENCE_STR = "difference(%<args>s)"
|
38
|
+
INTERSECTION_STR = "intersection(%<args>s)"
|
39
|
+
RENDER_STR = "render(%<args>s)"
|
40
|
+
MINKOWSKI_STR = "minkowski(%<args>s)"
|
41
|
+
HULL_STR = "hull(%<args>s)"
|
42
|
+
BACKGROUND_STR = '%'
|
43
|
+
DEBUG_STR = '#'
|
44
|
+
ROOT_STR = '!'
|
45
|
+
DISABLE_STR = '*'
|
46
|
+
IMPORT_STR = "import(%<args>s);"
|
47
|
+
SURFACE_STR = "surface(%<args>s);"
|
48
|
+
LINEAR_EXTRUDE_STR = "linear_extrude(%<args>s)"
|
49
|
+
ROTATE_EXTRUDE_STR = "rotate_extrude(%<args>s)"
|
50
|
+
PROJECTION_STR = "projection(%<args>s)"
|
51
|
+
|
52
|
+
INCLUDE_STR = "include <%<file>s>"
|
53
|
+
USE_STR = "use <%<file>s>"
|
54
|
+
ECHO_STR = "echo(%<string>s);"
|
55
|
+
FA_STR = "$fa = %<value>s;"
|
56
|
+
FS_STR = "$fs = %<value>s;"
|
57
|
+
FN_STR = "$fn = %<value>s;"
|
58
|
+
|
59
|
+
def fa(value)
|
60
|
+
format_output FA_STR % {value: value}
|
61
|
+
end
|
62
|
+
|
63
|
+
def fs(value)
|
64
|
+
format_output FS_STR % {value: value}
|
65
|
+
end
|
66
|
+
|
67
|
+
def fn(value)
|
68
|
+
format_output FN_STR % {value: value}
|
69
|
+
end
|
70
|
+
|
71
|
+
def include_scad(file)
|
72
|
+
format_output INCLUDE_STR % {file: file}
|
73
|
+
end
|
74
|
+
|
75
|
+
def use(file)
|
76
|
+
format_output USE_STR % {file: file}
|
77
|
+
end
|
78
|
+
|
79
|
+
def echo(*args)
|
80
|
+
format_output ECHO_STR % {string: args.join(', ')}
|
81
|
+
end
|
82
|
+
|
83
|
+
def projection(args={}, &block)
|
84
|
+
format_command PROJECTION_STR, args, &block
|
85
|
+
end
|
86
|
+
|
87
|
+
def linear_extrude(args={}, &block)
|
88
|
+
str_end = args.include?(:file) ? ";" : ""
|
89
|
+
format_command LINEAR_EXTRUDE_STR.concat(str_end), args, &block
|
90
|
+
end
|
91
|
+
|
92
|
+
def rotate_extrude(args={}, &block)
|
93
|
+
str_end = args.include?(:file) ? ";" : ""
|
94
|
+
format_command ROTATE_EXTRUDE_STR.concat(str_end), args, &block
|
95
|
+
end
|
96
|
+
|
97
|
+
def import(args={})
|
98
|
+
format_command IMPORT_STR, args
|
99
|
+
end
|
100
|
+
|
101
|
+
def difference(&block)
|
102
|
+
format_command DIFFERENCE_STR, &block
|
103
|
+
end
|
104
|
+
|
105
|
+
def union(&block)
|
106
|
+
format_command UNION_STR, &block
|
107
|
+
end
|
108
|
+
|
109
|
+
def intersection(&block)
|
110
|
+
format_command INTERSECTION_STR, &block
|
111
|
+
end
|
112
|
+
|
113
|
+
def render(args={}, &block)
|
114
|
+
format_command RENDER_STR, args, &block
|
115
|
+
end
|
116
|
+
|
117
|
+
def minkowski(&block)
|
118
|
+
format_command MINKOWSKI_STR, &block
|
119
|
+
end
|
120
|
+
|
121
|
+
def hull(&block)
|
122
|
+
format_command HULL_STR, &block
|
123
|
+
end
|
124
|
+
|
125
|
+
def background()
|
126
|
+
format_output BACKGROUND_STR
|
127
|
+
yield if block_given?
|
128
|
+
end
|
129
|
+
|
130
|
+
def debug()
|
131
|
+
format_output DEBUG_STR
|
132
|
+
yield if block_given?
|
133
|
+
end
|
134
|
+
|
135
|
+
def root()
|
136
|
+
format_output ROOT_STR
|
137
|
+
yield if block_given?
|
138
|
+
end
|
139
|
+
|
140
|
+
def disable()
|
141
|
+
format_output DISABLE_STR
|
142
|
+
yield if block_given?
|
143
|
+
end
|
144
|
+
|
145
|
+
def cube(args={})
|
146
|
+
format_command CUBE_STR, args
|
147
|
+
end
|
148
|
+
|
149
|
+
def sphere(args={})
|
150
|
+
if args.include?(:d)
|
151
|
+
args[:r] = args[:d]/2.0
|
152
|
+
args.delete(:d)
|
153
|
+
end
|
154
|
+
format_command SPHERE_STR, args
|
155
|
+
end
|
156
|
+
|
157
|
+
def polyhedron(args={})
|
158
|
+
format_command POLYHEDRON_STR, args
|
159
|
+
end
|
160
|
+
|
161
|
+
def square(args={})
|
162
|
+
format_command SQUARE_STR, args
|
163
|
+
end
|
164
|
+
|
165
|
+
def circle(args={})
|
166
|
+
if args.include?(:d)
|
167
|
+
args[:r] = args[:d]/2.0
|
168
|
+
args.delete(:d)
|
169
|
+
end
|
170
|
+
format_command CIRCLE_STR, args
|
171
|
+
end
|
172
|
+
|
173
|
+
def polygon(args={})
|
174
|
+
format_command POLYGON_STR, args
|
175
|
+
end
|
176
|
+
|
177
|
+
def surface(args={})
|
178
|
+
format_command SURFACE_STR, args
|
179
|
+
end
|
180
|
+
|
181
|
+
def cylinder(args={})
|
182
|
+
if args.include?(:d)
|
183
|
+
args[:r] = args[:d]/2.0
|
184
|
+
args.delete(:d)
|
185
|
+
end
|
186
|
+
if args.include?(:d1)
|
187
|
+
args[:r1] = args[:d1]/2.0
|
188
|
+
args.delete(:d1)
|
189
|
+
end
|
190
|
+
if args.include?(:d2)
|
191
|
+
args[:r2] = args[:d2]/2.0
|
192
|
+
args.delete(:d2)
|
193
|
+
end
|
194
|
+
format_command CYLINDER_STR, args
|
195
|
+
end
|
196
|
+
|
197
|
+
def rotate(args={}, &block)
|
198
|
+
vector_input(args, :a)
|
199
|
+
format_command ROTATE_STR, args, &block
|
200
|
+
end
|
201
|
+
|
202
|
+
def translate(args={}, &block)
|
203
|
+
vector_input(args, :v)
|
204
|
+
format_command TRANSLATE_STR, args, &block
|
205
|
+
end
|
206
|
+
|
207
|
+
def scale(args={}, &block)
|
208
|
+
vector_input(args, :v)
|
209
|
+
format_command SCALE_STR, args, &block
|
210
|
+
end
|
211
|
+
|
212
|
+
def mirror(args={}, &block)
|
213
|
+
vector_input(args, :v)
|
214
|
+
format_command MIRROR_STR, args, &block
|
215
|
+
end
|
216
|
+
|
217
|
+
def multmatrix(args={}, &block)
|
218
|
+
format_command MULTMATRIX_STR, args, &block
|
219
|
+
end
|
220
|
+
|
221
|
+
def color(args={}, &block)
|
222
|
+
unless args.include?(:color)
|
223
|
+
args[:color] = [args.fetch(:r, 0), args.fetch(:g, 0), args.fetch(:b, 0), args.fetch(:a, 1)].to_s
|
224
|
+
else
|
225
|
+
args[:color] = "\"#{args[:color]}\""
|
226
|
+
end
|
227
|
+
delete_from(args, :r, :g, :b, :a)
|
228
|
+
format_command(COLOR_STR, args[:color], &block)
|
229
|
+
end
|
230
|
+
|
231
|
+
def format_command(cmd_str, args={}, &block)
|
232
|
+
unless args.kind_of? String
|
233
|
+
arg_str = args.collect { |k, v| "#{format_key(k)} = #{format_value(v)}" }.join(', ')
|
234
|
+
else
|
235
|
+
arg_str = args
|
236
|
+
end
|
237
|
+
format_block cmd_str % {args: arg_str}, &block
|
238
|
+
end
|
239
|
+
|
240
|
+
def format_key(key)
|
241
|
+
key = key.to_s
|
242
|
+
key.prepend('$') if key.match("^f[asn]$")
|
243
|
+
key
|
244
|
+
end
|
245
|
+
|
246
|
+
def format_value(var)
|
247
|
+
if var.is_a?(Vector) or var.is_a?(Matrix)
|
248
|
+
return var.to_a.to_s
|
249
|
+
elsif var.is_a? String
|
250
|
+
return '"' + var + '"'
|
251
|
+
else
|
252
|
+
return var.to_s
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def delete_from(hash, *keys)
|
257
|
+
keys.each { |k| hash.delete(k) }
|
258
|
+
end
|
259
|
+
|
260
|
+
def vector_input(args, element)
|
261
|
+
unless args.include?(element)
|
262
|
+
args[element] = [args.fetch(:x, 0), args.fetch(:y, 0)]
|
263
|
+
args[element].push(args[:z]) if args.include?(:z)
|
264
|
+
delete_from(args, :x, :y, :z)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
def format_block(output_str)
|
269
|
+
format_output output_str.concat(' ')
|
270
|
+
if block_given?
|
271
|
+
start_block
|
272
|
+
yield
|
273
|
+
end_block
|
274
|
+
else
|
275
|
+
new_line unless output_str.include?(';')
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
def new_line
|
280
|
+
format_output "\n"
|
281
|
+
end
|
282
|
+
|
283
|
+
def start_block()
|
284
|
+
format_output START_BLOCK
|
285
|
+
end
|
286
|
+
|
287
|
+
def end_block()
|
288
|
+
format_output END_BLOCK
|
289
|
+
end
|
290
|
+
|
291
|
+
def end_all_blocks()
|
292
|
+
end_block while @@tab_level > 0
|
293
|
+
end
|
294
|
+
|
295
|
+
def space_string(str, tab_level)
|
296
|
+
((' '*TAB_SIZE)*tab_level) + str
|
297
|
+
end
|
298
|
+
|
299
|
+
def raw_output(str)
|
300
|
+
if @@output_file
|
301
|
+
File.open(@@output_file, 'a') { |f| f.print(str) }
|
302
|
+
else
|
303
|
+
print str
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
def format_output(str)
|
308
|
+
@@prev_output ||= ""
|
309
|
+
@@tab_level ||= 0
|
310
|
+
str.lines do |l|
|
311
|
+
l.concat("\n") if l.match('[;\}\{>]')
|
312
|
+
@@tab_level-=1 if(l.include?('}')) && @@tab_level > 0
|
313
|
+
l = space_string(l, @@tab_level) if @@prev_output.include?("\n")
|
314
|
+
raw_output(l)
|
315
|
+
@@tab_level+=1 if(l.include?('{'))
|
316
|
+
@@prev_output = l
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
def self.start_output
|
321
|
+
@@output_file ||= nil
|
322
|
+
if ARGV[0] && ARGV[0].include?(".scad")
|
323
|
+
@@output_file = ARGV[0]
|
324
|
+
ARGV.shift
|
325
|
+
end
|
326
|
+
if @@output_file
|
327
|
+
File.open(@@output_file, 'w') do |f|
|
328
|
+
f.puts "//created with rubyscad #{VERSION}\n\n"
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
def self.extended(mod)
|
334
|
+
start_output
|
335
|
+
end
|
336
|
+
|
337
|
+
def self.included(mod)
|
338
|
+
start_output
|
339
|
+
end
|
340
|
+
|
341
|
+
start_output if __FILE__== $0
|
342
|
+
|
343
|
+
def lookup(x, points)
|
344
|
+
xmin, xmax = [0.0, 0.0]
|
345
|
+
points.keys.sort.reverse_each do |k|
|
346
|
+
if k <= x
|
347
|
+
xmin = k
|
348
|
+
break
|
349
|
+
end
|
350
|
+
end
|
351
|
+
points.keys.sort.each do |k|
|
352
|
+
if k >= x
|
353
|
+
xmax = k
|
354
|
+
break
|
355
|
+
end
|
356
|
+
end
|
357
|
+
return points[xmax] if x == xmax
|
358
|
+
return points[xmin] if x == xmin
|
359
|
+
return points[xmin] + (((x - xmin) * (points[xmax] - points[xmin])) / (xmax - xmin))
|
360
|
+
end
|
361
|
+
|
362
|
+
def dxf_cross(args={})
|
363
|
+
return 0.0
|
364
|
+
end
|
365
|
+
|
366
|
+
def dxf_dim(args={})
|
367
|
+
return 0.0
|
368
|
+
end
|
369
|
+
end
|