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,93 @@
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 CustomPartWithFemaleThread < SolidRuby::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.show # - tries output normally, we want show here
20
+ end
21
+
22
+ def threads_top
23
+ ScrewThread.new(x: @x / 2, y: @y / 2 + 3, size: 4, depth: @z)
24
+ end
25
+ end
26
+
27
+ class CustomPartWithMaleThread < SolidRuby::Assembly
28
+ def initialize
29
+ @x = 50
30
+ @y = 50
31
+ @z = 15
32
+ end
33
+
34
+ def show
35
+ res = cube([@x, @y, @z]).color(r: 200, b: 200, g: 200, a: 100)
36
+ res += threads
37
+ end
38
+
39
+ def threads_top
40
+ ScrewThread.new(x: @x / 2 + 2, y: @y / 2 + 2, z: @z, size: 4, depth: @z)
41
+ end
42
+
43
+ def threads_bottom
44
+ ScrewThread.new(x: @x / 2 + 2, y: @y / 2 + 2, z: 0, size: 4, depth: @z, face: 'bottom')
45
+ end
46
+
47
+ def threads_left
48
+ ScrewThread.new(x: 0, y: 10, z: 8, size: 4, depth: 10, face: 'left')
49
+ end
50
+
51
+ def threads_right
52
+ ScrewThread.new(x: @x, y: 15, z: 3, size: 4, depth: 10, face: 'right')
53
+ end
54
+
55
+ def threads_front
56
+ ScrewThread.new(x: 25, y: 0, z: 11, size: 4, depth: 10, face: 'front')
57
+ end
58
+
59
+ def threads_back
60
+ ScrewThread.new(x: 25, y: @y, z: 11, size: 4, depth: 10, face: 'back')
61
+ end
62
+ end
63
+
64
+ female = CustomPartWithFemaleThread.new
65
+ male = CustomPartWithMaleThread.new
66
+
67
+ pos = male.threads_top.position_on(female.threads_top)
68
+
69
+ res = male.show
70
+ res += female.show.translate(pos)
71
+
72
+ rotation = {}
73
+ pos = male.threads_bottom.position_on(female.threads_top, rotation)
74
+ res += female.show.rotate(rotation).mirror(z: 1).translate(pos)
75
+
76
+ rotation = { y: -90 }
77
+ pos = male.threads_left.position_on(female.threads_top, rotation)
78
+ res += female.show.rotate(rotation).translate(pos)
79
+
80
+ rotation = { y: 90 }
81
+ pos = male.threads_right.position_on(female.threads_top, rotation)
82
+ res += female.show.rotate(rotation).translate(pos)
83
+
84
+ rotation = { x: 90 }
85
+ pos = male.threads_front.position_on(female.threads_top, rotation)
86
+ # testing rotate_around here
87
+ res += female.show.rotate_around(female.threads_top, z: 90).rotate(rotation).translate(pos)
88
+
89
+ rotation = { x: -90 }
90
+ pos = male.threads_back.position_on(female.threads_top, rotation)
91
+ res += female.show.rotate(rotation).translate(pos)
92
+
93
+ res.save('threads2.scad')
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solidruby'
4
+ include SolidRuby
5
+
6
+ class NutPart < SolidRuby::Assembly
7
+ def initialize
8
+ @hardware = []
9
+ @height = 10
10
+ super
11
+ end
12
+
13
+ def part(_show)
14
+ res = cube([50, 50, @height]).center_xy
15
+
16
+ @hardware << Nut.new(4, direction: '-z')
17
+ @hardware << Nut.new(4, direction: 'z').translate(x: 10, z: @height - 3)
18
+ @hardware << Nut.new(4, slot: 15, slot_direction: '-x', direction: 'x').rotate(y: 90).translate(x: -20, y: 5, z: @height - 5)
19
+ @hardware << Nut.new(4, slot: 15, slot_direction: 'x', direction: 'x').rotate(y: -90).translate(x: 20, y: -8, z: @height - 5)
20
+
21
+ @hardware << Nut.new(4, slot: 15, slot_direction: '-y', direction: 'y').rotate(x: -90).translate(x: 2, y: -20, z: @height - 5)
22
+ @hardware << Nut.new(4, slot: 15, slot_direction: 'y', direction: 'y').rotate(x: 90).translate(x: -10, y: 20, z: @height - 5)
23
+
24
+ res -= @hardware
25
+ end
26
+ end
27
+
28
+ class ScrewOnPart < SolidRuby::Assembly
29
+ def initialize
30
+ @nutpart = NutPart.new
31
+ super
32
+ end
33
+
34
+ def part(_show)
35
+ res = @nutpart.show
36
+
37
+ @nutpart.hardware.each do |hw|
38
+ res += hw.bolt(20)
39
+ end
40
+ res
41
+ end
42
+ end
43
+
44
+ res = ScrewOnPart.new.show
45
+
46
+ res.save('threads3.scad')
data/lib/solidruby.rb ADDED
@@ -0,0 +1,60 @@
1
+ require 'solidruby/version'
2
+ require 'solidruby/bill_of_material'
3
+ require 'solidruby/solidruby_object'
4
+ require 'solidruby/rubyscad_bridge'
5
+
6
+ require 'solidruby/primitives/primitive'
7
+ require 'solidruby/primitives/cylinder'
8
+ require 'solidruby/primitives/cube'
9
+ require 'solidruby/primitives/sphere'
10
+ require 'solidruby/primitives/cylinder'
11
+ require 'solidruby/primitives/circle'
12
+ require 'solidruby/primitives/polygon'
13
+ require 'solidruby/primitives/square'
14
+ require 'solidruby/primitives/render'
15
+ require 'solidruby/primitives/import'
16
+ require 'solidruby/primitives/surface'
17
+ require 'solidruby/primitives/text'
18
+
19
+ require 'solidruby/helpers/chamfer'
20
+ require 'solidruby/helpers/fillet'
21
+ require 'solidruby/helpers/position'
22
+ require 'solidruby/helpers/rounded_cube'
23
+ require 'solidruby/helpers/triangle'
24
+
25
+ require 'solidruby/primitives/polyhedron' # not tested
26
+
27
+ require 'solidruby/csg_modifiers/csg_modifier'
28
+ require 'solidruby/csg_modifiers/color'
29
+ require 'solidruby/csg_modifiers/linear_extrude'
30
+ require 'solidruby/csg_modifiers/rotate_extrude'
31
+ require 'solidruby/csg_modifiers/projection'
32
+
33
+ require 'solidruby/csg_modelling/csg_modelling'
34
+ require 'solidruby/csg_modelling/difference'
35
+ require 'solidruby/csg_modelling/hull'
36
+ require 'solidruby/csg_modelling/intersection'
37
+ require 'solidruby/csg_modelling/minkowski'
38
+ require 'solidruby/csg_modelling/union'
39
+
40
+ require 'solidruby/assemblies/assembly'
41
+ require 'solidruby/assemblies/linear_bearing'
42
+ require 'solidruby/assemblies/gear'
43
+ require 'solidruby/assemblies/pipe'
44
+ require 'solidruby/assemblies/ruler'
45
+
46
+ require 'solidruby/assemblies/bolt'
47
+ require 'solidruby/assemblies/nut'
48
+ require 'solidruby/assemblies/washer'
49
+
50
+ require 'solidruby/transformations/transformation'
51
+ require 'solidruby/transformations/translate'
52
+ require 'solidruby/transformations/rotate'
53
+ require 'solidruby/transformations/mirror'
54
+ require 'solidruby/transformations/scale'
55
+
56
+ require 'solidruby/screw_thread'
57
+ require 'solidruby/printed_thread'
58
+ require 'solidruby/extra'
59
+
60
+ require 'solidruby/solidruby'
@@ -0,0 +1,176 @@
1
+ # This file is part of SolidRuby.
2
+ #
3
+ # SolidRuby 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
+ # SolidRuby 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 SolidRuby. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ module SolidRuby::Assemblies
17
+ class Assembly < SolidRuby::SolidRubyObject
18
+ attr_accessor :x, :y, :z, :skip, :hardware, :transformations
19
+
20
+ def transform(obj)
21
+ obj = obj.debug if debug?
22
+ @transformations ||= nil
23
+ return obj if @transformations.nil?
24
+ @transformations.each do |t|
25
+ obj.transformations << t
26
+ end
27
+
28
+ obj
29
+ end
30
+
31
+ def initialize(args = {})
32
+ super(args)
33
+ @args ||= args
34
+
35
+ @x = args[:x]
36
+ @y = args[:y]
37
+ @z = args[:z]
38
+
39
+ add_to_bom
40
+ end
41
+
42
+ def add_to_bom
43
+ @bom_added ||= false
44
+
45
+ unless @bom_added
46
+ BillOfMaterial.bom.add(description) unless @args[:no_bom] == true
47
+ @bom_added = true
48
+ end
49
+ end
50
+
51
+ def description
52
+ "No description set for Class #{self.class}"
53
+ end
54
+
55
+ def show
56
+ transform(part(true))
57
+ end
58
+
59
+ def output
60
+ transform(part(false))
61
+ end
62
+
63
+ def part(_show = false)
64
+ #SolidRubyObject.new
65
+ end
66
+
67
+ def walk_tree
68
+ res = debug? ? '#' : ''
69
+ res + output.walk_tree
70
+ end
71
+
72
+ def +(args)
73
+ output + args
74
+ end
75
+
76
+ def -(args)
77
+ output - args
78
+ end
79
+
80
+ def *(args)
81
+ output * args
82
+ end
83
+
84
+ def scad_output
85
+ res = debug? ? '#' : ''
86
+ res + output.scad_output
87
+ end
88
+
89
+ def threads
90
+ a = []
91
+ [:threads_top, :threads_bottom, :threads_left, :threads_right, :threads_front, :threads_back].each do |m|
92
+ next unless respond_to? m
93
+ ret = send m
94
+ unless ret.nil?
95
+ if ret.is_a? Array
96
+ a += ret
97
+ else
98
+ a << ret
99
+ end
100
+ end
101
+ end
102
+
103
+ a
104
+ end
105
+
106
+ # Makes the save_all method in SolidRuby skip the specified method(s)
107
+ def self.skip(args)
108
+ @skip = [] if @skip.nil?
109
+ if args.is_a? Array
110
+ args.each do |arg|
111
+ skip(arg)
112
+ end
113
+ return
114
+ end
115
+
116
+ @skip << args.to_s
117
+ nil
118
+ end
119
+
120
+ def self.get_skip
121
+ @skip
122
+ end
123
+
124
+ def self.view(args)
125
+ @added_views = [] if @added_views.nil?
126
+ if args.is_a? Array
127
+ args.each do |arg|
128
+ view(arg)
129
+ end
130
+ return
131
+ end
132
+
133
+ @added_views << args.to_s
134
+ nil
135
+ end
136
+
137
+ def self.get_views
138
+ @added_views || []
139
+ end
140
+
141
+ def color(args = {})
142
+ @color = args
143
+ self
144
+ end
145
+
146
+ def colorize(res)
147
+ return res if @color.nil?
148
+ res.color(@color)
149
+ end
150
+
151
+ def show_hardware
152
+ return nil if @hardware.nil? || (@hardware == [])
153
+ res = nil
154
+ @hardware.each do |part|
155
+ res += part.show
156
+ end
157
+ transform(res)
158
+ end
159
+ end
160
+
161
+ class Printed < Assembly
162
+ def description
163
+ "Printed part #{self.class}"
164
+ end
165
+ end
166
+
167
+ class LasercutSheet < Assembly
168
+ def description
169
+ "Laser cut sheet #{self.class}"
170
+ end
171
+
172
+ def part(_show)
173
+ square([@x, @y])
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,158 @@
1
+ # This file is part of SolidRuby.
2
+ #
3
+ # SolidRuby 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
+ # SolidRuby 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 SolidRuby. If not, see <http://www.gnu.org/licenses/>.
15
+ #
16
+ module SolidRuby::Assemblies
17
+ class Bolt < Assembly
18
+ def initialize(size, length, args = {})
19
+ @args = args
20
+ @args[:type] ||= '912'
21
+ @args[:material] ||= 'steel 8.8'
22
+ @args[:surface] ||= 'zinc plated'
23
+ # options for output only:
24
+ @args[:additional_length] ||= 0
25
+ @args[:additional_diameter] ||= 0.3
26
+ @args[:head_margin] ||= 0.0
27
+
28
+ if @args[:washer] == true
29
+ @washer = Washer.new(size, material: @args[:material], surface: @args[:surface])
30
+ end
31
+
32
+ @size = size
33
+ @length = length
34
+ @transformations ||= []
35
+ super(args)
36
+ end
37
+
38
+ def description
39
+ norm = ''
40
+ if ['912', '933'].include? @args[:type]
41
+ norm = 'DIN'
42
+ elsif ['7380'].include? @args[:type]
43
+ norm = 'ISO'
44
+ end
45
+
46
+ "M#{@size}x#{@length} Bolt, #{norm} #{@args[:type]}, #{@args[:material]} #{@args[:surface]}"
47
+ end
48
+
49
+ def output
50
+ add_to_bom
51
+ case @args[:type].to_s
52
+ when '912'
53
+ res = bolt_912(@args[:additional_length], @args[:additional_diameter])
54
+ when '933'
55
+ res = bolt_933(@args[:additional_length], @args[:additional_diameter], @args[:head_margin])
56
+ when '7380'
57
+ res = bolt_7380(@args[:additional_length], @args[:additional_diameter])
58
+ else
59
+ raise "unkown type #{args[:type]} for Bolt!"
60
+ end
61
+
62
+ transform(res)
63
+ end
64
+
65
+ def show
66
+ add_to_bom
67
+ case @args[:type].to_s
68
+ when '912'
69
+ res = bolt_912(0, 0)
70
+ when '933'
71
+ res = bolt_933(0, 0)
72
+ when '7380'
73
+ res = bolt_7380(0, 0)
74
+ else
75
+ raise "unkown type #{args[:type]} for Bolt!"
76
+ end
77
+
78
+ @washer ||= nil
79
+ if @washer
80
+ res += @washer.show
81
+ res = res.translate(z: -@washer.height)
82
+ end
83
+
84
+ transform(res)
85
+ end
86
+
87
+ # ISO 7380
88
+ def bolt_7380(additional_length = 0, addtional_diameter = 0)
89
+ chart_iso7380 = {
90
+ 3 => { head_dia: 5.7, head_length: 1.65 },
91
+ 4 => { head_dia: 7.6, head_length: 2.2 },
92
+ 5 => { head_dia: 9.5, head_length: 2.75 },
93
+ 6 => { head_dia: 10.5, head_length: 3.3 },
94
+ 8 => { head_dia: 14, head_length: 4.4 },
95
+ 10 => { head_dia: 17.5, head_length: 5.5 },
96
+ 12 => { head_dia: 21, head_length: 6.6 }
97
+ }
98
+ res = cylinder(d1: chart_iso7380[@size][:head_dia] / 2.0, d2: chart_iso7380[@size][:head_dia], h: chart_iso7380[@size][:head_length]).translate(z: -chart_iso7380[@size][:head_length]).color('Gainsboro')
99
+ total_length = @length + additional_length
100
+ res += cylinder(d: @size + addtional_diameter, h: total_length).color('DarkGray')
101
+ end
102
+
103
+ # DIN 912
104
+ def bolt_912(additional_length = 0, addtional_diameter = 0)
105
+ chart_din912 = {
106
+ 2 => { head_dia: 3.8, head_length: 2, thread_length: 16 },
107
+ 2.5 => { head_dia: 4.5, head_length: 2.5, thread_length: 17 },
108
+ 3 => { head_dia: 5.5, head_length: 3, thread_length: 18 },
109
+ 4 => { head_dia: 7.0, head_length: 4, thread_length: 20 },
110
+ 5 => { head_dia: 8.5, head_length: 5, thread_length: 22 },
111
+ 6 => { head_dia: 10, head_length: 6, thread_length: 24 },
112
+ 8 => { head_dia: 13, head_length: 8, thread_length: 28 },
113
+ 10 => { head_dia: 16, head_length: 10, thread_length: 32 },
114
+ 12 => { head_dia: 18, head_length: 12, thread_length: 36 },
115
+ 14 => { head_dia: 21, head_length: 14, thread_length: 40 },
116
+ 16 => { head_dia: 24, head_length: 16, thread_length: 44 },
117
+ 18 => { head_dia: 27, head_length: 18, thread_length: 48 },
118
+ 20 => { head_dia: 30, head_length: 20, thread_length: 52 },
119
+ 22 => { head_dia: 33, head_length: 22, thread_length: 56 },
120
+ 24 => { head_dia: 36, head_length: 24, thread_length: 60 },
121
+ 30 => { head_dia: 45, head_length: 30, thread_length: 72 },
122
+ 36 => { head_dia: 54, head_length: 36, thread_length: 84 }
123
+ }
124
+
125
+ res = cylinder(d: chart_din912[@size][:head_dia], h: chart_din912[@size][:head_length]).translate(z: -chart_din912[@size][:head_length]).color('Gainsboro')
126
+
127
+ total_length = @length + additional_length
128
+ thread_length = chart_din912[@size][:thread_length]
129
+ if total_length.to_f <= thread_length
130
+ res += cylinder(d: @size + addtional_diameter, h: total_length).color('DarkGray')
131
+ else
132
+ res += cylinder(d: @size + addtional_diameter, h: total_length - thread_length).color('Gainsboro')
133
+ res += cylinder(d: @size + addtional_diameter, h: thread_length).translate(z: total_length - thread_length).color('DarkGray')
134
+ end
135
+ res
136
+ end
137
+
138
+ def bolt_933(additional_length = 0, addtional_diameter = 0, head_margin = 0)
139
+ chart = {
140
+ 2 => { head_side_to_side: 4, head_length: 1.4 },
141
+ 2.5 => { head_side_to_side: 5, head_length: 1.7 },
142
+ 3 => { head_side_to_side: 5.5, head_length: 2 },
143
+ 4 => { head_side_to_side: 7, head_length: 2.8 },
144
+ 5 => { head_side_to_side: 8, head_length: 3.5 },
145
+ 6 => { head_side_to_side: 10, head_length: 4 },
146
+ 8 => { head_side_to_side: 13, head_length: 5.5 },
147
+ 10 => { head_side_to_side: 17, head_length: 7 },
148
+ 12 => { head_side_to_side: 19, head_length: 8 },
149
+ 14 => { head_side_to_side: 22, head_length: 9 },
150
+ 16 => { head_side_to_side: 24, head_length: 10 }
151
+ }
152
+ head_dia = chart[@size][:head_side_to_side].to_f + head_margin.to_f
153
+ res = cylinder(d: (head_dia / Math.sqrt(3)) * 2, fn: 6, h: chart[@size][:head_length]).translate(z: -chart[@size][:head_length]).color('Gainsboro')
154
+ total_length = @length + additional_length
155
+ res += cylinder(d: @size + addtional_diameter, h: total_length).color('DarkGray')
156
+ end
157
+ end
158
+ end