jenncad 1.0.0.pre.alpha1
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.
- checksums.yaml +7 -0
- data/Rakefile +1 -0
- data/bin/jenncad +10 -0
- data/examples/old/cube.rb +12 -0
- data/examples/old/slot.rb +10 -0
- data/examples/old/test.rb +18 -0
- data/examples/old/test1.rb +21 -0
- data/examples/old/test2.rb +9 -0
- data/examples/old/test3.rb +15 -0
- data/examples/old/test4.rb +17 -0
- data/examples/old/test5.rb +31 -0
- data/jenncad.gemspec +27 -0
- data/lib/jenncad/commands.rb +169 -0
- data/lib/jenncad/default_profile.rb +40 -0
- data/lib/jenncad/extras/din912.rb +89 -0
- data/lib/jenncad/extras/din933.rb +64 -0
- data/lib/jenncad/extras/din934.rb +99 -0
- data/lib/jenncad/extras/hardware.rb +16 -0
- data/lib/jenncad/extras/iso7380.rb +58 -0
- data/lib/jenncad/jenncad.rb +3 -0
- data/lib/jenncad/openscad.rb +274 -0
- data/lib/jenncad/part.rb +14 -0
- data/lib/jenncad/patches/array.rb +29 -0
- data/lib/jenncad/primitives/aggregation.rb +12 -0
- data/lib/jenncad/primitives/boolean_object.rb +76 -0
- data/lib/jenncad/primitives/circle.rb +11 -0
- data/lib/jenncad/primitives/cube.rb +69 -0
- data/lib/jenncad/primitives/cylinder.rb +52 -0
- data/lib/jenncad/primitives/hull_object.rb +4 -0
- data/lib/jenncad/primitives/intersection_object.rb +4 -0
- data/lib/jenncad/primitives/linear_extrude.rb +25 -0
- data/lib/jenncad/primitives/openscad_include.rb +11 -0
- data/lib/jenncad/primitives/polygon.rb +9 -0
- data/lib/jenncad/primitives/primitive.rb +24 -0
- data/lib/jenncad/primitives/projection.rb +9 -0
- data/lib/jenncad/primitives/rotate_extrude.rb +20 -0
- data/lib/jenncad/primitives/rounded_cube.rb +77 -0
- data/lib/jenncad/primitives/slot.rb +82 -0
- data/lib/jenncad/primitives/sphere.rb +11 -0
- data/lib/jenncad/primitives/subtract_object.rb +84 -0
- data/lib/jenncad/primitives/union_object.rb +5 -0
- data/lib/jenncad/profile_loader.rb +34 -0
- data/lib/jenncad/project.rb +28 -0
- data/lib/jenncad/register.rb +31 -0
- data/lib/jenncad/shortcuts.rb +109 -0
- data/lib/jenncad/thing.rb +308 -0
- data/lib/jenncad/transformation/color.rb +8 -0
- data/lib/jenncad/transformation/mirror.rb +7 -0
- data/lib/jenncad/transformation/move.rb +7 -0
- data/lib/jenncad/transformation/multmatrix.rb +9 -0
- data/lib/jenncad/transformation/rotate.rb +7 -0
- data/lib/jenncad/transformation/scale.rb +7 -0
- data/lib/jenncad/transformation/transformation.rb +14 -0
- data/lib/jenncad/version.rb +4 -0
- data/lib/jenncad.rb +73 -0
- data/todo.txt +29 -0
- metadata +155 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 81f68c07dc7fd50719d6ce024f56eb25712ef97c9b31568dcfa6658d9fa01596
|
4
|
+
data.tar.gz: 3c877488f386a7d7c6f8dd3b1543ca84641316ae2dbd5d6bcbb4577fbf94ae7c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9a95e7f398d275b81bfb4c9bbe21d3bd0e306708f0ef514e8391f50837eab066ec7aaca3ee46e4bbb08cd4a0c3fbee009b899b87aea2b5fe86ea5a74f6294ee3
|
7
|
+
data.tar.gz: 5425a1f502e12c8b8300995f921b2e9ce1d10f214728f5f2b6508610aa783f76907f3ffcc9bb40ed88e997302a12a896dc7afa9c544d6e3f0216750e4914e37f
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/jenncad
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "jenncad"
|
3
|
+
|
4
|
+
JennCad::Commands.register "", JennCad::Commands::Observe
|
5
|
+
JennCad::Commands.register "run", JennCad::Commands::Observe
|
6
|
+
JennCad::Commands.register "build", JennCad::Commands::Build
|
7
|
+
JennCad::Commands.register "new", JennCad::Commands::NewPart
|
8
|
+
JennCad::Commands.register "create", JennCad::Commands::NewProject
|
9
|
+
|
10
|
+
Hanami::CLI.new(JennCad::Commands).call
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'jenncad'
|
3
|
+
include JennCad
|
4
|
+
|
5
|
+
# cubes are centered in x,y and flat to z=0 by default
|
6
|
+
res = cube(40,30,20)
|
7
|
+
# if symbols are omitted first argument of cylinder is d (diameter), second is height
|
8
|
+
# if height is omitted, it will assume height of first suitable parent object. This only works for z direction
|
9
|
+
# if height is omitted, it will also reward you with automatic z-fighting. For other cuts it'll try to do the same but is not so smart
|
10
|
+
res -= cylinder(5)
|
11
|
+
|
12
|
+
res.openscad("cube.scad")
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'jenncad'
|
2
|
+
include JennCad
|
3
|
+
include JennCad::Extras
|
4
|
+
Nut = Din934
|
5
|
+
|
6
|
+
res = cylinder(d:40,h:20)
|
7
|
+
|
8
|
+
n = Nut.new(4)
|
9
|
+
res -= n.cut
|
10
|
+
|
11
|
+
n = Nut.new(4)
|
12
|
+
res -= n.cut.translate(x:20)
|
13
|
+
res += n.show.translate(x:20)
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
a = OpenScad.new(res)
|
18
|
+
a.save("examples/test1.scad")
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'jenncad'
|
3
|
+
include JennCad
|
4
|
+
include JennCad::Extras
|
5
|
+
Nut = Din934
|
6
|
+
|
7
|
+
h1 = 10
|
8
|
+
h2 = 20
|
9
|
+
res = cube([10,20,h1])
|
10
|
+
res += cylinder(d:40,h:h2).move(z:h1)
|
11
|
+
|
12
|
+
|
13
|
+
n = Nut.new(4)
|
14
|
+
res -= n.cut
|
15
|
+
|
16
|
+
n = Nut.new(4)
|
17
|
+
res -= n.cut.move(z:h1+h2-n.height)
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
res.openscad("examples/test1.scad")
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'jenncad'
|
2
|
+
include JennCad
|
3
|
+
|
4
|
+
res = import("involute_gears","bevel_gear",number_of_teeth:13, bore_diameter:10)
|
5
|
+
res += import("involute_gears","bevel_gear",number_of_teeth:6, bore_diameter:5).rotate(x:90).translate(y:50,z:30)
|
6
|
+
|
7
|
+
|
8
|
+
a = OpenScad.new(res)
|
9
|
+
a.save("examples/test2.scad")
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'jenncad'
|
3
|
+
include JennCad
|
4
|
+
include JennCad::Extras
|
5
|
+
Nut = Din934
|
6
|
+
|
7
|
+
res = cylinder(d:40,h:20)
|
8
|
+
res &= cylinder(d:40,h:20).translate(x:20)
|
9
|
+
res &= cube([20,20,20]).translate(y:20)
|
10
|
+
|
11
|
+
res.skew(y:-0.3)
|
12
|
+
|
13
|
+
|
14
|
+
a = OpenScad.new(res)
|
15
|
+
a.save("examples/test3.scad")
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'jenncad'
|
3
|
+
include JennCad
|
4
|
+
include JennCad::Extras
|
5
|
+
Nut = Din934
|
6
|
+
|
7
|
+
res = cube([30,30,10]).center_xy
|
8
|
+
res -= cylinder(d:20,h:2)
|
9
|
+
|
10
|
+
cyl = cylinder(d:10,h:5).translate(z:5)
|
11
|
+
res -= cyl
|
12
|
+
|
13
|
+
puts cyl.calc_z+cyl.calc_h
|
14
|
+
|
15
|
+
|
16
|
+
a = OpenScad.new(res)
|
17
|
+
a.save("examples/test4.scad")
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'jenncad'
|
3
|
+
include JennCad
|
4
|
+
include JennCad::Extras
|
5
|
+
Nut = Din934
|
6
|
+
|
7
|
+
res = cube([30,30,10]).center_xy
|
8
|
+
# at this moment, res is a cube
|
9
|
+
res.color = "Blue"
|
10
|
+
|
11
|
+
res += cylinder(d:10,h:20)
|
12
|
+
# with the += operator, res is now a union boolean object
|
13
|
+
res.color [120,20,13,200]
|
14
|
+
|
15
|
+
# everything added to the union will remain this color
|
16
|
+
res += cylinder(d:6,h:25)
|
17
|
+
|
18
|
+
# unless specified otherwise
|
19
|
+
res += cylinder(d:5, h:30).color("red")
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
# subtracting will change res to a subtraction object
|
24
|
+
res -= cylinder(d:4, h:30)
|
25
|
+
res += cylinder(d:2, h:40)
|
26
|
+
res.color("green")
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
a = OpenScad.new(res)
|
31
|
+
a.save("examples/test5.scad")
|
data/jenncad.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
require "jenncad"
|
6
|
+
|
7
|
+
Gem::Specification.new do |gem|
|
8
|
+
gem.name = "jenncad"
|
9
|
+
gem.version = JennCad::VERSION
|
10
|
+
gem.authors = ["Jennifer Glauche"]
|
11
|
+
gem.email = ["=^.^=@jenncad.kittenme.ws"]
|
12
|
+
gem.homepage = ""
|
13
|
+
gem.summary = %q{TBD}
|
14
|
+
gem.description = %q{TBD}
|
15
|
+
|
16
|
+
gem.license = 'LGPL-3'
|
17
|
+
gem.files = `git ls-files`.split($/)
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
|
+
gem.require_paths = ["lib"]
|
21
|
+
|
22
|
+
gem.required_ruby_version = ">= 2.5.0"
|
23
|
+
gem.add_runtime_dependency "geo3d"
|
24
|
+
gem.add_runtime_dependency "deep_merge"
|
25
|
+
gem.add_runtime_dependency "hanami-cli"
|
26
|
+
gem.add_runtime_dependency "activesupport"
|
27
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module JennCad
|
2
|
+
module Commands
|
3
|
+
extend Hanami::CLI::Registry
|
4
|
+
|
5
|
+
class Run < Hanami::CLI::Command
|
6
|
+
argument :name, required: false
|
7
|
+
|
8
|
+
def guess_executable(dir=Dir.pwd)
|
9
|
+
dir.split("/").last.to_s + ".rb"
|
10
|
+
end
|
11
|
+
|
12
|
+
def check_executable(file)
|
13
|
+
return true if File.exists?(file)
|
14
|
+
# this is not too smart at the moment
|
15
|
+
puts "cannot find executable #{file}"
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def observe(exec)
|
20
|
+
execute(exec)
|
21
|
+
script = Observr::Script.new
|
22
|
+
Dir.glob("**/**.rb").each do |file|
|
23
|
+
script.watch(file) do
|
24
|
+
execute(exec)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
contr = Observr::Controller.new(script, Observr.handler.new)
|
28
|
+
puts "JennCad running, refreshing on file changes. Press ctrl+c to exit"
|
29
|
+
contr.run
|
30
|
+
end
|
31
|
+
|
32
|
+
def execute(file)
|
33
|
+
print "refreshing..."
|
34
|
+
r = system("./#{file}")
|
35
|
+
case r
|
36
|
+
when true
|
37
|
+
$jenncad_profile.on_success(file)
|
38
|
+
when false
|
39
|
+
$jenncad_profile.on_error(file)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def build
|
44
|
+
admesh_installed = system("admesh --version > /dev/null")
|
45
|
+
unless admesh_installed
|
46
|
+
puts "Warning: cannot find admesh, stl export will be in ASCII"
|
47
|
+
end
|
48
|
+
|
49
|
+
Dir.glob("output/**/*.scad").each do |file|
|
50
|
+
stl = file.gsub(".scad",".stl")
|
51
|
+
build_stl(file, stl)
|
52
|
+
convert_to_binary(stl) if admesh_installed
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_stl(scad, stl)
|
57
|
+
puts "building #{stl}"
|
58
|
+
system("openscad #{scad} -o #{stl}")
|
59
|
+
end
|
60
|
+
|
61
|
+
def convert_to_binary(stl)
|
62
|
+
system("admesh #{stl} -b #{stl}")
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
class Build < Run
|
68
|
+
def call(name: nil, **)
|
69
|
+
unless name
|
70
|
+
name = guess_executable
|
71
|
+
end
|
72
|
+
if check_executable(name)
|
73
|
+
execute(name)
|
74
|
+
build
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class Observe < Run
|
80
|
+
def call(name: nil, **)
|
81
|
+
unless name
|
82
|
+
name = guess_executable
|
83
|
+
end
|
84
|
+
if check_executable(name)
|
85
|
+
observe(name)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class NewPart < Hanami::CLI::Command
|
91
|
+
include ActiveSupport::Inflector
|
92
|
+
desc "creates a new part in a project"
|
93
|
+
argument :name, required: true
|
94
|
+
def call(name:, **)
|
95
|
+
dir = Dir.pwd.split("/").last
|
96
|
+
executable = underscore(dir)+".rb"
|
97
|
+
executable_class = camelize(dir)
|
98
|
+
unless File.exists?(executable)
|
99
|
+
puts "Could not find #{executable}. Are you in a JennCad project directory?"
|
100
|
+
exit
|
101
|
+
end
|
102
|
+
FileUtils.mkdir_p("parts")
|
103
|
+
name = underscore(name)
|
104
|
+
classname = camelize(name)
|
105
|
+
filename = "parts/#{name}.rb"
|
106
|
+
if File.exists?(filename)
|
107
|
+
puts "File #{filename} already exists."
|
108
|
+
exit
|
109
|
+
end
|
110
|
+
File.open(filename, "w") do |f|
|
111
|
+
f.puts "class #{classname} < Part"
|
112
|
+
f.puts " def initialize(opts={})"
|
113
|
+
f.puts " @opts = {"
|
114
|
+
f.puts " x: 10,"
|
115
|
+
f.puts " y: 10,"
|
116
|
+
f.puts " z: 5,"
|
117
|
+
f.puts " }.merge(opts)"
|
118
|
+
f.puts " end"
|
119
|
+
f.puts ""
|
120
|
+
f.puts " def part"
|
121
|
+
f.puts " cube(@opts)"
|
122
|
+
f.puts " end"
|
123
|
+
f.puts "end"
|
124
|
+
end
|
125
|
+
puts "part #{filename} created. In your #{executable} add to class #{executable_class}:"
|
126
|
+
puts " def #{name}"
|
127
|
+
puts " #{classname}.new(config)"
|
128
|
+
puts " end"
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
class NewProject < Hanami::CLI::Command
|
135
|
+
include ActiveSupport::Inflector
|
136
|
+
desc "generates a new project"
|
137
|
+
argument :name, required: true
|
138
|
+
|
139
|
+
def call(name:, **)
|
140
|
+
name = underscore(name)
|
141
|
+
filename = name+".rb"
|
142
|
+
Dir.mkdir(name)
|
143
|
+
Dir.chdir(name)
|
144
|
+
classname = camelize(name)
|
145
|
+
File.open(filename, "w") do |f|
|
146
|
+
f.puts "#!/usr/bin/env ruby"
|
147
|
+
f.puts "require \"jenncad\""
|
148
|
+
f.puts "include JennCad"
|
149
|
+
f.puts ""
|
150
|
+
f.puts "class #{classname} < Project"
|
151
|
+
f.puts " def config"
|
152
|
+
f.puts " {}"
|
153
|
+
f.puts " end"
|
154
|
+
f.puts ""
|
155
|
+
f.puts " def #{name}"
|
156
|
+
f.puts " cube(10,10,10)"
|
157
|
+
f.puts " end"
|
158
|
+
f.puts "end"
|
159
|
+
f.puts ""
|
160
|
+
f.puts "#{classname}.new.run"
|
161
|
+
end
|
162
|
+
File.chmod(0755, filename)
|
163
|
+
|
164
|
+
puts "created new project #{name}"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module JennCad
|
2
|
+
class DefaultProfile
|
3
|
+
attr_accessor :colors
|
4
|
+
|
5
|
+
def auto_colors
|
6
|
+
%w(
|
7
|
+
Teal
|
8
|
+
DarkOliveGreen
|
9
|
+
Aquamarine
|
10
|
+
SteelBlue
|
11
|
+
LightCoral
|
12
|
+
OrangeRed
|
13
|
+
MediumVioletRed
|
14
|
+
DarkOrchid
|
15
|
+
HotPink
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
def colors
|
20
|
+
@colors ||= []
|
21
|
+
if @colors.empty?
|
22
|
+
@colors = auto_colors
|
23
|
+
end
|
24
|
+
@colors
|
25
|
+
end
|
26
|
+
|
27
|
+
# called by the command line interface when receiving normal exit status
|
28
|
+
def on_success(file)
|
29
|
+
system("echo $'\033]30;#{file}: ok\007'")
|
30
|
+
puts "ok"
|
31
|
+
end
|
32
|
+
|
33
|
+
# called by the command line interface when receiving error exit status
|
34
|
+
def on_error(file)
|
35
|
+
system("echo $'\033]30;#{file}: error\007'")
|
36
|
+
puts "error"
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module JennCad::Extras
|
2
|
+
class Din912 < Hardware
|
3
|
+
Data = {2 => {head_dia:3.8,head_length:2,thread_length:16},
|
4
|
+
2.5=> {head_dia:4.5,head_length:2.5,thread_length:17},
|
5
|
+
3 => {head_dia:5.5,head_length:3,thread_length:18},
|
6
|
+
4 => {head_dia:7.0,head_length:4,thread_length:20},
|
7
|
+
5 => {head_dia:8.5,head_length:5,thread_length:22},
|
8
|
+
6 => {head_dia:10,head_length:6,thread_length:24},
|
9
|
+
8 => {head_dia:13,head_length:8,thread_length:28},
|
10
|
+
10=> {head_dia:16,head_length:10,thread_length:32},
|
11
|
+
12=> {head_dia:18,head_length:12,thread_length:36},
|
12
|
+
14=> {head_dia:21,head_length:14,thread_length:40},
|
13
|
+
16=> {head_dia:24,head_length:16,thread_length:44},
|
14
|
+
18=> {head_dia:27,head_length:18,thread_length:48},
|
15
|
+
20=> {head_dia:30,head_length:20,thread_length:52},
|
16
|
+
22=> {head_dia:33,head_length:22,thread_length:56},
|
17
|
+
24=> {head_dia:36,head_length:24,thread_length:60},
|
18
|
+
30=> {head_dia:45,head_length:30,thread_length:72},
|
19
|
+
36=> {head_dia:54,head_length:36,thread_length:84},
|
20
|
+
}
|
21
|
+
|
22
|
+
|
23
|
+
attr_accessor :height
|
24
|
+
|
25
|
+
def initialize(size,length,args={})
|
26
|
+
super(args)
|
27
|
+
@args = args
|
28
|
+
# options for output only:
|
29
|
+
@args[:additional_length] ||= 0
|
30
|
+
@args[:additional_diameter] ||= 0.2
|
31
|
+
@args[:head_margin] ||= 0.3
|
32
|
+
@face = args[:face] || "bottom"
|
33
|
+
@flush = args[:flush] || nil
|
34
|
+
|
35
|
+
# if @args[:washer] == true
|
36
|
+
# @washer = Washer.new(size,{:material => @args[:material], :surface => @args[:surface]})
|
37
|
+
# end
|
38
|
+
|
39
|
+
@size = size
|
40
|
+
@length = length
|
41
|
+
@transformations ||= []
|
42
|
+
end
|
43
|
+
|
44
|
+
def cut
|
45
|
+
Aggregation.new("din912f#{@face}c#{@size}l#{@length}#{option_string}", bolt_912(false, @args[:additional_length], @args[:additional_diameter], @args[:head_margin])
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
def show
|
50
|
+
res = bolt_912(true, 0,0)
|
51
|
+
# if @washer
|
52
|
+
# res += @washer.show
|
53
|
+
# res = res.move(z:-@washer.height)
|
54
|
+
# end
|
55
|
+
# res
|
56
|
+
Aggregation.new("din912f#{@face}s#{@size}l#{@length}#{option_string}", res)
|
57
|
+
end
|
58
|
+
|
59
|
+
def bolt_912(show, additional_length=0, addtional_diameter=0, head_margin=0)
|
60
|
+
|
61
|
+
res = cylinder(d:Data[@size][:head_dia]+head_margin,h:Data[@size][:head_length]).move(z:-Data[@size][:head_length])
|
62
|
+
total_length = @length + additional_length
|
63
|
+
|
64
|
+
if show
|
65
|
+
res.color("Gainsboro")
|
66
|
+
thread_length=Data[@size][:thread_length]
|
67
|
+
if total_length.to_f <= thread_length
|
68
|
+
res+= cylinder(d:@size+addtional_diameter, h:total_length).color("DarkGray")
|
69
|
+
else
|
70
|
+
res+= cylinder(d:@size+addtional_diameter, h:total_length-thread_length)
|
71
|
+
res+= cylinder(d:@size+addtional_diameter, h:thread_length).move(z:total_length-thread_length).color("DarkGray")
|
72
|
+
end
|
73
|
+
else
|
74
|
+
res+= cylinder(d:@size+addtional_diameter, h:total_length)
|
75
|
+
end
|
76
|
+
if @flush
|
77
|
+
if @face == :top
|
78
|
+
@flush*=-1
|
79
|
+
end
|
80
|
+
res.move(z:Data[@size][:head_length] + @flush) # this needs to be fixed, need to tell it cut height to surface + margin for openscad mess
|
81
|
+
end
|
82
|
+
case @face
|
83
|
+
when :top
|
84
|
+
res = res.mirror(z:1)
|
85
|
+
end
|
86
|
+
res
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module JennCad::Extras
|
2
|
+
class Din933 < Hardware
|
3
|
+
attr_accessor :height
|
4
|
+
|
5
|
+
def initialize(size,length,args={})
|
6
|
+
super(args)
|
7
|
+
@args = args
|
8
|
+
# options for output only:
|
9
|
+
@args[:additional_length] ||= 0
|
10
|
+
@args[:additional_diameter] ||= 0.3
|
11
|
+
@args[:head_margin] ||= 0.0
|
12
|
+
|
13
|
+
#if @args[:washer] == true
|
14
|
+
# @washer = Washer.new(size,{:material => @args[:material], :surface => @args[:surface]})
|
15
|
+
#end
|
16
|
+
|
17
|
+
@size = size
|
18
|
+
@length = length
|
19
|
+
@transformations ||= []
|
20
|
+
end
|
21
|
+
|
22
|
+
def cut
|
23
|
+
res = bolt_933(@args[:additional_length], @args[:additional_diameter], @args[:head_margin])
|
24
|
+
Aggregation.new("din933c#{@size}#{option_string}", res)
|
25
|
+
end
|
26
|
+
|
27
|
+
def show
|
28
|
+
res = bolt_933(0,0)
|
29
|
+
#if @washer
|
30
|
+
# res += @washer.show
|
31
|
+
# res = res.move(z:-@washer.height)
|
32
|
+
#end
|
33
|
+
res.color("DarkGray")
|
34
|
+
Aggregation.new("din933s#{@size}#{option_string}", res)
|
35
|
+
end
|
36
|
+
|
37
|
+
def bolt_933(additional_length=0, addtional_diameter=0, head_margin=0)
|
38
|
+
|
39
|
+
chart = {2 => {head_side_to_side:4,head_length:1.4},
|
40
|
+
2.5=> {head_side_to_side:5,head_length:1.7},
|
41
|
+
3 => {head_side_to_side:5.5,head_length:2},
|
42
|
+
4 => {head_side_to_side:7,head_length:2.8},
|
43
|
+
5 => {head_side_to_side:8,head_length:3.5},
|
44
|
+
6 => {head_side_to_side:10,head_length:4},
|
45
|
+
8 => {head_side_to_side:13,head_length:5.5},
|
46
|
+
10=> {head_side_to_side:17,head_length:7},
|
47
|
+
12=> {head_side_to_side:19,head_length:8},
|
48
|
+
14=> {head_side_to_side:22,head_length:9},
|
49
|
+
16=> {head_side_to_side:24,head_length:10},
|
50
|
+
}
|
51
|
+
head_dia = chart[@size][:head_side_to_side].to_f + head_margin.to_f
|
52
|
+
res = cylinder(d:(head_dia/Math.sqrt(3))*2,fn:6,h:chart[@size][:head_length]).move(z:-chart[@size][:head_length])
|
53
|
+
total_length = @length + additional_length
|
54
|
+
res+= cylinder(d:@size+addtional_diameter, h:total_length)
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module JennCad::Extras
|
2
|
+
class Din934 < Hardware
|
3
|
+
attr_accessor :height
|
4
|
+
attr_accessor :data
|
5
|
+
Data = {2.5=> {side_to_side:5,height:2, support_diameter:2.8},
|
6
|
+
3 => {side_to_side:5.5,height:2.4, support_diameter:3.5},
|
7
|
+
4 => {side_to_side:7,height:3.2, support_diameter:4.4},
|
8
|
+
5 => {side_to_side:8,height:4, support_diameter:5.3},
|
9
|
+
6 => {side_to_side:10,height:5, support_diameter:6.3},
|
10
|
+
8 => {side_to_side:13,height:6.5, support_diameter:8.3},
|
11
|
+
10 => {side_to_side:17,height:8, support_diameter:10.3},
|
12
|
+
12 => {side_to_side:19,height:10, support_diameter:12.3},
|
13
|
+
}
|
14
|
+
|
15
|
+
|
16
|
+
def initialize(size,args={})
|
17
|
+
@size = size
|
18
|
+
@options = args.dup
|
19
|
+
@support = args[:support] ||= false
|
20
|
+
@support_layer_height = args[:support_layer_height] ||= 0.2
|
21
|
+
@margin = args[:margin] ||= 0.2 # default output margin
|
22
|
+
|
23
|
+
@slot = args[:slot] || nil
|
24
|
+
@slot_margin = args[:slot_margin] || 0.2
|
25
|
+
@slot_direction = args[:slot_direction] || "z"
|
26
|
+
@cylinder_length = args[:cylinder_length] || 0 # for slot only
|
27
|
+
|
28
|
+
@transformations ||= []
|
29
|
+
@args = args
|
30
|
+
|
31
|
+
@direction = args[:direction] || @slot_direction
|
32
|
+
|
33
|
+
@s = Data[@size][:side_to_side]
|
34
|
+
@height = Data[@size][:height]
|
35
|
+
@support_diameter = Data[@size][:support_diameter]
|
36
|
+
super(args)
|
37
|
+
end
|
38
|
+
|
39
|
+
def add_support(layer_height=@support_layer_height)
|
40
|
+
res = cylinder(d:@support_diameter,h:@height-layer_height)
|
41
|
+
# on very small nuts, add a support base of one layer height, so the support won't fall over
|
42
|
+
if @size < 6
|
43
|
+
res += cylinder(d:@s-1,h:layer_height)
|
44
|
+
end
|
45
|
+
res
|
46
|
+
end
|
47
|
+
|
48
|
+
def slot
|
49
|
+
case @slot_direction
|
50
|
+
when "x"
|
51
|
+
pos = {x:@slot}
|
52
|
+
when "y"
|
53
|
+
pos = {y:@slot}
|
54
|
+
when "z"
|
55
|
+
pos = {z:@slot}
|
56
|
+
when "-x"
|
57
|
+
pos = {x:-@slot}
|
58
|
+
when "-y"
|
59
|
+
pos = {y:-@slot}
|
60
|
+
when "-z"
|
61
|
+
pos = {z:-@slot}
|
62
|
+
else
|
63
|
+
raise "Invalid slot direction #{@slot_direction}"
|
64
|
+
end
|
65
|
+
res = hull(
|
66
|
+
nut_934(false,@margin,@slot_margin),
|
67
|
+
nut_934(false,@margin,@slot_margin).move(pos)
|
68
|
+
)
|
69
|
+
if @cylinder_length > 0
|
70
|
+
res += cylinder(d:@size+@margin,h:@cylinder_length)
|
71
|
+
end
|
72
|
+
res
|
73
|
+
end
|
74
|
+
|
75
|
+
def cut
|
76
|
+
Aggregation.new("din934c#{@size}#{option_string}", nut_934(false,@margin))
|
77
|
+
end
|
78
|
+
|
79
|
+
def show
|
80
|
+
Aggregation.new("din934s#{@size}#{option_string}", nut_934)
|
81
|
+
end
|
82
|
+
|
83
|
+
def nut_934(show=true,margin=0,height_margin=0)
|
84
|
+
size = @s + margin
|
85
|
+
|
86
|
+
res = cylinder(d:(size/Math.sqrt(3))*2,h:@height+height_margin,fn:6)
|
87
|
+
res -= cylinder(d:@size,h:@height) if show == true
|
88
|
+
if @support
|
89
|
+
res -= add_support
|
90
|
+
end
|
91
|
+
res.color("Gainsboro") if show
|
92
|
+
res
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
end
|