crystalscad 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- data/crystalscad.gemspec +2 -1
- data/lib/crystalscad/Assembly.rb +55 -0
- data/lib/crystalscad/CrystalScad.rb +40 -8
- data/lib/crystalscad/Hardware.rb +80 -24
- data/lib/crystalscad/LinearBearing.rb +76 -0
- data/lib/crystalscad/version.rb +1 -1
- data/lib/crystalscad.rb +3 -0
- metadata +8 -6
data/crystalscad.gemspec
CHANGED
@@ -12,7 +12,8 @@ Gem::Specification.new do |gem|
|
|
12
12
|
gem.homepage = "http://github.com/Joaz/CrystalScad"
|
13
13
|
gem.summary = %q{Generate OpenSCAD scripts with ruby}
|
14
14
|
gem.description = %q{Inspired by SolidPython, based on RubyScad}
|
15
|
-
|
15
|
+
|
16
|
+
gem.license = 'GPL-3'
|
16
17
|
gem.files = `git ls-files`.split($/)
|
17
18
|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
18
19
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module CrystalScad
|
2
|
+
class Assembly
|
3
|
+
def initialize(args={})
|
4
|
+
@args = args if @args == nil
|
5
|
+
@@bom.add(description) unless args[:no_bom] == true
|
6
|
+
end
|
7
|
+
|
8
|
+
def description
|
9
|
+
"No description set for Class #{self.class.to_s}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def show
|
13
|
+
ScadObject.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def output
|
17
|
+
show
|
18
|
+
end
|
19
|
+
|
20
|
+
def walk_tree
|
21
|
+
return output.walk_tree
|
22
|
+
end
|
23
|
+
|
24
|
+
def +(args)
|
25
|
+
return self.output+args
|
26
|
+
end
|
27
|
+
|
28
|
+
def -(args)
|
29
|
+
return self.output-args
|
30
|
+
end
|
31
|
+
|
32
|
+
def *(args)
|
33
|
+
return self.output*args
|
34
|
+
end
|
35
|
+
|
36
|
+
def translate(args)
|
37
|
+
return self.output.translate(args)
|
38
|
+
end
|
39
|
+
|
40
|
+
def mirror(args)
|
41
|
+
return self.output.mirror(args)
|
42
|
+
end
|
43
|
+
|
44
|
+
def rotate(args)
|
45
|
+
return self.output.rotate(args)
|
46
|
+
end
|
47
|
+
|
48
|
+
def scad_output()
|
49
|
+
return self.output.scad_output
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
@@ -19,10 +19,12 @@ require "rubyscad"
|
|
19
19
|
module CrystalScad
|
20
20
|
include CrystalScad::BillOfMaterial
|
21
21
|
include CrystalScad::Hardware
|
22
|
-
|
22
|
+
include CrystalScad::LinearBearing
|
23
|
+
|
24
|
+
|
23
25
|
class ScadObject
|
24
26
|
attr_accessor :args
|
25
|
-
|
27
|
+
attr_accessor :transformations
|
26
28
|
def initialize(*args)
|
27
29
|
@transformations = []
|
28
30
|
@args = args.flatten
|
@@ -41,7 +43,7 @@ module CrystalScad
|
|
41
43
|
res += self.to_rubyscad.to_s+ "\n"
|
42
44
|
res
|
43
45
|
end
|
44
|
-
alias :
|
46
|
+
alias :scad_output :walk_tree
|
45
47
|
|
46
48
|
def to_rubyscad
|
47
49
|
""
|
@@ -52,6 +54,11 @@ module CrystalScad
|
|
52
54
|
class Primitive < ScadObject
|
53
55
|
|
54
56
|
def rotate(args)
|
57
|
+
# always make sure we have a z parameter; otherwise RubyScad will produce a 2-dimensional output
|
58
|
+
# which can result in openscad weirdness
|
59
|
+
if args[:z] == nil
|
60
|
+
args[:z] = 0
|
61
|
+
end
|
55
62
|
@transformations << Rotate.new(args)
|
56
63
|
self
|
57
64
|
end
|
@@ -66,6 +73,11 @@ module CrystalScad
|
|
66
73
|
self
|
67
74
|
end
|
68
75
|
|
76
|
+
def mirror(args)
|
77
|
+
@transformations << Mirror.new(args)
|
78
|
+
self
|
79
|
+
end
|
80
|
+
|
69
81
|
end
|
70
82
|
|
71
83
|
class TransformedObject < Primitive
|
@@ -96,7 +108,14 @@ module CrystalScad
|
|
96
108
|
return RubyScadBridge.new.translate(@args)
|
97
109
|
end
|
98
110
|
end
|
99
|
-
|
111
|
+
|
112
|
+
class Mirror < Transformation
|
113
|
+
def to_rubyscad
|
114
|
+
return RubyScadBridge.new.mirror(@args)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
|
100
119
|
class Cylinder < Primitive
|
101
120
|
def to_rubyscad
|
102
121
|
return RubyScadBridge.new.cylinder(@args)
|
@@ -108,6 +127,14 @@ module CrystalScad
|
|
108
127
|
end
|
109
128
|
|
110
129
|
class Cube < Primitive
|
130
|
+
attr_accessor :x,:y,:z
|
131
|
+
|
132
|
+
def initialize(*args)
|
133
|
+
super(args)
|
134
|
+
@x,@y,@z = args[0][:size].map{|l| l.to_f}
|
135
|
+
|
136
|
+
end
|
137
|
+
|
111
138
|
def to_rubyscad
|
112
139
|
return RubyScadBridge.new.cube(@args)
|
113
140
|
end
|
@@ -166,11 +193,9 @@ module CrystalScad
|
|
166
193
|
def format_block(output_str)
|
167
194
|
return output_str
|
168
195
|
end
|
169
|
-
|
170
|
-
|
171
196
|
end
|
172
197
|
|
173
|
-
|
198
|
+
|
174
199
|
def csg_operation(operation, code1, code2)
|
175
200
|
ret = "#{operation}(){"
|
176
201
|
ret +=code1
|
@@ -180,20 +205,27 @@ module CrystalScad
|
|
180
205
|
end
|
181
206
|
|
182
207
|
def +(args)
|
208
|
+
return args if self == nil
|
183
209
|
csg_operation("union",self.walk_tree,args.walk_tree)
|
184
210
|
end
|
185
211
|
|
186
212
|
def -(args)
|
213
|
+
return args if self == nil
|
187
214
|
csg_operation("difference",self.walk_tree,args.walk_tree)
|
188
215
|
end
|
189
216
|
|
190
217
|
def *(args)
|
218
|
+
return args if self == nil
|
191
219
|
csg_operation("intersection",self.walk_tree,args.walk_tree)
|
192
220
|
end
|
193
221
|
|
222
|
+
def hull(part1,part2)
|
223
|
+
csg_operation("hull",part1.walk_tree,part2.walk_tree)
|
224
|
+
end
|
225
|
+
|
194
226
|
# Fixme: currently just accepting named colors
|
195
227
|
def color(args)
|
196
|
-
|
228
|
+
ret = "color(\"#{args}\"){"
|
197
229
|
ret +=self.walk_tree
|
198
230
|
ret +="}"
|
199
231
|
return TransformedObject.new(ret)
|
data/lib/crystalscad/Hardware.rb
CHANGED
@@ -13,53 +13,107 @@
|
|
13
13
|
# You should have received a copy of the GNU General Public License
|
14
14
|
# along with CrystalScad. If not, see <http://www.gnu.org/licenses/>.
|
15
15
|
|
16
|
-
module CrystalScad::Hardware
|
16
|
+
module CrystalScad::Hardware
|
17
|
+
|
18
|
+
class Bolt < CrystalScad::Assembly
|
19
|
+
def initialize(size,length,args={})
|
20
|
+
@args = args
|
21
|
+
@args[:type] ||= "912"
|
22
|
+
@args[:material] ||= "8.8"
|
23
|
+
@args[:surface] ||= "zinc plated"
|
24
|
+
# options for output only:
|
25
|
+
@args[:additional_length] ||= 0
|
26
|
+
@args[:additional_diameter] ||= 0.2
|
17
27
|
|
18
|
-
class Bolt
|
19
|
-
def initialize(size,length, type="912", material="8.8", surface="zinc plated")
|
20
28
|
@size = size
|
21
29
|
@length = length
|
22
|
-
|
23
|
-
@material = material
|
24
|
-
@surface = surface
|
30
|
+
|
25
31
|
|
26
32
|
@@bom.add(description)
|
27
33
|
end
|
28
34
|
|
29
35
|
def description
|
30
|
-
"M#{@size}x#{@length} Bolt, DIN #{@type}, #{@material} #{@surface}"
|
36
|
+
"M#{@size}x#{@length} Bolt, DIN #{@args[:type]}, #{@args[:material]} #{@args[:surface]}"
|
31
37
|
end
|
32
38
|
|
33
39
|
def output
|
34
|
-
return bolt_912
|
40
|
+
return bolt_912(@args[:additional_length],@args[:additional_diameter])
|
41
|
+
end
|
42
|
+
|
43
|
+
def show
|
44
|
+
return bolt_912(0,0)
|
35
45
|
end
|
36
46
|
|
37
47
|
# currently only din912
|
38
|
-
def bolt_912(
|
48
|
+
def bolt_912(additional_length=0, addtional_diameter=0)
|
39
49
|
|
40
50
|
|
41
|
-
chart_din912 = {
|
51
|
+
chart_din912 = {2 => {head_dia:3.8,head_length:2,thread_length:16},
|
52
|
+
2.5=> {head_dia:4.5,head_length:2.5,thread_length:17},
|
53
|
+
3 => {head_dia:5.5,head_length:3,thread_length:18},
|
42
54
|
4 => {head_dia:7.0,head_length:4,thread_length:20},
|
43
55
|
5 => {head_dia:8.5,head_length:5,thread_length:22},
|
44
|
-
|
56
|
+
6 => {head_dia:10,head_length:6,thread_length:24},
|
57
|
+
8 => {head_dia:13,head_length:8,thread_length:28},
|
58
|
+
10=> {head_dia:16,head_length:10,thread_length:32},
|
59
|
+
12=> {head_dia:18,head_length:12,thread_length:36},
|
60
|
+
14=> {head_dia:21,head_length:14,thread_length:40},
|
61
|
+
16=> {head_dia:24,head_length:16,thread_length:44},
|
62
|
+
18=> {head_dia:27,head_length:18,thread_length:48},
|
63
|
+
20=> {head_dia:30,head_length:20,thread_length:52},
|
64
|
+
22=> {head_dia:33,head_length:22,thread_length:56},
|
65
|
+
24=> {head_dia:36,head_length:24,thread_length:60},
|
66
|
+
30=> {head_dia:45,head_length:30,thread_length:72},
|
67
|
+
36=> {head_dia:54,head_length:36,thread_length:84},
|
68
|
+
|
69
|
+
|
45
70
|
}
|
46
71
|
|
47
72
|
res = cylinder(d:chart_din912[@size][:head_dia],h:chart_din912[@size][:head_length]).translate(z:-chart_din912[@size][:head_length]).color("Gainsboro")
|
48
73
|
|
74
|
+
total_length = @length + additional_length
|
49
75
|
thread_length=chart_din912[@size][:thread_length]
|
50
|
-
if
|
51
|
-
res+= cylinder(d:@size+
|
76
|
+
if total_length.to_f <= thread_length
|
77
|
+
res+= cylinder(d:@size+addtional_diameter, h:total_length).color("DarkGray")
|
52
78
|
else
|
53
|
-
res+= cylinder(d:@size+
|
54
|
-
res+= cylinder(d:@size+
|
79
|
+
res+= cylinder(d:@size+addtional_diameter, h:total_length-thread_length).color("Gainsboro")
|
80
|
+
res+= cylinder(d:@size+addtional_diameter, h:thread_length).translate(z:total_length-thread_length).color("DarkGray")
|
55
81
|
end
|
56
82
|
res
|
57
83
|
end
|
58
84
|
|
59
85
|
end
|
86
|
+
|
87
|
+
class Washer < CrystalScad::Assembly
|
88
|
+
def initialize(size,args={})
|
89
|
+
@args=args
|
90
|
+
@size = size
|
91
|
+
@args[:type] ||= "125"
|
92
|
+
@args[:material] ||= "steel"
|
93
|
+
@args[:surface] ||= "zinc plated"
|
94
|
+
|
95
|
+
@chart_din125 = { 3.2 => {outer_diameter:7, height:0.5},
|
96
|
+
4.3 => {outer_diameter:9, height:0.8},
|
97
|
+
5.3 => {outer_diameter:10, height:1.0},
|
98
|
+
|
99
|
+
}
|
100
|
+
|
101
|
+
super(args)
|
102
|
+
end
|
60
103
|
|
104
|
+
def description
|
105
|
+
"Washer #{@args[:size]}, Material #{@args[:material]} #{@args[:surface]}"
|
106
|
+
end
|
107
|
+
|
108
|
+
def show
|
109
|
+
washer = cylinder(d:@chart_din125[@size][:outer_diameter].to_f,h:@chart_din125[@size][:height].to_f)
|
110
|
+
washer-= cylinder(d:@size,h:@chart_din125[@size][:outer_diameter].to_f+0.2).translate(z:-0.1)
|
111
|
+
washer.color("Gainsboro")
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
61
115
|
|
62
|
-
class Nut
|
116
|
+
class Nut < CrystalScad::Assembly
|
63
117
|
attr_accessor :height
|
64
118
|
def initialize(size,args={})
|
65
119
|
@size = size
|
@@ -108,7 +162,7 @@ module CrystalScad::Hardware
|
|
108
162
|
end
|
109
163
|
|
110
164
|
|
111
|
-
class TSlot
|
165
|
+
class TSlot < CrystalScad::Assembly
|
112
166
|
# the code in this class is based on code by Nathan Zadoks
|
113
167
|
# taken from https://github.com/nathan7/scadlib
|
114
168
|
# Ported to CrystalScad by Joachim Glauche
|
@@ -128,13 +182,15 @@ module CrystalScad::Hardware
|
|
128
182
|
if length != nil
|
129
183
|
@args[:length] = length
|
130
184
|
end
|
131
|
-
@@bom.add(
|
185
|
+
@@bom.add(description) unless args[:no_bom] == true
|
132
186
|
|
133
187
|
return TransformedObject.new(single_profile.output) if @args[:configuration] == 1
|
134
188
|
return TransformedObject.new(multi_profile.output)
|
135
189
|
end
|
190
|
+
|
191
|
+
alias :show :output
|
136
192
|
|
137
|
-
def
|
193
|
+
def description
|
138
194
|
"T-Slot #{@args[:size]}x#{@args[:size]*@args[:configuration]}, length #{@args[:length]}mm"
|
139
195
|
end
|
140
196
|
|
@@ -151,7 +207,7 @@ module CrystalScad::Hardware
|
|
151
207
|
profile-=circle(r:gap/2,center:true);
|
152
208
|
profile=profile.translate(x:size/2,y:size/2);
|
153
209
|
|
154
|
-
return profile.linear_extrude(height:@args[:length])
|
210
|
+
return profile.linear_extrude(height:@args[:length],convexity:2)
|
155
211
|
end
|
156
212
|
|
157
213
|
def multi_profile
|
@@ -175,12 +231,12 @@ module CrystalScad::Hardware
|
|
175
231
|
|
176
232
|
alias tslot_output output
|
177
233
|
|
178
|
-
def output(length)
|
234
|
+
def output(length=nil)
|
179
235
|
tslot_output(length)-bolts
|
180
236
|
end
|
181
237
|
|
182
|
-
def show
|
183
|
-
output+bolts
|
238
|
+
def show(length=nil)
|
239
|
+
output(length)+bolts
|
184
240
|
end
|
185
241
|
|
186
242
|
def bolts
|
@@ -202,7 +258,7 @@ module CrystalScad::Hardware
|
|
202
258
|
bolt
|
203
259
|
end
|
204
260
|
|
205
|
-
def
|
261
|
+
def description
|
206
262
|
str = "T-Slot #{@args[:size]}x#{@args[:size]*@args[:configuration]}, length #{@args[:length]}mm"
|
207
263
|
if @args[:holes] != nil
|
208
264
|
str << " with holes for M#{@args[:bolt_size]} on "+ @args[:holes].split(",").join(' and ')
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# This file is part of CrystalScad.
|
2
|
+
#
|
3
|
+
# CrystalScad is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# CrystalScad is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with CrystalScad. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
module CrystalScad::LinearBearing
|
17
|
+
|
18
|
+
class Lm_uu < CrystalScad::Assembly
|
19
|
+
|
20
|
+
def initialize(args={inner_diameter:10})
|
21
|
+
@args = args
|
22
|
+
@lm_uu = {
|
23
|
+
3 => {diameter:7, length:10},
|
24
|
+
4 => {diameter:8, length:12},
|
25
|
+
5 => {diameter:10, length:15},
|
26
|
+
6 => {diameter:12, length:19},
|
27
|
+
8 => {diameter:15, length:24},
|
28
|
+
10 => {diameter:19, length:29},
|
29
|
+
12 => {diameter:21, length:30},
|
30
|
+
13 => {diameter:23, length:32},
|
31
|
+
16 => {diameter:28, length:37},
|
32
|
+
20 => {diameter:32, length:42},
|
33
|
+
25 => {diameter:40, length:59},
|
34
|
+
30 => {diameter:45, length:64},
|
35
|
+
35 => {diameter:52, length:70},
|
36
|
+
40 => {diameter:60, length:80},
|
37
|
+
50 => {diameter:80, length:100},
|
38
|
+
60 => {diameter:90, length:110},
|
39
|
+
|
40
|
+
}
|
41
|
+
@shell_thickness = 1.1
|
42
|
+
@@bom.add(description) unless args[:no_bom] == true
|
43
|
+
end
|
44
|
+
|
45
|
+
def description
|
46
|
+
"LM#{@args[:inner_diameter]}UU Linear bearing"
|
47
|
+
end
|
48
|
+
|
49
|
+
def output
|
50
|
+
show
|
51
|
+
end
|
52
|
+
|
53
|
+
def dimensions
|
54
|
+
diameter = @lm_uu[@args[:inner_diameter]][:diameter]
|
55
|
+
length = @lm_uu[@args[:inner_diameter]][:length]
|
56
|
+
return diameter, length
|
57
|
+
end
|
58
|
+
|
59
|
+
def show
|
60
|
+
diameter, length = dimensions
|
61
|
+
shell=cylinder(d:diameter, h:length)
|
62
|
+
shell-=cylinder(d:diameter-@shell_thickness*2, h:length+0.2).translate(z:-0.1)
|
63
|
+
shell=shell.color("LightGrey")
|
64
|
+
|
65
|
+
inner = cylinder(d:diameter-@shell_thickness*2, h:length)
|
66
|
+
inner-= cylinder(d:@args[:inner_diameter], h:length+0.2).translate(z:-0.1)
|
67
|
+
inner=inner.color("DimGray")
|
68
|
+
|
69
|
+
shell+inner
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
data/lib/crystalscad/version.rb
CHANGED
data/lib/crystalscad.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crystalscad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 31
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 4
|
10
|
+
version: 0.2.4
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Joachim Glauche
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2013-09-
|
18
|
+
date: 2013-09-13 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description: Inspired by SolidPython, based on RubyScad
|
@@ -34,13 +34,15 @@ files:
|
|
34
34
|
- Rakefile
|
35
35
|
- crystalscad.gemspec
|
36
36
|
- lib/crystalscad.rb
|
37
|
+
- lib/crystalscad/Assembly.rb
|
37
38
|
- lib/crystalscad/BillOfMaterial.rb
|
38
39
|
- lib/crystalscad/CrystalScad.rb
|
39
40
|
- lib/crystalscad/Hardware.rb
|
41
|
+
- lib/crystalscad/LinearBearing.rb
|
40
42
|
- lib/crystalscad/version.rb
|
41
43
|
homepage: http://github.com/Joaz/CrystalScad
|
42
|
-
licenses:
|
43
|
-
|
44
|
+
licenses:
|
45
|
+
- GPL-3
|
44
46
|
post_install_message:
|
45
47
|
rdoc_options: []
|
46
48
|
|