rubyscad 1.0.0
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.
- data/README.md +425 -0
- data/lib/RubyScad.rb +349 -0
- data/lib/rubyscad/version.rb +3 -0
- data/lib/rubyscad.rb +8 -0
- metadata +49 -0
data/README.md
ADDED
@@ -0,0 +1,425 @@
|
|
1
|
+
RubyScad
|
2
|
+
========
|
3
|
+
|
4
|
+
Ruby module to easily generate openscad scripts
|
5
|
+
|
6
|
+
General Usage
|
7
|
+
|
8
|
+
Requirements: Ruby 1.9.3
|
9
|
+
|
10
|
+
RubyScad is a ruby mixin module which provides functions which allow easy output of openscad scripts . To use simply "include" or "extend" the module into any class or module:
|
11
|
+
|
12
|
+
|
13
|
+
--------------------------------test.rb--------------------------------------
|
14
|
+
|
15
|
+
load "RubyScad.rb" #or use require but it must be in ruby's system path
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
module Test
|
20
|
+
|
21
|
+
extend RubyScad #extend makes all function available at the class level
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
def self.cone(base=5, height=10)
|
26
|
+
|
27
|
+
cylinder(r1: base, r2: 0, h:height)
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
cone(2, 4)
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
----------------------------------------------------------------------------
|
38
|
+
|
39
|
+
from command line:
|
40
|
+
|
41
|
+
print to standard output: ruby test.rb
|
42
|
+
|
43
|
+
generate file: ruby test.rb "test.scad"
|
44
|
+
|
45
|
+
--------------------------------test2.rb------------------------------------
|
46
|
+
|
47
|
+
load "RubyScad.rb" #or use require but it must be in ruby's system path
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
class Test2
|
52
|
+
|
53
|
+
include RubyScad #includ makes function available within the class/module
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
def initialize(args={})
|
58
|
+
|
59
|
+
@radius = args.fetch(:radius, 3)
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
def render()
|
66
|
+
|
67
|
+
sphere(r:@radius)
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
Test2.new.render
|
76
|
+
|
77
|
+
----------------------------------------------------------------------------
|
78
|
+
|
79
|
+
from command line:
|
80
|
+
|
81
|
+
print to standard output: ruby test2.rb
|
82
|
+
|
83
|
+
generate file: ruby test2.rb "test2.scad"
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
General Considerations:
|
90
|
+
|
91
|
+
-All arguments passed to rubyscad functions are passed as named hash values matching the openscad spec, exceptions are for functions fa, fs, fn, echo, include, and use (see below).
|
92
|
+
|
93
|
+
openscad: cube(6)
|
94
|
+
|
95
|
+
rubyscad: cube(size: 6)
|
96
|
+
|
97
|
+
-Any arguments may be passed to functions (with the exception of the ones noted above) but openscad may or may not use these values
|
98
|
+
|
99
|
+
-cube(openscadwontusethis: 5) will produce the following openscad
|
100
|
+
|
101
|
+
-cube(openscadwontusethis = 5);
|
102
|
+
|
103
|
+
nothing bad will happen here, the value will just have no effect
|
104
|
+
|
105
|
+
-$fn, $fs, $fa variables are passed without the '$'
|
106
|
+
|
107
|
+
openscad: sphere(4, $fn=12)
|
108
|
+
|
109
|
+
rubyscad: sphere(r: 4, fn: 12)
|
110
|
+
|
111
|
+
-Ruby's math functions use radians, openscad uses degrees, for ease I've added a 'radians' function to the numeric class so the following is possible
|
112
|
+
|
113
|
+
openscad: sin(15)
|
114
|
+
|
115
|
+
rubyscad: Math.sin(15.radians)
|
116
|
+
|
117
|
+
-All functions which take code blocks (union, difference, intersection, ...) can use the form "function() { code }" or "function()" with the following result
|
118
|
+
|
119
|
+
the code:
|
120
|
+
|
121
|
+
translate(x: 5)
|
122
|
+
|
123
|
+
cube(size: 7)
|
124
|
+
|
125
|
+
would produce:
|
126
|
+
|
127
|
+
translate([5,0,0])
|
128
|
+
|
129
|
+
cube(size = 7);
|
130
|
+
|
131
|
+
the code
|
132
|
+
|
133
|
+
translate(x: 5) {
|
134
|
+
|
135
|
+
cube(size: 7)
|
136
|
+
|
137
|
+
}
|
138
|
+
|
139
|
+
would produce:
|
140
|
+
|
141
|
+
translate([5,0,0]) {
|
142
|
+
|
143
|
+
cube(size = 7);
|
144
|
+
|
145
|
+
}
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
Openscad Functions:
|
150
|
+
|
151
|
+
----------------------------------------------------------------------------
|
152
|
+
|
153
|
+
openscad: $fa = 0.2;
|
154
|
+
|
155
|
+
rubyscad: fa 0.2
|
156
|
+
|
157
|
+
----------------------------------------------------------------------------
|
158
|
+
|
159
|
+
openscad: $fs = 2;
|
160
|
+
|
161
|
+
rubyscad: fs 2
|
162
|
+
|
163
|
+
----------------------------------------------------------------------------
|
164
|
+
|
165
|
+
openscad: $fn = 5;
|
166
|
+
|
167
|
+
rubyscad: fn 5
|
168
|
+
|
169
|
+
----------------------------------------------------------------------------
|
170
|
+
|
171
|
+
openscad: include <file.scad>
|
172
|
+
|
173
|
+
rubyscad: include_scad "file.scad"
|
174
|
+
|
175
|
+
----------------------------------------------------------------------------
|
176
|
+
|
177
|
+
openscad: use <file.scad>
|
178
|
+
|
179
|
+
rubyscad: use "file.scad"
|
180
|
+
|
181
|
+
----------------------------------------------------------------------------
|
182
|
+
|
183
|
+
openscad: echo(1,2,3);
|
184
|
+
|
185
|
+
rubyscad: echo 1, 2, 3
|
186
|
+
|
187
|
+
----------------------------------------------------------------------------
|
188
|
+
|
189
|
+
openscad: %
|
190
|
+
|
191
|
+
rubyscad: background
|
192
|
+
|
193
|
+
----------------------------------------------------------------------------
|
194
|
+
|
195
|
+
openscad: #
|
196
|
+
|
197
|
+
rubyscad: debug
|
198
|
+
|
199
|
+
----------------------------------------------------------------------------
|
200
|
+
|
201
|
+
openscad: !
|
202
|
+
|
203
|
+
rubyscad: root
|
204
|
+
|
205
|
+
----------------------------------------------------------------------------
|
206
|
+
|
207
|
+
openscad: *
|
208
|
+
|
209
|
+
rubyscad: disable
|
210
|
+
|
211
|
+
----------------------------------------------------------------------------
|
212
|
+
|
213
|
+
openscad: projection([args]) [{ code }]
|
214
|
+
|
215
|
+
rubyscad: projection([args]) [{ code }]
|
216
|
+
|
217
|
+
----------------------------------------------------------------------------
|
218
|
+
|
219
|
+
openscad: linear_extrude([args]) [{ code }]
|
220
|
+
|
221
|
+
rubyscad: linear_extrude([args]) [{ code }]
|
222
|
+
|
223
|
+
----------------------------------------------------------------------------
|
224
|
+
|
225
|
+
openscad: rotate_extrude([args]) [{ code }]
|
226
|
+
|
227
|
+
rubyscad: rotate_extrude([args]) [{ code }]
|
228
|
+
|
229
|
+
----------------------------------------------------------------------------
|
230
|
+
|
231
|
+
openscad: import([args])
|
232
|
+
|
233
|
+
rubyscad: import([args])
|
234
|
+
|
235
|
+
----------------------------------------------------------------------------
|
236
|
+
|
237
|
+
openscad: difference() { code }
|
238
|
+
|
239
|
+
rubyscad: difference() { code }
|
240
|
+
|
241
|
+
----------------------------------------------------------------------------
|
242
|
+
|
243
|
+
openscad: union() { code }
|
244
|
+
|
245
|
+
rubyscad: union() { code }
|
246
|
+
|
247
|
+
----------------------------------------------------------------------------
|
248
|
+
|
249
|
+
openscad: intersection() { code }
|
250
|
+
|
251
|
+
rubyscad: intersection() { code }
|
252
|
+
|
253
|
+
----------------------------------------------------------------------------
|
254
|
+
|
255
|
+
openscad: render([args]) [{ code }]
|
256
|
+
|
257
|
+
rubyscad: render([args]) [{ code }]
|
258
|
+
|
259
|
+
----------------------------------------------------------------------------
|
260
|
+
|
261
|
+
openscad: minkowski() { code }
|
262
|
+
|
263
|
+
rubyscad: minkowski() { code }
|
264
|
+
|
265
|
+
----------------------------------------------------------------------------
|
266
|
+
|
267
|
+
openscad: hull() { code }
|
268
|
+
|
269
|
+
rubyscad: hull() { code }
|
270
|
+
|
271
|
+
----------------------------------------------------------------------------
|
272
|
+
|
273
|
+
openscad: cube([args])
|
274
|
+
|
275
|
+
rubyscad: cube([args])
|
276
|
+
|
277
|
+
----------------------------------------------------------------------------
|
278
|
+
|
279
|
+
openscad: sphere([args])
|
280
|
+
|
281
|
+
rubyscad: sphere([args])
|
282
|
+
|
283
|
+
In addition to the normal arguments d: can also be provided instead of r: to
|
284
|
+
|
285
|
+
specify the diameter instead of the radius
|
286
|
+
|
287
|
+
----------------------------------------------------------------------------
|
288
|
+
|
289
|
+
openscad: polyhedron([args])
|
290
|
+
|
291
|
+
rubyscad: polyhedron([args])
|
292
|
+
|
293
|
+
----------------------------------------------------------------------------
|
294
|
+
|
295
|
+
openscad: square([args])
|
296
|
+
|
297
|
+
rubyscad: square([args])
|
298
|
+
|
299
|
+
----------------------------------------------------------------------------
|
300
|
+
|
301
|
+
openscad: circle([args])
|
302
|
+
|
303
|
+
rubyscad: circle([args])
|
304
|
+
|
305
|
+
In addition to the normal arguments d: can also be provided instead of r: to
|
306
|
+
|
307
|
+
specify the diameter instead of the radius
|
308
|
+
|
309
|
+
----------------------------------------------------------------------------
|
310
|
+
|
311
|
+
openscad: polygon([args])
|
312
|
+
|
313
|
+
rubyscad: polygon([args])
|
314
|
+
|
315
|
+
----------------------------------------------------------------------------
|
316
|
+
|
317
|
+
openscad: surface([args])
|
318
|
+
|
319
|
+
rubyscad: surface([args])
|
320
|
+
|
321
|
+
----------------------------------------------------------------------------
|
322
|
+
|
323
|
+
openscad: cylinder([args])
|
324
|
+
|
325
|
+
rubyscad: cylinder([args])
|
326
|
+
|
327
|
+
----------------------------------------------------------------------------
|
328
|
+
|
329
|
+
openscad: rotate([args]) [{ code }]
|
330
|
+
|
331
|
+
rubyscad: rotate([args]) [{ code }]
|
332
|
+
|
333
|
+
In addition to the normal arguments x:, y:, and z: can be used instead of
|
334
|
+
|
335
|
+
the normal vector input
|
336
|
+
|
337
|
+
----------------------------------------------------------------------------
|
338
|
+
|
339
|
+
openscad: translate([args]) [{ code }]
|
340
|
+
|
341
|
+
rubyscad: translate([args]) [{ code }]
|
342
|
+
|
343
|
+
In addition to the normal arguments x:, y:, and z: can be used instead of
|
344
|
+
|
345
|
+
the normal vector input
|
346
|
+
|
347
|
+
----------------------------------------------------------------------------
|
348
|
+
|
349
|
+
openscad: scale([args]) [{ code }]
|
350
|
+
|
351
|
+
rubyscad: scale([args]) [{ code }]
|
352
|
+
|
353
|
+
In addition to the normal arguments x:, y:, and z: can be used instead of
|
354
|
+
|
355
|
+
the normal vector input
|
356
|
+
|
357
|
+
----------------------------------------------------------------------------
|
358
|
+
|
359
|
+
openscad: mirror([args]) [{ code }]
|
360
|
+
|
361
|
+
rubyscad: mirror([args]) [{ code }]
|
362
|
+
|
363
|
+
In addition to the normal arguments x:, y:, and z: can be used instead of
|
364
|
+
|
365
|
+
the normal vector input
|
366
|
+
|
367
|
+
----------------------------------------------------------------------------
|
368
|
+
|
369
|
+
openscad: multmatrix([args]) [{ code }]
|
370
|
+
|
371
|
+
rubyscad: multmatrix([args]) [{ code }]
|
372
|
+
|
373
|
+
----------------------------------------------------------------------------
|
374
|
+
|
375
|
+
openscad: color([args]) [{ code }]
|
376
|
+
|
377
|
+
rubyscad: color([args]) [{ code }]
|
378
|
+
|
379
|
+
Instead of color: being a vector, r:, g:, b:, and a: can be provided
|
380
|
+
|
381
|
+
|
382
|
+
|
383
|
+
RubyScad Functions:
|
384
|
+
|
385
|
+
----------------------------------------------------------------------------
|
386
|
+
|
387
|
+
format_command(cmd_str, args={}, &block)
|
388
|
+
|
389
|
+
an easy way to implement new openscad commands.
|
390
|
+
|
391
|
+
cmd_str should be in the form "func_name(%<args>);"
|
392
|
+
|
393
|
+
all arguments passed from "args" will be inserted into the <args> string modifier, if
|
394
|
+
|
395
|
+
a block is passed it will output between { }
|
396
|
+
|
397
|
+
----------------------------------------------------------------------------
|
398
|
+
|
399
|
+
new_line
|
400
|
+
|
401
|
+
outputs a new line
|
402
|
+
|
403
|
+
----------------------------------------------------------------------------
|
404
|
+
|
405
|
+
start_block
|
406
|
+
|
407
|
+
outputs a { at the correct tab level
|
408
|
+
|
409
|
+
----------------------------------------------------------------------------
|
410
|
+
|
411
|
+
end_block
|
412
|
+
|
413
|
+
outputs a } at the correct tab level
|
414
|
+
|
415
|
+
----------------------------------------------------------------------------
|
416
|
+
|
417
|
+
end_all_blocks
|
418
|
+
|
419
|
+
outputs a } for every open block
|
420
|
+
|
421
|
+
----------------------------------------------------------------------------
|
422
|
+
|
423
|
+
format_output
|
424
|
+
|
425
|
+
outputs a string at the correct tab level
|
data/lib/RubyScad.rb
ADDED
@@ -0,0 +1,349 @@
|
|
1
|
+
require 'matrix'
|
2
|
+
|
3
|
+
class Numeric
|
4
|
+
def radians
|
5
|
+
self * Math::PI / 180
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Float
|
10
|
+
FP_P = 3
|
11
|
+
def to_s
|
12
|
+
"%.#{FP_P}f" % self.round(FP_P)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module RubyScad
|
17
|
+
START_BLOCK = "{"
|
18
|
+
END_BLOCK = "}"
|
19
|
+
TAB_SIZE = 3
|
20
|
+
PAD = 0.01
|
21
|
+
|
22
|
+
CUBE_STR = "cube(%<args>s);"
|
23
|
+
SPHERE_STR = "sphere(%<args>s);"
|
24
|
+
CYLINDER_STR = "cylinder(%<args>s);"
|
25
|
+
POLYHEDRON_STR = "polyhedron(%<args>s);"
|
26
|
+
SQUARE_STR = "square(%<args>s);"
|
27
|
+
CIRCLE_STR = "circle(%<args>s);"
|
28
|
+
POLYGON_STR = "polygon(%<args>s);"
|
29
|
+
TRANSLATE_STR = "translate(%<args>s)"
|
30
|
+
ROTATE_STR = "rotate(%<args>s)"
|
31
|
+
SCALE_STR = "scale(%<args>s)"
|
32
|
+
MIRROR_STR = "mirror(%<args>s)"
|
33
|
+
MULTMATRIX_STR = "multmatrix(%<args>s)"
|
34
|
+
COLOR_STR = "color(%<args>s)"
|
35
|
+
UNION_STR = "union(%<args>s)"
|
36
|
+
DIFFERENCE_STR = "difference(%<args>s)"
|
37
|
+
INTERSECTION_STR = "intersection(%<args>s)"
|
38
|
+
RENDER_STR = "render(%<args>s)"
|
39
|
+
MINKOWSKI_STR = "minkowski(%<args>s)"
|
40
|
+
HULL_STR = "hull(%<args>s)"
|
41
|
+
BACKGROUND_STR = '%'
|
42
|
+
DEBUG_STR = '#'
|
43
|
+
ROOT_STR = '!'
|
44
|
+
DISABLE_STR = '*'
|
45
|
+
IMPORT_STR = "import(%<args>s);"
|
46
|
+
SURFACE_STR = "surface(%<args>s);"
|
47
|
+
LINEAR_EXTRUDE_STR = "linear_extrude(%<args>s)"
|
48
|
+
ROTATE_EXTRUDE_STR = "rotate_extrude(%<args>s)"
|
49
|
+
PROJECTION_STR = "projection(%<args>s)"
|
50
|
+
|
51
|
+
INCLUDE_STR = "include <%<file>s>"
|
52
|
+
USE_STR = "use <%<file>s>"
|
53
|
+
ECHO_STR = "echo(%<string>s);"
|
54
|
+
FA_STR = "$fa = %<value>s;"
|
55
|
+
FS_STR = "$fs = %<value>s;"
|
56
|
+
FN_STR = "$fn = %<value>s;"
|
57
|
+
|
58
|
+
def fa(value)
|
59
|
+
format_output FA_STR % {value: value}
|
60
|
+
end
|
61
|
+
|
62
|
+
def fs(value)
|
63
|
+
format_output FS_STR % {value: value}
|
64
|
+
end
|
65
|
+
|
66
|
+
def fn(value)
|
67
|
+
format_output FN_STR % {value: value}
|
68
|
+
end
|
69
|
+
|
70
|
+
def include_scad(file)
|
71
|
+
format_output INCLUDE_STR % {file: file}
|
72
|
+
end
|
73
|
+
|
74
|
+
def use(file)
|
75
|
+
format_output USE_STR % {file: file}
|
76
|
+
end
|
77
|
+
|
78
|
+
def echo(*args)
|
79
|
+
format_output ECHO_STR % {string: args.join(', ')}
|
80
|
+
end
|
81
|
+
|
82
|
+
def projection(args={}, &block)
|
83
|
+
format_command PROJECTION_STR, args, &block
|
84
|
+
end
|
85
|
+
|
86
|
+
def linear_extrude(args={}, &block)
|
87
|
+
str_end = args.include?(:file) ? ";" : ""
|
88
|
+
format_command LINEAR_EXTRUDE_STR.concat(str_end), args, &block
|
89
|
+
end
|
90
|
+
|
91
|
+
def rotate_extrude(args={}, &block)
|
92
|
+
str_end = args.include?(:file) ? ";" : ""
|
93
|
+
format_command ROTATE_EXTRUDE_STR.concat(str_end), args, &block
|
94
|
+
end
|
95
|
+
|
96
|
+
def import(args={})
|
97
|
+
format_command IMPORT_STR, args
|
98
|
+
end
|
99
|
+
|
100
|
+
def difference(&block)
|
101
|
+
format_command DIFFERENCE_STR, &block
|
102
|
+
end
|
103
|
+
|
104
|
+
def union(&block)
|
105
|
+
format_command UNION_STR, &block
|
106
|
+
end
|
107
|
+
|
108
|
+
def intersection(&block)
|
109
|
+
format_command INTERSECTION_STR, &block
|
110
|
+
end
|
111
|
+
|
112
|
+
def render(args={}, &block)
|
113
|
+
format_command RENDER_STR, args, &block
|
114
|
+
end
|
115
|
+
|
116
|
+
def minkowski(&block)
|
117
|
+
format_command MINKOWSKI_STR, &block
|
118
|
+
end
|
119
|
+
|
120
|
+
def hull(&block)
|
121
|
+
format_command HULL_STR, &block
|
122
|
+
end
|
123
|
+
|
124
|
+
def background()
|
125
|
+
format_output BACKGROUND_STR
|
126
|
+
yield if block_given?
|
127
|
+
end
|
128
|
+
|
129
|
+
def debug()
|
130
|
+
format_output DEBUG_STR
|
131
|
+
yield if block_given?
|
132
|
+
end
|
133
|
+
|
134
|
+
def root()
|
135
|
+
format_output ROOT_STR
|
136
|
+
yield if block_given?
|
137
|
+
end
|
138
|
+
|
139
|
+
def disable()
|
140
|
+
format_output DISABLE_STR
|
141
|
+
yield if block_given?
|
142
|
+
end
|
143
|
+
|
144
|
+
def cube(args={})
|
145
|
+
format_command CUBE_STR, args
|
146
|
+
end
|
147
|
+
|
148
|
+
def sphere(args={})
|
149
|
+
if args.include?(:d)
|
150
|
+
args[:r] = args[:d]/2.0
|
151
|
+
args.delete(:d)
|
152
|
+
end
|
153
|
+
format_command SPHERE_STR, args
|
154
|
+
end
|
155
|
+
|
156
|
+
def polyhedron(args={})
|
157
|
+
format_command POLYHEDRON_STR, args
|
158
|
+
end
|
159
|
+
|
160
|
+
def square(args={})
|
161
|
+
format_command SQUARE_STR, args
|
162
|
+
end
|
163
|
+
|
164
|
+
def circle(args={})
|
165
|
+
if args.include?(:d)
|
166
|
+
args[:r] = args[:d]/2.0
|
167
|
+
args.delete(:d)
|
168
|
+
end
|
169
|
+
format_command CIRCLE_STR, args
|
170
|
+
end
|
171
|
+
|
172
|
+
def polygon(args={})
|
173
|
+
format_command POLYGON_STR, args
|
174
|
+
end
|
175
|
+
|
176
|
+
def surface(args={})
|
177
|
+
format_command SURFACE_STR, args
|
178
|
+
end
|
179
|
+
|
180
|
+
def cylinder(args={})
|
181
|
+
format_command CYLINDER_STR, args
|
182
|
+
end
|
183
|
+
|
184
|
+
def rotate(args={}, &block)
|
185
|
+
vector_input(args, :a)
|
186
|
+
format_command ROTATE_STR, args, &block
|
187
|
+
end
|
188
|
+
|
189
|
+
def translate(args={}, &block)
|
190
|
+
vector_input(args, :v)
|
191
|
+
format_command TRANSLATE_STR, args, &block
|
192
|
+
end
|
193
|
+
|
194
|
+
def scale(args={}, &block)
|
195
|
+
vector_input(args, :v)
|
196
|
+
format_command SCALE_STR, args, &block
|
197
|
+
end
|
198
|
+
|
199
|
+
def mirror(args={}, &block)
|
200
|
+
vector_input(args, :v)
|
201
|
+
format_command MIRROR_STR, args, &block
|
202
|
+
end
|
203
|
+
|
204
|
+
def multmatrix(args={}, &block)
|
205
|
+
format_command MULTMATRIX_STR, args, &block
|
206
|
+
end
|
207
|
+
|
208
|
+
def color(args={}, &block)
|
209
|
+
args[:color] = [args.fetch(:r, 0), args.fetch(:g, 0), args.fetch(:b, 0), args.fetch(:a, 1)] unless args.include?(:color)
|
210
|
+
delete_from(args, :r, :g, :b, :a)
|
211
|
+
format_command COLOR_STR, args, &block
|
212
|
+
end
|
213
|
+
|
214
|
+
def format_command(cmd_str, args={}, &block)
|
215
|
+
arg_str = args.collect { |k, v| "#{format_key(k)} = #{format_value(v)}" }.join(', ')
|
216
|
+
format_block cmd_str % {args: arg_str}, &block
|
217
|
+
end
|
218
|
+
|
219
|
+
def format_key(key)
|
220
|
+
key = key.to_s
|
221
|
+
key.prepend('$') if key.match("^f[asn]$")
|
222
|
+
key
|
223
|
+
end
|
224
|
+
|
225
|
+
def format_value(var)
|
226
|
+
if var.is_a?(Vector) or var.is_a?(Matrix)
|
227
|
+
return var.to_a.to_s
|
228
|
+
elsif var.is_a? String
|
229
|
+
return '"' + var + '"'
|
230
|
+
else
|
231
|
+
return var.to_s
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def delete_from(hash, *keys)
|
236
|
+
keys.each { |k| hash.delete(k) }
|
237
|
+
end
|
238
|
+
|
239
|
+
def vector_input(args, element)
|
240
|
+
unless args.include?(element)
|
241
|
+
args[element] = [args.fetch(:x, 0), args.fetch(:y, 0)]
|
242
|
+
args[element].push(args[:z]) if args.include?(:z)
|
243
|
+
delete_from(args, :x, :y, :z)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
def format_block(output_str)
|
248
|
+
format_output output_str.concat(' ')
|
249
|
+
if block_given?
|
250
|
+
start_block
|
251
|
+
yield
|
252
|
+
end_block
|
253
|
+
else
|
254
|
+
new_line unless output_str.include?(';')
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def new_line
|
259
|
+
format_output "\n"
|
260
|
+
end
|
261
|
+
|
262
|
+
def start_block()
|
263
|
+
format_output START_BLOCK
|
264
|
+
end
|
265
|
+
|
266
|
+
def end_block()
|
267
|
+
format_output END_BLOCK
|
268
|
+
end
|
269
|
+
|
270
|
+
def end_all_blocks()
|
271
|
+
end_block while @@tab_level > 0
|
272
|
+
end
|
273
|
+
|
274
|
+
def space_string(str, tab_level)
|
275
|
+
((' '*TAB_SIZE)*tab_level) + str
|
276
|
+
end
|
277
|
+
|
278
|
+
def raw_output(str)
|
279
|
+
if @@output_file
|
280
|
+
File.open(@@output_file, 'a') { |f| f.print(str) }
|
281
|
+
else
|
282
|
+
print str
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
def format_output(str)
|
287
|
+
@@prev_output ||= ""
|
288
|
+
@@tab_level ||= 0
|
289
|
+
str.lines do |l|
|
290
|
+
l.concat("\n") if l.match('[;\}\{>]')
|
291
|
+
@@tab_level-=1 if(l.include?('}')) && @@tab_level > 0
|
292
|
+
l = space_string(l, @@tab_level) if @@prev_output.include?("\n")
|
293
|
+
raw_output(l)
|
294
|
+
@@tab_level+=1 if(l.include?('{'))
|
295
|
+
@@prev_output = l
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
def self.start_output
|
300
|
+
@@output_file = nil
|
301
|
+
if ARGV[0] && ARGV[0].include?(".scad")
|
302
|
+
@@output_file = ARGV[0]
|
303
|
+
ARGV.shift
|
304
|
+
end
|
305
|
+
if @@output_file
|
306
|
+
File.open(@@output_file, 'w') do |f|
|
307
|
+
f.puts "//created with rubyscad #{VERSION}\n\n"
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
def self.extended(mod)
|
313
|
+
start_output
|
314
|
+
mod.class_variable_set(:@@fa, 30)
|
315
|
+
end
|
316
|
+
|
317
|
+
def self.included(mod)
|
318
|
+
start_output
|
319
|
+
end
|
320
|
+
|
321
|
+
start_output if __FILE__== $0
|
322
|
+
|
323
|
+
def lookup(x, points)
|
324
|
+
xmin, xmax = [0.0, 0.0]
|
325
|
+
points.keys.sort.reverse_each do |k|
|
326
|
+
if k <= x
|
327
|
+
xmin = k
|
328
|
+
break
|
329
|
+
end
|
330
|
+
end
|
331
|
+
points.keys.sort.each do |k|
|
332
|
+
if k >= x
|
333
|
+
xmax = k
|
334
|
+
break
|
335
|
+
end
|
336
|
+
end
|
337
|
+
return points[xmax] if x == xmax
|
338
|
+
return points[xmin] if x == xmin
|
339
|
+
return points[xmin] + (((x - xmin) * (points[xmax] - points[xmin])) / (xmax - xmin))
|
340
|
+
end
|
341
|
+
|
342
|
+
def dxf_cross(args={})
|
343
|
+
return 0.0
|
344
|
+
end
|
345
|
+
|
346
|
+
def dxf_dim(args={})
|
347
|
+
return 0.0
|
348
|
+
end
|
349
|
+
end
|
data/lib/rubyscad.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
# I put this file here to both make bundler happy with a gem named 'rubyscad'
|
2
|
+
# (all lowercase) and to provide a place to start breaking the project into
|
3
|
+
# smaller components.
|
4
|
+
#
|
5
|
+
# Hope that wasn't too presumptious :-\
|
6
|
+
require 'RubyScad'
|
7
|
+
|
8
|
+
require 'rubyscad/version'
|
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rubyscad
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Curtis Bissonnette
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-20 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Ruby module to easily generate openscad scripts
|
15
|
+
email:
|
16
|
+
- cjbissonnette
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/rubyscad/version.rb
|
22
|
+
- lib/rubyscad.rb
|
23
|
+
- lib/RubyScad.rb
|
24
|
+
- README.md
|
25
|
+
homepage: http://github.com/cjbissonnette
|
26
|
+
licenses: []
|
27
|
+
post_install_message:
|
28
|
+
rdoc_options: []
|
29
|
+
require_paths:
|
30
|
+
- lib
|
31
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
32
|
+
none: false
|
33
|
+
requirements:
|
34
|
+
- - ! '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '0'
|
37
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ! '>='
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
requirements: []
|
44
|
+
rubyforge_project:
|
45
|
+
rubygems_version: 1.8.24
|
46
|
+
signing_key:
|
47
|
+
specification_version: 3
|
48
|
+
summary: Ruby module to easily generate openscad scripts
|
49
|
+
test_files: []
|