crystalscad 0.2.3 → 0.2.4
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/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
|
|