crystalscad 0.3.7 → 0.3.8
Sign up to get free protection for your applications and to get access to all the features.
- data/examples/openscad_examples/example001.rb +45 -0
- data/examples/openscad_examples/example002.rb +51 -0
- data/examples/openscad_examples/example003.rb +42 -0
- data/examples/openscad_examples/example004.rb +29 -0
- data/examples/openscad_examples/example005.rb +58 -0
- data/examples/printed_gear.rb +14 -0
- data/examples/threads2.rb +102 -0
- data/lib/crystalscad/Assembly.rb +18 -0
- data/lib/crystalscad/CrystalScad.rb +23 -3
- data/lib/crystalscad/Gears.rb +78 -2
- data/lib/crystalscad/ScrewThreads.rb +49 -4
- data/lib/crystalscad/version.rb +1 -1
- metadata +11 -4
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
size=50
|
7
|
+
hole=25
|
8
|
+
h = size * 2.5
|
9
|
+
|
10
|
+
res = sphere(d:size)
|
11
|
+
res -= cylinder(d:hole,h:h,center:true)
|
12
|
+
res -= cylinder(d:hole,h:h,center:true).rotate(x:90)
|
13
|
+
res -= cylinder(d:hole,h:h,center:true).rotate(y:90)
|
14
|
+
|
15
|
+
res.save("example001.scad")
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
=begin
|
20
|
+
module example001()
|
21
|
+
{
|
22
|
+
function r_from_dia(d) = d / 2;
|
23
|
+
|
24
|
+
module rotcy(rot, r, h) {
|
25
|
+
rotate(90, rot)
|
26
|
+
cylinder(r = r, h = h, center = true);
|
27
|
+
}
|
28
|
+
|
29
|
+
difference() {
|
30
|
+
sphere(r = r_from_dia(size));
|
31
|
+
rotcy([0, 0, 0], cy_r, cy_h);
|
32
|
+
rotcy([1, 0, 0], cy_r, cy_h);
|
33
|
+
rotcy([0, 1, 0], cy_r, cy_h);
|
34
|
+
}
|
35
|
+
|
36
|
+
size = 50;
|
37
|
+
hole = 25;
|
38
|
+
|
39
|
+
cy_r = r_from_dia(hole);
|
40
|
+
cy_h = r_from_dia(size * 2.5);
|
41
|
+
}
|
42
|
+
|
43
|
+
example001();
|
44
|
+
=end
|
45
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
# note that center:true doesn't work with cube
|
7
|
+
# however, there are convenience methods like
|
8
|
+
# center, center_x, center_y, center_xy, center_z available.
|
9
|
+
# As rule of thumb, avoid center if possible.
|
10
|
+
|
11
|
+
res1 = cube([30,30,30]).center
|
12
|
+
res1+= cube([15,15,50]).center.translate(z:-25)
|
13
|
+
|
14
|
+
res2 = cube([50,10,10]).center
|
15
|
+
res2+= cube([10,50,10]).center
|
16
|
+
res2+= cube([10,10,50]).center
|
17
|
+
|
18
|
+
res = res1-res2
|
19
|
+
res*=cylinder(r1:20,r2:5,h:50,center:true).translate(z:5)
|
20
|
+
|
21
|
+
res.save("example002.scad")
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
=begin
|
28
|
+
module example002()
|
29
|
+
{
|
30
|
+
intersection() {
|
31
|
+
difference() {
|
32
|
+
union() {
|
33
|
+
cube([30, 30, 30], center = true);
|
34
|
+
translate([0, 0, -25])
|
35
|
+
cube([15, 15, 50], center = true);
|
36
|
+
}
|
37
|
+
union() {
|
38
|
+
cube([50, 10, 10], center = true);
|
39
|
+
cube([10, 50, 10], center = true);
|
40
|
+
cube([10, 10, 50], center = true);
|
41
|
+
}
|
42
|
+
}
|
43
|
+
translate([0, 0, 5])
|
44
|
+
cylinder(h = 50, r1 = 20, r2 = 5, center = true);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
example002();
|
49
|
+
=end
|
50
|
+
|
51
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
|
7
|
+
def example003
|
8
|
+
res1 = cube([30,30,30]).center
|
9
|
+
res2 = nil # either initialize it with a CrystalScadObject or nil as we do a += on it later on
|
10
|
+
[[1,0,0],[0,1,0],[0,0,1]].each do |x,y,z|
|
11
|
+
res1+= cube([15+x*25,15+y*25,15+z*25]).center
|
12
|
+
res2+= cube([10+x*40,10+y*40,+10+z*40]).center
|
13
|
+
end
|
14
|
+
res1-res2
|
15
|
+
end
|
16
|
+
|
17
|
+
example003.save("example003.scad")
|
18
|
+
|
19
|
+
|
20
|
+
=begin
|
21
|
+
|
22
|
+
module example003()
|
23
|
+
{
|
24
|
+
difference() {
|
25
|
+
union() {
|
26
|
+
cube([30, 30, 30], center = true);
|
27
|
+
cube([40, 15, 15], center = true);
|
28
|
+
cube([15, 40, 15], center = true);
|
29
|
+
cube([15, 15, 40], center = true);
|
30
|
+
}
|
31
|
+
union() {
|
32
|
+
cube([50, 10, 10], center = true);
|
33
|
+
cube([10, 50, 10], center = true);
|
34
|
+
cube([10, 10, 50], center = true);
|
35
|
+
}
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
39
|
+
example003();
|
40
|
+
|
41
|
+
=end
|
42
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
|
7
|
+
def example004
|
8
|
+
cube([30,30,30]).center-sphere(d:40)
|
9
|
+
end
|
10
|
+
|
11
|
+
example004.save("example004.scad")
|
12
|
+
|
13
|
+
|
14
|
+
=begin
|
15
|
+
|
16
|
+
|
17
|
+
module example004()
|
18
|
+
{
|
19
|
+
difference() {
|
20
|
+
cube(30, center = true);
|
21
|
+
sphere(20);
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
25
|
+
example004();
|
26
|
+
|
27
|
+
|
28
|
+
=end
|
29
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
|
7
|
+
# note that openscad works with radians automatically and ruby doesn't.
|
8
|
+
def radians(a)
|
9
|
+
a/180.0 * Math::PI
|
10
|
+
end
|
11
|
+
|
12
|
+
def example005
|
13
|
+
# base
|
14
|
+
res = cylinder(d:200,h:50)
|
15
|
+
res -= cylinder(d:160,h:50).translate(z:10)
|
16
|
+
res -= cube([50,50,50]).center.translate(x:100,z:35)
|
17
|
+
|
18
|
+
# pylons
|
19
|
+
(0..5).each do |i|
|
20
|
+
res+= cylinder(d:20,h:200).translate(x:Math::sin(radians(360*i/6))*80,y:Math::cos(radians(360*i/6))*80)
|
21
|
+
end
|
22
|
+
|
23
|
+
# roof
|
24
|
+
res += cylinder(d1:240,d2:0,h:80).translate(z:200)
|
25
|
+
|
26
|
+
res.translate(z:-120)
|
27
|
+
end
|
28
|
+
|
29
|
+
example005.save("example005.scad")
|
30
|
+
|
31
|
+
|
32
|
+
=begin
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
module example005()
|
37
|
+
{
|
38
|
+
translate([0, 0, -120]) {
|
39
|
+
difference() {
|
40
|
+
cylinder(h = 50, r = 100);
|
41
|
+
translate([0, 0, 10]) cylinder(h = 50, r = 80);
|
42
|
+
translate([100, 0, 35]) cube(50, center = true);
|
43
|
+
}
|
44
|
+
for (i = [0:5]) {
|
45
|
+
echo(360*i/6, sin(360*i/6)*80, cos(360*i/6)*80);
|
46
|
+
translate([sin(360*i/6)*80, cos(360*i/6)*80, 0 ])
|
47
|
+
cylinder(h = 200, r=10);
|
48
|
+
}
|
49
|
+
translate([0, 0, 200])
|
50
|
+
cylinder(h = 80, r1 = 120, r2 = 0);
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
example005();
|
55
|
+
|
56
|
+
|
57
|
+
=end
|
58
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
|
7
|
+
g1 = PrintedGear.new(module:2.0,teeth:40,bore:5,height:4)
|
8
|
+
g2 = PrintedGear.new(module:2.0,teeth:20,bore:5,height:4,rotation:0.5) # rotation in number of teeth
|
9
|
+
|
10
|
+
res = g1.show.color("red").rotate(z:"$t*360")
|
11
|
+
res += g2.show.rotate(z:"-$t*360*#{g1.ratio(g2)}").translate(x:g1.distance_to(g2))
|
12
|
+
|
13
|
+
res.save("printed_gear.scad")
|
14
|
+
|
@@ -0,0 +1,102 @@
|
|
1
|
+
#!/usr/bin/ruby1.9.3
|
2
|
+
require "rubygems"
|
3
|
+
require "crystalscad"
|
4
|
+
include CrystalScad
|
5
|
+
|
6
|
+
# This example shows the use of ScrewThreads in CrystalScad.
|
7
|
+
|
8
|
+
class CustomPartWithFemaleThread < CrystalScad::Assembly
|
9
|
+
# this could be something like a tslot-nut
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@x=8
|
13
|
+
@y=20
|
14
|
+
@z=8
|
15
|
+
end
|
16
|
+
|
17
|
+
def show
|
18
|
+
res = cube([@x,@y,@z]).color(r:180,b:180,g:180)
|
19
|
+
res -= threads_top.map(&:show) # - tries output normally, we want show here
|
20
|
+
end
|
21
|
+
|
22
|
+
def threads_top
|
23
|
+
holes =*ScrewThread.new(x:@x/2,y:@y/2+3,size:4,depth:@z)
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
class CustomPartWithMaleThread < CrystalScad::Assembly
|
30
|
+
def initialize
|
31
|
+
@x=50
|
32
|
+
@y=50
|
33
|
+
@z=15
|
34
|
+
end
|
35
|
+
|
36
|
+
def show
|
37
|
+
res = cube([@x,@y,@z]).color(r:200,b:200,g:200,a:100)
|
38
|
+
res += threads
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def threads_top
|
43
|
+
holes =*ScrewThread.new(x:@x/2+2,y:@y/2+2,z:@z,size:4,depth:@z)
|
44
|
+
end
|
45
|
+
|
46
|
+
def threads_bottom
|
47
|
+
holes =*ScrewThread.new(x:@x/2+2,y:@y/2+2,z:0,size:4,depth:@z,face:"bottom")
|
48
|
+
end
|
49
|
+
|
50
|
+
def threads_left
|
51
|
+
holes =*ScrewThread.new(x:0,y:10,z:8,size:4,depth:10,face:"left")
|
52
|
+
end
|
53
|
+
|
54
|
+
def threads_right
|
55
|
+
holes =*ScrewThread.new(x:@x,y:15,z:3,size:4,depth:10,face:"right")
|
56
|
+
end
|
57
|
+
|
58
|
+
def threads_front
|
59
|
+
holes =*ScrewThread.new(x:25,y:0,z:11,size:4,depth:10,face:"front")
|
60
|
+
end
|
61
|
+
|
62
|
+
def threads_back
|
63
|
+
holes =*ScrewThread.new(x:25,y:@y,z:11,size:4,depth:10,face:"back")
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
female=CustomPartWithFemaleThread.new
|
70
|
+
male =CustomPartWithMaleThread.new
|
71
|
+
|
72
|
+
pos = male.threads_top.first.position_on(female.threads_top.first)
|
73
|
+
|
74
|
+
res = male.show
|
75
|
+
res += female.show.translate(pos)
|
76
|
+
|
77
|
+
rotation = {}
|
78
|
+
pos = male.threads_bottom.first.position_on(female.threads_top.first,rotation)
|
79
|
+
res += female.show.rotate(rotation).mirror(z:1).translate(pos)
|
80
|
+
|
81
|
+
|
82
|
+
rotation = {y:-90}
|
83
|
+
pos = male.threads_left.first.position_on(female.threads_top.first,rotation)
|
84
|
+
res += female.show.rotate(rotation).translate(pos)
|
85
|
+
|
86
|
+
rotation = {y:90}
|
87
|
+
pos = male.threads_right.first.position_on(female.threads_top.first,rotation)
|
88
|
+
res += female.show.rotate(rotation).translate(pos)
|
89
|
+
|
90
|
+
|
91
|
+
rotation = {x:90}
|
92
|
+
pos = male.threads_front.first.position_on(female.threads_top.first,rotation)
|
93
|
+
# testing rotate_around here
|
94
|
+
res += female.show.rotate_around(female.threads_top.first,z:90).rotate(rotation).translate(pos)
|
95
|
+
|
96
|
+
|
97
|
+
rotation = {x:-90}
|
98
|
+
pos = male.threads_back.first.position_on(female.threads_top.first,rotation)
|
99
|
+
res += female.show.rotate(rotation).translate(pos)
|
100
|
+
|
101
|
+
|
102
|
+
res.save("threads2.scad")
|
data/lib/crystalscad/Assembly.rb
CHANGED
@@ -76,6 +76,24 @@ module CrystalScad
|
|
76
76
|
def scad_output()
|
77
77
|
return self.output.scad_output
|
78
78
|
end
|
79
|
+
|
80
|
+
def threads
|
81
|
+
a = []
|
82
|
+
[:threads_top,:threads_bottom,:threads_left,:threads_right,:threads_front,:threads_back].each do |m|
|
83
|
+
if self.respond_to? m
|
84
|
+
ret = self.send m
|
85
|
+
unless ret == nil
|
86
|
+
if ret.kind_of? Array
|
87
|
+
a+= ret
|
88
|
+
else
|
89
|
+
a << ret
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
return a
|
96
|
+
end
|
79
97
|
|
80
98
|
end
|
81
99
|
|
@@ -75,6 +75,11 @@ module CrystalScad
|
|
75
75
|
self
|
76
76
|
end
|
77
77
|
|
78
|
+
def rotate_around(point,args)
|
79
|
+
x,y,z= point.x, point.y, point.z
|
80
|
+
self.translate(x:-x,y:-y,z:-z).rotate(args).translate(x:x,y:y,z:z)
|
81
|
+
end
|
82
|
+
|
78
83
|
def translate(args)
|
79
84
|
@transformations << Translate.new(args)
|
80
85
|
self
|
@@ -97,13 +102,13 @@ module CrystalScad
|
|
97
102
|
|
98
103
|
class Rotate < Transformation
|
99
104
|
def to_rubyscad
|
100
|
-
return RubyScadBridge.new.rotate(@args)
|
105
|
+
return RubyScadBridge.new.rotate(@args).gsub('"','')
|
101
106
|
end
|
102
107
|
end
|
103
108
|
|
104
109
|
class Translate < Transformation
|
105
110
|
def to_rubyscad
|
106
|
-
return RubyScadBridge.new.translate(@args)
|
111
|
+
return RubyScadBridge.new.translate(@args).gsub('"','')
|
107
112
|
end
|
108
113
|
end
|
109
114
|
|
@@ -152,6 +157,10 @@ module CrystalScad
|
|
152
157
|
self
|
153
158
|
end
|
154
159
|
|
160
|
+
def center
|
161
|
+
@transformations << Translate.new({x:-@x/2,y:-@y/2,z:-@z/2})
|
162
|
+
self
|
163
|
+
end
|
155
164
|
|
156
165
|
def to_rubyscad
|
157
166
|
return RubyScadBridge.new.cube(@args)
|
@@ -169,6 +178,17 @@ module CrystalScad
|
|
169
178
|
end
|
170
179
|
Cube.new(args)
|
171
180
|
end
|
181
|
+
|
182
|
+
class Sphere < Primitive
|
183
|
+
def to_rubyscad
|
184
|
+
return RubyScadBridge.new.sphere(@args)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def sphere(args)
|
189
|
+
Sphere.new(args)
|
190
|
+
end
|
191
|
+
|
172
192
|
|
173
193
|
# 2d primitives
|
174
194
|
class Square < Primitive
|
@@ -297,7 +317,7 @@ module CrystalScad
|
|
297
317
|
args.each do |a|
|
298
318
|
if a.respond_to? :output
|
299
319
|
r = Difference.new(r,a.output)
|
300
|
-
else
|
320
|
+
else
|
301
321
|
r = Difference.new(r,a)
|
302
322
|
end
|
303
323
|
end
|
data/lib/crystalscad/Gears.rb
CHANGED
@@ -18,7 +18,6 @@ module CrystalScad::Gears
|
|
18
18
|
|
19
19
|
class Gear < CrystalScad::Assembly
|
20
20
|
# this library is to be used to easily work with gears and their distances to each other
|
21
|
-
# TODO: maybe at some point port the publicDomainGear.scad into it?
|
22
21
|
|
23
22
|
attr_reader :module, :teeth, :height, :hub_dia, :hub_height
|
24
23
|
|
@@ -60,10 +59,87 @@ module CrystalScad::Gears
|
|
60
59
|
raise "You cannot use two gears with different gear modules."
|
61
60
|
return
|
62
61
|
end
|
63
|
-
return (@module * (@teeth + other_gear.teeth))/2.0
|
62
|
+
return (@module.to_f * (@teeth.to_f + other_gear.teeth.to_f))/2.0
|
63
|
+
end
|
64
|
+
|
65
|
+
def ratio(other_gear)
|
66
|
+
@teeth.to_f / other_gear.teeth.to_f
|
64
67
|
end
|
65
68
|
|
66
69
|
end
|
70
|
+
|
71
|
+
# Acts the same as Gear, but does produce printable output
|
72
|
+
class PrintedGear < Gear
|
73
|
+
|
74
|
+
def initialize(args={})
|
75
|
+
super
|
76
|
+
@pressure_angle = args[:pressure_angle] || 20
|
77
|
+
@clearance = args[:clearance] || 0.0
|
78
|
+
@backlash = args[:backlash] || 0.0
|
79
|
+
@twist = args[:twist] || 0.0
|
80
|
+
@teeth_to_hide = args[:teeth_to_hide] || 0.0
|
81
|
+
|
82
|
+
@rotation = args[:rotation] || 0.0 # rotation in teeth
|
83
|
+
end
|
84
|
+
|
85
|
+
def show
|
86
|
+
output
|
87
|
+
end
|
88
|
+
|
89
|
+
# ported from publicDomainGearV1.1.scad
|
90
|
+
def output
|
91
|
+
p = @module * @teeth / 2.0
|
92
|
+
c = p + @module - @clearance # radius of pitch circle
|
93
|
+
b = p*Math::cos(radians(@pressure_angle)) # radius of base circle
|
94
|
+
r = p-(c-p)-@clearance # radius of root circle
|
95
|
+
t = (@module*Math::PI)/2.0-@backlash/2.0 # tooth thickness at pitch circle
|
96
|
+
k = -iang(b, p) - t/2.0/p/Math::PI*180 # angle to where involute meets base circle on each side of tooth
|
97
|
+
|
98
|
+
points=[
|
99
|
+
[0, -@hub_dia/10.0],
|
100
|
+
polar(r, -181/@teeth.to_f),
|
101
|
+
polar(r, r<b ? k : -180/@teeth.to_f),
|
102
|
+
q7(0/5,r,b,c,k, 1),q7(1/5,r,b,c,k, 1),q7(2/5,r,b,c,k, 1),q7(3/5,r,b,c,k, 1),q7(4/5,r,b,c,k, 1),q7(5/5,r,b,c,k, 1),
|
103
|
+
q7(5/5,r,b,c,k,-1),q7(4/5,r,b,c,k,-1),q7(3/5,r,b,c,k,-1),q7(2/5,r,b,c,k,-1),q7(1/5,r,b,c,k,-1),q7(0/5,r,b,c,k,-1),
|
104
|
+
polar(r, r<b ? -k : 180/@teeth.to_f),
|
105
|
+
polar(r, 181/@teeth.to_f)
|
106
|
+
]
|
107
|
+
paths=[(0..16).to_a]
|
108
|
+
|
109
|
+
res = CrystalScadObject.new
|
110
|
+
(0..@teeth-@teeth_to_hide-1).each do |i|
|
111
|
+
res+= polygon(points:points,paths:paths).linear_extrude(h:@height,convexity:10,center:false,twist:@twist).rotate(z:i*360/@teeth.to_f)
|
112
|
+
end
|
113
|
+
|
114
|
+
res-= cylinder(h:@height+0.2,d:@bore).translate(z:-0.1)
|
115
|
+
res.rotate(z:@rotation*360.0/@teeth)
|
116
|
+
end
|
117
|
+
|
118
|
+
def radians(a)
|
119
|
+
a/180.0 * Math::PI
|
120
|
+
end
|
121
|
+
|
122
|
+
def degrees(a)
|
123
|
+
a*180 / Math::PI
|
124
|
+
end
|
125
|
+
|
126
|
+
def polar(r,theta)
|
127
|
+
[r*Math::sin(radians(theta)), r*Math::cos(radians(theta))] #convert polar to cartesian coordinates
|
128
|
+
end
|
129
|
+
|
130
|
+
def iang(r1,r2)
|
131
|
+
Math::sqrt((r2/r1)*(r2/r1) - 1)/Math::PI*180 - degrees(Math::acos(r1/r2)) #//unwind a string this many degrees to go from radius r1 to radius r2
|
132
|
+
end
|
133
|
+
|
134
|
+
def q7(f,r,b,r2,t,s)
|
135
|
+
q6(b,s,t,(1-f)*[b,r].max+f*r2) #radius a fraction f up the curved side of the tooth
|
136
|
+
end
|
137
|
+
|
138
|
+
def q6(b,s,t,d)
|
139
|
+
polar(d,s*(iang(b,d)+t)) # point at radius d on the involute curve
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
67
143
|
|
68
144
|
end
|
69
145
|
|
@@ -17,7 +17,7 @@ module CrystalScad::ScrewThreads
|
|
17
17
|
class ScrewThread
|
18
18
|
# I would name this Thread but that's already taken by something else
|
19
19
|
|
20
|
-
attr_accessor :x,:y,:z,:size, :depth
|
20
|
+
attr_accessor :x,:y,:z,:size, :depth, :face
|
21
21
|
|
22
22
|
def initialize(args={})
|
23
23
|
@x = args[:x] || 0
|
@@ -25,6 +25,52 @@ module CrystalScad::ScrewThreads
|
|
25
25
|
@z = args[:z] || 0
|
26
26
|
@depth = args[:depth]
|
27
27
|
@size = args[:size]
|
28
|
+
@face = args[:face] || :top
|
29
|
+
end
|
30
|
+
|
31
|
+
def rotation
|
32
|
+
case @face.to_s
|
33
|
+
when "top"
|
34
|
+
return {}
|
35
|
+
when "bottom"
|
36
|
+
return {y:180}
|
37
|
+
when "left"
|
38
|
+
return {y:-90}
|
39
|
+
when "right"
|
40
|
+
return {y:90}
|
41
|
+
when "front" # checkme
|
42
|
+
return {x:90}
|
43
|
+
when "back"
|
44
|
+
return {x:-90}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def show
|
49
|
+
cylinder(d:@size,h:@depth).rotate(rotation).translate(x:@x,y:@y,z:@z).color(r:130,g:130,b:130)
|
50
|
+
end
|
51
|
+
|
52
|
+
def orientation_swap_to(coords,rotation)
|
53
|
+
if rotation[:x].to_i == -90
|
54
|
+
return [coords[0],coords[2],-coords[1]]
|
55
|
+
end
|
56
|
+
if rotation[:x].to_i == 90
|
57
|
+
return [coords[0],-coords[2],coords[1]]
|
58
|
+
end
|
59
|
+
if rotation[:y].to_i == -90
|
60
|
+
return [coords[2],coords[1],coords[0]]
|
61
|
+
end
|
62
|
+
if rotation[:y].to_i == 90
|
63
|
+
return [-coords[2],coords[1],-coords[0]]
|
64
|
+
end
|
65
|
+
|
66
|
+
return coords
|
67
|
+
end
|
68
|
+
|
69
|
+
def position_on(other_thread,rotation={})
|
70
|
+
oc = other_thread.x, other_thread.y, other_thread.z
|
71
|
+
oc = orientation_swap_to(oc,rotation)
|
72
|
+
|
73
|
+
return {x:@x-oc[0],y:@y-oc[1],z:@z-oc[2]}
|
28
74
|
end
|
29
75
|
|
30
76
|
end
|
@@ -39,7 +85,7 @@ module CrystalScad::ScrewThreads
|
|
39
85
|
|
40
86
|
# we need to know obj1 height (if not supplied by user)
|
41
87
|
height ||= args[:height]
|
42
|
-
case face
|
88
|
+
case face.to_s
|
43
89
|
when "top"
|
44
90
|
height ||= obj1.z rescue nil
|
45
91
|
when "bottom"
|
@@ -92,7 +138,6 @@ module CrystalScad::ScrewThreads
|
|
92
138
|
ret = []
|
93
139
|
holes.each_with_index do |hole,i|
|
94
140
|
bolt = Bolt.new(hole.size,bolt_heights[i])
|
95
|
-
puts bolt_heights[i]
|
96
141
|
case face
|
97
142
|
when "top"
|
98
143
|
bolt.transformations << Rotate.new(x:180)
|
@@ -117,6 +162,6 @@ module CrystalScad::ScrewThreads
|
|
117
162
|
end
|
118
163
|
|
119
164
|
ret
|
120
|
-
end
|
165
|
+
end
|
121
166
|
|
122
167
|
end
|
data/lib/crystalscad/version.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: 3
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 8
|
10
|
+
version: 0.3.8
|
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:
|
18
|
+
date: 2014-01-05 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rubyscad
|
@@ -63,8 +63,15 @@ files:
|
|
63
63
|
- Rakefile
|
64
64
|
- crystalscad.gemspec
|
65
65
|
- examples/gear.rb
|
66
|
+
- examples/openscad_examples/example001.rb
|
67
|
+
- examples/openscad_examples/example002.rb
|
68
|
+
- examples/openscad_examples/example003.rb
|
69
|
+
- examples/openscad_examples/example004.rb
|
70
|
+
- examples/openscad_examples/example005.rb
|
71
|
+
- examples/printed_gear.rb
|
66
72
|
- examples/stack.rb
|
67
73
|
- examples/threads.rb
|
74
|
+
- examples/threads2.rb
|
68
75
|
- lib/crystalscad.rb
|
69
76
|
- lib/crystalscad/Assembly.rb
|
70
77
|
- lib/crystalscad/BillOfMaterial.rb
|