solidruby 0.1.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.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.travis.yml +3 -0
  4. data/COPYING +674 -0
  5. data/Gemfile +2 -0
  6. data/Guardfile +24 -0
  7. data/LICENSE.md +675 -0
  8. data/README.md +180 -0
  9. data/Rakefile +10 -0
  10. data/bin/solidruby +61 -0
  11. data/examples/chamfered_cube.rb +39 -0
  12. data/examples/filleted_cube.rb +39 -0
  13. data/examples/gear.rb +11 -0
  14. data/examples/knurls.rb +12 -0
  15. data/examples/nut_support.rb +17 -0
  16. data/examples/openscad_examples/old/example001.rb +42 -0
  17. data/examples/openscad_examples/old/example002.rb +45 -0
  18. data/examples/openscad_examples/old/example003.rb +37 -0
  19. data/examples/openscad_examples/old/example004.rb +22 -0
  20. data/examples/openscad_examples/old/example005.rb +45 -0
  21. data/examples/openscad_examples/old/example006.rb +85 -0
  22. data/examples/openscad_examples/old/example007.dxf +2410 -0
  23. data/examples/openscad_examples/old/example007.rb +107 -0
  24. data/examples/openscad_examples/old/example008.rb +61 -0
  25. data/examples/openscad_examples/old/example009.dxf +3894 -0
  26. data/examples/openscad_examples/old/example009.rb.old +48 -0
  27. data/examples/openscad_examples/old/example010.dat +51 -0
  28. data/examples/openscad_examples/old/example010.rb +23 -0
  29. data/examples/openscad_examples/old/example011.rb +42 -0
  30. data/examples/openscad_examples/old/example012.rb +22 -0
  31. data/examples/openscad_examples/old/example012.stl +450 -0
  32. data/examples/openscad_examples/old/example013.dxf +2276 -0
  33. data/examples/openscad_examples/old/example013.rb +30 -0
  34. data/examples/openscad_examples/old/example014.rb +30 -0
  35. data/examples/openscad_examples/old/example015.rb +46 -0
  36. data/examples/openscad_examples/old/example016.rb +75 -0
  37. data/examples/openscad_examples/old/example016.stl +0 -0
  38. data/examples/pipe.rb +38 -0
  39. data/examples/pipe_bug.rb +16 -0
  40. data/examples/printed_gear.rb +12 -0
  41. data/examples/printed_gear2.rb +16 -0
  42. data/examples/printed_thread.rb +9 -0
  43. data/examples/printed_thread2.rb +13 -0
  44. data/examples/stack.rb +21 -0
  45. data/examples/threads.rb +183 -0
  46. data/examples/threads2.rb +93 -0
  47. data/examples/threads3.rb +46 -0
  48. data/lib/solidruby.rb +60 -0
  49. data/lib/solidruby/assemblies/assembly.rb +176 -0
  50. data/lib/solidruby/assemblies/bolt.rb +158 -0
  51. data/lib/solidruby/assemblies/gear.rb +131 -0
  52. data/lib/solidruby/assemblies/linear_bearing.rb +84 -0
  53. data/lib/solidruby/assemblies/nut.rb +153 -0
  54. data/lib/solidruby/assemblies/pipe.rb +153 -0
  55. data/lib/solidruby/assemblies/ruler.rb +44 -0
  56. data/lib/solidruby/assemblies/tslot.rb +141 -0
  57. data/lib/solidruby/assemblies/tslot_machining.rb +62 -0
  58. data/lib/solidruby/assemblies/washer.rb +57 -0
  59. data/lib/solidruby/bill_of_material.rb +43 -0
  60. data/lib/solidruby/csg_modelling/csg_modelling.rb +43 -0
  61. data/lib/solidruby/csg_modelling/difference.rb +41 -0
  62. data/lib/solidruby/csg_modelling/hull.rb +23 -0
  63. data/lib/solidruby/csg_modelling/intersection.rb +24 -0
  64. data/lib/solidruby/csg_modelling/minkowski.rb +23 -0
  65. data/lib/solidruby/csg_modelling/union.rb +41 -0
  66. data/lib/solidruby/csg_modifiers/color.rb +41 -0
  67. data/lib/solidruby/csg_modifiers/csg_modifier.rb +50 -0
  68. data/lib/solidruby/csg_modifiers/linear_extrude.rb +34 -0
  69. data/lib/solidruby/csg_modifiers/projection.rb +29 -0
  70. data/lib/solidruby/csg_modifiers/rotate_extrude.rb +30 -0
  71. data/lib/solidruby/extra.rb +58 -0
  72. data/lib/solidruby/helpers/chamfer.rb +27 -0
  73. data/lib/solidruby/helpers/fillet.rb +28 -0
  74. data/lib/solidruby/helpers/position.rb +267 -0
  75. data/lib/solidruby/helpers/rounded_cube.rb +37 -0
  76. data/lib/solidruby/helpers/triangle.rb +167 -0
  77. data/lib/solidruby/primitives/circle.rb +26 -0
  78. data/lib/solidruby/primitives/cube.rb +123 -0
  79. data/lib/solidruby/primitives/cylinder.rb +72 -0
  80. data/lib/solidruby/primitives/import.rb +42 -0
  81. data/lib/solidruby/primitives/polygon.rb +26 -0
  82. data/lib/solidruby/primitives/polyhedron.rb +30 -0
  83. data/lib/solidruby/primitives/primitive.rb +19 -0
  84. data/lib/solidruby/primitives/render.rb +48 -0
  85. data/lib/solidruby/primitives/sphere.rb +49 -0
  86. data/lib/solidruby/primitives/square.rb +88 -0
  87. data/lib/solidruby/primitives/surface.rb +44 -0
  88. data/lib/solidruby/primitives/text.rb +43 -0
  89. data/lib/solidruby/printed_thread.rb +163 -0
  90. data/lib/solidruby/rubyscad_bridge.rb +376 -0
  91. data/lib/solidruby/screw_thread.rb +170 -0
  92. data/lib/solidruby/solidruby.rb +150 -0
  93. data/lib/solidruby/solidruby_object.rb +176 -0
  94. data/lib/solidruby/transformations/mirror.rb +22 -0
  95. data/lib/solidruby/transformations/rotate.rb +22 -0
  96. data/lib/solidruby/transformations/scale.rb +22 -0
  97. data/lib/solidruby/transformations/transformation.rb +29 -0
  98. data/lib/solidruby/transformations/translate.rb +32 -0
  99. data/lib/solidruby/version.rb +18 -0
  100. data/lib/templates/assembly.tt +13 -0
  101. data/lib/templates/gitignore.tt +3 -0
  102. data/lib/templates/guardfile.tt +4 -0
  103. data/lib/templates/main.tt +20 -0
  104. data/lib/templates/params.tt +3 -0
  105. data/lib/templates/printed.tt +9 -0
  106. data/manual/manual.html +417 -0
  107. data/solidruby.gemspec +35 -0
  108. metadata +277 -0
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solidruby'
4
+ include SolidRuby
5
+
6
+ r = import(f: 'example013.dxf')
7
+ .linear_extrude(h: 100, center: true, co: 3)
8
+
9
+ r *= import(f: 'example013.dxf')
10
+ .linear_extrude(h: 100, ce: true, co: 3)
11
+ .rotate(y: 90)
12
+
13
+ r *= import(f: 'example013.dxf')
14
+ .linear_extrude(h: 100, ce: true, co: 3)
15
+ .rotate(x: 90)
16
+
17
+ r.save('example013.scad')
18
+
19
+ # echo(version=version());
20
+ #
21
+ # intersection() {
22
+ # linear_extrude(height = 100, center = true, convexity= 3)
23
+ # import(file = "example013.dxf");
24
+ # rotate([0, 90, 0])
25
+ # linear_extrude(height = 100, center = true, convexity= 3)
26
+ # import(file = "example013.dxf");
27
+ # rotate([90, 0, 0])
28
+ # linear_extrude(height = 100, center = true, convexity= 3)
29
+ # import(file = "example013.dxf");
30
+ # }
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solidruby'
4
+ include SolidRuby
5
+
6
+ r = [
7
+ {x: 0, y: 0, z: 0},
8
+ {x: 10, y: 20, z: 300},
9
+ {x: 200, y: 40, z: 57},
10
+ {x: 20, y: 88, z: 57},
11
+ ]
12
+
13
+ res = nil #cube(x: 100, y: 20, z: 20, c: true)
14
+
15
+ r.each do |v|
16
+ res *= cube(x: 100, y: 20, z: 20, c: true)
17
+ .rotate(v)
18
+ end
19
+
20
+ res.save('example014.scad')
21
+
22
+ # echo(version=version());
23
+ #
24
+ # intersection_for(i = [
25
+ # [0, 0, 0],
26
+ # [10, 20, 300],
27
+ # [200, 40, 57],
28
+ # [20, 88, 57]
29
+ # ])
30
+ # rotate(i) cube([100, 20, 20], center = true);
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solidruby'
4
+ include SolidRuby
5
+
6
+ def shape
7
+ (((square(s: 100, c: true) -
8
+ square(s: 50, c: true)) +
9
+ square(s: 15, c: true)
10
+ .translate(x: 50, y: 50)) *
11
+ square(x: 100, y: 30)
12
+ .translate(y: -15)
13
+ .rotate(z: 45)
14
+ ).translate(x: -35, y: -35) -
15
+ circle(r: 5)
16
+ .scale(x: 0.7, y: 1.3)
17
+ .rotate(z: -45) &
18
+ import(f: 'example009.dxf', l: 'body', co: 6, s: 2)
19
+ end
20
+
21
+ shape.save('example015.scad')
22
+
23
+ # module shape()
24
+ # {
25
+ # difference() {
26
+ # translate([ -35, -35 ]) intersection() {
27
+ # union() {
28
+ # difference() {
29
+ # square(100, true);
30
+ # square(50, true);
31
+ # }
32
+ # translate([ 50, 50 ]) square(15, true);
33
+ # }
34
+ # rotate(45) translate([ 0, -15 ]) square([ 100, 30 ]);
35
+ # }
36
+ #
37
+ # rotate(-45) scale([ 0.7, 1.3 ]) circle(5);
38
+ # }
39
+ #
40
+ # import(file = "example009.dxf", layer = "body", convexity = 6, scale=2);
41
+ # }
42
+ #
43
+ # echo(version=version());
44
+ #
45
+ # // linear_extrude(convexity = 10, center = true)
46
+ # shape();
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solidruby'
4
+ include SolidRuby
5
+
6
+ def blk1
7
+ cube(65, 28, 28).center
8
+ end
9
+
10
+ def blk2
11
+ cube(60, 28, 14).center
12
+ .translate(z: 7.5) -
13
+ cube(8, 32, 32).center
14
+ end
15
+
16
+ def chop
17
+ import(f: 'example016.stl', co: 12)
18
+ .translate(x: -18)
19
+ end
20
+
21
+ r = blk1
22
+ [0, 90, 180, 270].each do |a|
23
+ r -= (blk2 - chop)
24
+ .render(co: 12)
25
+ .rotate(x: a)
26
+ end
27
+
28
+
29
+
30
+
31
+ # difference() {
32
+ # blk1();
33
+ # for (alpha = [0, 90, 180, 270]) {
34
+ # rotate(alpha, [ 1, 0, 0])
35
+ # render(convexity = 12)
36
+ # difference() {
37
+ # blk2();
38
+ # chop();
39
+ # }
40
+ # }
41
+
42
+ r.save('example016.scad')
43
+
44
+ # // chopped_blocks.stl is derived from Basics/LetterBlock.scad
45
+ # // The exported STL was converted to binary using MeshLab
46
+ #
47
+ # module blk1() {
48
+ # cube([ 65, 28, 28 ], center = true);
49
+ # }
50
+ #
51
+ # module blk2() {
52
+ # difference() {
53
+ # translate([ 0, 0, 7.5 ]) cube([ 60, 28, 14 ], center = true);
54
+ # cube([ 8, 32, 32 ], center = true);
55
+ # }
56
+ # }
57
+ #
58
+ # module chop() {
59
+ # translate([ -18, 0, 0 ])
60
+ # import(file = "example016.stl", convexity = 12);
61
+ # }
62
+ #
63
+ # echo(version=version());
64
+ #
65
+ # difference() {
66
+ # blk1();
67
+ # for (alpha = [0, 90, 180, 270]) {
68
+ # rotate(alpha, [ 1, 0, 0])
69
+ # render(convexity = 12)
70
+ # difference() {
71
+ # blk2();
72
+ # chop();
73
+ # }
74
+ # }
75
+ # }
data/examples/pipe.rb ADDED
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solidruby'
4
+ include SolidRuby
5
+
6
+ class MyPipe < SolidRuby::Pipe
7
+ def shape
8
+ @line_rotation = 30
9
+ circle(d: @diameter, fn: 6)
10
+ end
11
+
12
+ def inner_shape
13
+ circle(d: 6)
14
+ end
15
+ end
16
+
17
+ pipe = MyPipe.new(diameter: 10)
18
+
19
+ pipe.line(10)
20
+ pipe.ccw(20, 30, 'yellow')
21
+ pipe.line(30)
22
+
23
+ pipe.cw(30, 60, 'blue')
24
+ pipe.ccw(30, 45, 'green')
25
+ pipe.line(3)
26
+ pipe.ccw(30, 160, 'blue')
27
+ pipe.ccw(30, 60, 'pink')
28
+
29
+ # pipe.cw(30,60,"blue")
30
+ # pipe.cw(20,60,"green")
31
+ # pipe.cw(10,60,"black")
32
+ # pipe.line(33)
33
+ # pipe.cw(30,90,"white")
34
+ # pipe.cw(15,95,"silver")
35
+ # pipe.line(10,"pink")
36
+ res = pipe.pipe
37
+
38
+ res.save('pipe.scad', '$fn=64;')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ require 'solidruby'
3
+ include SolidRuby
4
+
5
+ # Used to debug
6
+ # https://github.com/jglauche/CrystalScad/issues/5
7
+
8
+ pipe = Pipe.new(diameter: 10)
9
+
10
+ pipe.line(5, 'red')
11
+ pipe.cw(20, 8, 'yellow')
12
+ pipe.line(20, 'blue')
13
+
14
+ res = pipe.pipe
15
+
16
+ res.save('pipe_bug.scad', '$fn=64;')
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solidruby'
4
+ include SolidRuby
5
+
6
+ g1 = PrintedGear.new(module: 2.0, teeth: 40, bore: 5, height: 4)
7
+ g2 = PrintedGear.new(module: 2.0, teeth: 20, bore: 5, height: 4, rotation: 0.5) # rotation in number of teeth
8
+
9
+ res = g1.show.color('red').rotate(z: '$t*360')
10
+ res += g2.show.rotate(z: "-$t*360*#{g1.ratio(g2)}").translate(x: g1.distance_to(g2))
11
+
12
+ res.save('printed_gear.scad')
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solidruby'
4
+ include SolidRuby
5
+
6
+ g1 = PrintedGear.new(module: 2.0, teeth: 40, bore: 8.5, height: 6)
7
+ res = g1.show.color('red')
8
+
9
+ res += cylinder(d: 20, h: nut_support_height = 20)
10
+
11
+ n = Nut.new(8)
12
+ res -= n.output.translate(z: nut_support_height - n.height + 0.1)
13
+
14
+ res -= cylinder(d: 8.5, h: nut_support_height)
15
+
16
+ res.save('printed_gear2.scad')
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solidruby'
4
+ include SolidRuby
5
+
6
+ t1 = PrintedThread.new
7
+ res = t1.show
8
+
9
+ res.save('printed_thread.scad')
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solidruby'
4
+ include SolidRuby
5
+
6
+ t1 = PrintedThread.new(diameter: 20, pitch: 2.5, length: 22.5, internal: true)
7
+ t2 = PrintedThread.new(diameter: 20, pitch: 2.5, length: 20, internal: false)
8
+
9
+ res = cube([25, 25, z = 26]).center_xy
10
+ res -= t1.output
11
+ res += t2.output.translate(z: z)
12
+
13
+ res.save('printed_thread2.scad')
data/examples/stack.rb ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solidruby'
4
+ include SolidRuby
5
+
6
+ # Note that this example does not work as intended and the function is deprecated
7
+
8
+ parts = [
9
+ Washer.new(4.3),
10
+ Nut.new(4),
11
+ Washer.new(4.3),
12
+ Nut.new(4)
13
+ ]
14
+ bolt = Bolt.new(4, 16).show
15
+ bolt_assembly = bolt
16
+ bolt_assembly += stack({ method: 'output', spacing: 0.1 }, *parts)
17
+
18
+ x, y, z = position(bolt)
19
+ bolt_assembly.translate(x: x * -1, y: y * -1, z: z * -1)
20
+
21
+ bolt_assembly.save('stack.scad')
@@ -0,0 +1,183 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solidruby'
4
+ include SolidRuby
5
+
6
+ # This example shows the use of ScrewThreads in SolidRuby.
7
+
8
+ class BlackBox < SolidRuby::Assembly
9
+ # This is a box (the part that you want to make a mount for)
10
+
11
+ def initialize
12
+ @x = 200
13
+ @y = 100
14
+ @z = 50
15
+ end
16
+
17
+ # note: when you design a box like that, make sure that it starts at 0,0,0
18
+ def show
19
+ cube([@x, @y, @z]).color(r: 10, b: 10, g: 10, a: 150)
20
+ end
21
+
22
+ # We're defining threads on every side. It must be called thread_side
23
+ # where side is either top, bottom, left, right, front, back
24
+ def threads_top
25
+ holes = *ScrewThread.new(x: 50, y: 50, size: 8, depth: 10) # note that =* creates an Array
26
+ holes << ScrewThread.new(x: 150, y: 50, size: 8, depth: 10) # and << adds stuff to an Array
27
+ end
28
+
29
+ def threads_bottom
30
+ [ScrewThread.new(x: 50, y: 50, size: 8, depth: 10)]
31
+ end
32
+
33
+ # note that the coordinates for the threads are needed in 2 directions from 0,0,0
34
+ # on top and bottom you're defining x & y
35
+ # on left and right you're defining y & z
36
+ # on front and back you're defining x & z
37
+ def threads_left
38
+ holes = *ScrewThread.new(y: 15, z: 10, size: 3, depth: 5)
39
+ holes << ScrewThread.new(y: 40, z: 30, size: 3, depth: 5)
40
+ end
41
+
42
+ def threads_right
43
+ holes = *ScrewThread.new(y: 15, z: 10, size: 3, depth: 5)
44
+ holes << ScrewThread.new(y: 40, z: 30, size: 3, depth: 5)
45
+ end
46
+
47
+ # this example has different thread sizes for m3 and m6
48
+ def threads_front
49
+ holes = *ScrewThread.new(x: 20, z: 10, size: 3, depth: 5)
50
+ holes << ScrewThread.new(x: 100, z: 20, size: 6, depth: 25)
51
+ holes << ScrewThread.new(x: 140, z: 20, size: 6, depth: 25)
52
+ holes << ScrewThread.new(x: 180, z: 45, size: 3, depth: 5)
53
+ end
54
+
55
+ def threads_back
56
+ holes = *ScrewThread.new(x: 20, z: 10, size: 3, depth: 5)
57
+ holes << ScrewThread.new(x: 100, z: 25, size: 12, depth: 25)
58
+ holes << ScrewThread.new(x: 180, z: 45, size: 3, depth: 5)
59
+ end
60
+ end
61
+
62
+ # this is what a basic mount looks like.
63
+ class BlackBoxMountTop < SolidRuby::Printed
64
+ def part(show)
65
+ box = BlackBox.new
66
+ mount = cube(x: 200, y: 100, z: 7)
67
+ # the mount should either be a cube or an object that returns x,y,z as dimensions
68
+ # if you have a complicated part, split the cube and add it later on to your object
69
+ # Alternatively, define height in the arguments.
70
+
71
+ # create_bolts needs the face as first argument, your new mount as second argument
72
+ # and the object that has the threads as third argument
73
+ # it accepts an hash of arguments as 4th argument. You can define
74
+ # height: define a custom height of your mount
75
+ # bolt_height: custom height for your bolt(s). Can also be an array for different lengths.
76
+ # This is useful if the automatic length calculation doesn't produce values
77
+ # that are available.
78
+ # This example would, without the setting 16 produce a M8x17 bolt. We don't have
79
+ # that size, so we use M8x16 instead.
80
+
81
+ bolts = create_bolts('top', mount, box, bolt_height: 16)
82
+ mount -= bolts
83
+ mount += bolts if show
84
+
85
+ res = mount.translate(z: box.z)
86
+ res += box.show if show
87
+ res
88
+ end
89
+ end
90
+
91
+ class BlackBoxMountBottom < SolidRuby::Printed
92
+ def part(show)
93
+ box = BlackBox.new
94
+ mount = cube(x: 200, y: 100, z: z = 2)
95
+ # note that the bolt height bom output is unchecked in this and the following examples
96
+ bolts = create_bolts('bottom', mount, box)
97
+ mount -= bolts
98
+ mount += bolts if show
99
+
100
+ res = mount.translate(z: -z)
101
+ res += box.show if show
102
+ res
103
+ end
104
+ end
105
+
106
+ class BlackBoxMountLeft < SolidRuby::Printed
107
+ def part(show)
108
+ box = BlackBox.new
109
+ mount = cube(x: x = 5, y: 100, z: 50)
110
+
111
+ bolts = create_bolts('left', mount, box)
112
+ mount -= bolts
113
+ mount += bolts if show
114
+
115
+ res = mount.translate(x: -x)
116
+ res += box.show if show
117
+ res
118
+ end
119
+ end
120
+
121
+ class BlackBoxMountRight < SolidRuby::Printed
122
+ def part(show)
123
+ box = BlackBox.new
124
+ mount = cube(x: 5, y: 100, z: 50)
125
+
126
+ bolts = create_bolts('right', mount, box)
127
+ mount -= bolts
128
+ mount += bolts if show
129
+
130
+ res = mount.translate(x: box.x)
131
+ res += box.show if show
132
+ res
133
+ end
134
+ end
135
+
136
+ class BlackBoxMountFront < SolidRuby::Printed
137
+ def part(show)
138
+ box = BlackBox.new
139
+ mount = cube(x: box.x, y: y = 15, z: box.z)
140
+
141
+ bolts = create_bolts('front', mount, box)
142
+ mount -= bolts
143
+ mount += bolts if show
144
+
145
+ res = mount.translate(y: -y)
146
+ res += box.show if show
147
+ res
148
+ end
149
+ end
150
+
151
+ class BlackBoxMountBack < SolidRuby::Printed
152
+ def part(show)
153
+ box = BlackBox.new
154
+ mount = cube(x: box.x, y: 35, z: box.z)
155
+
156
+ bolts = create_bolts('back', mount, box)
157
+ mount -= bolts
158
+ mount += bolts if show
159
+
160
+ res = mount.translate(y: box.y)
161
+ res += box.show if show
162
+ res
163
+ end
164
+ end
165
+
166
+ b = SolidRubyObject.new
167
+
168
+ # uncomment as many mounts as you like here
169
+
170
+ b += BlackBoxMountTop.new.show
171
+ b +=BlackBoxMountBottom.new.show
172
+ b +=BlackBoxMountLeft.new.show
173
+ b +=BlackBoxMountRight.new.show
174
+ b +=BlackBoxMountFront.new.show
175
+ b +=BlackBoxMountBack.new.show
176
+
177
+ # you can also try output instead of show
178
+ # b =BlackBoxMountTop.new.output
179
+
180
+ # Uncomment this for checking the BOM output
181
+ # puts BillOfMaterial.bom.output
182
+
183
+ b.save('threads.scad')