jenncad 1.0.0.pre.alpha1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|