scad-btw 0.1.0.pre1
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/.rspec +3 -0
- data/.rubocop.yml +17 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +21 -0
- data/README.md +31 -0
- data/Rakefile +12 -0
- data/exe/scad-btw +6 -0
- data/flake.lock +306 -0
- data/flake.nix +63 -0
- data/lib/extensions/jenncad.rb +91 -0
- data/lib/extensions/kernel.rb +17 -0
- data/lib/extensions/thor.rb +11 -0
- data/lib/scad/btw/base.rb +224 -0
- data/lib/scad/btw/cli/base.rb +31 -0
- data/lib/scad/btw/cli/concerns/export_formats.rb +43 -0
- data/lib/scad/btw/cli/concerns/export_options.rb +62 -0
- data/lib/scad/btw/cli/presets.rb +66 -0
- data/lib/scad/btw/cli/solid.rb +33 -0
- data/lib/scad/btw/cli/spoked.rb +33 -0
- data/lib/scad/btw/component/axle_hole.rb +53 -0
- data/lib/scad/btw/component/center.rb +58 -0
- data/lib/scad/btw/component/counterweight.rb +117 -0
- data/lib/scad/btw/component/flange.rb +96 -0
- data/lib/scad/btw/component/joint.rb +57 -0
- data/lib/scad/btw/component/joint_base.rb +34 -0
- data/lib/scad/btw/component/o_ring_groove.rb +95 -0
- data/lib/scad/btw/component/solid.rb +67 -0
- data/lib/scad/btw/component/spokes.rb +118 -0
- data/lib/scad/btw/component/tread.rb +109 -0
- data/lib/scad/btw/concerns/component_args.rb +26 -0
- data/lib/scad/btw/concerns/flange_heights.rb +24 -0
- data/lib/scad/btw/concerns/joint_args.rb +58 -0
- data/lib/scad/btw/concerns/part_commons.rb +29 -0
- data/lib/scad/btw/concerns/tread_width.rb +21 -0
- data/lib/scad/btw/converters/openscad_2_ascii_stl.rb +39 -0
- data/lib/scad/btw/presets/scale_1_38/cargo_wheel_thin_36_inch.rb +21 -0
- data/lib/scad/btw/presets/scale_1_38/v20.rb +83 -0
- data/lib/scad/btw/solid.rb +13 -0
- data/lib/scad/btw/spoked.rb +13 -0
- data/lib/scad/btw/version.rb +7 -0
- data/lib/scad/btw.rb +29 -0
- data/sig/scad/btw.rbs +6 -0
- metadata +150 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'extensions/jenncad'
|
4
|
+
|
5
|
+
module Extensions
|
6
|
+
module Kernel
|
7
|
+
def require(path)
|
8
|
+
ret = super
|
9
|
+
|
10
|
+
if path == 'jenncad/profile_loader'
|
11
|
+
::JennCad::ProfileLoader.prepend Extensions::JennCad::ProfileLoader
|
12
|
+
end
|
13
|
+
|
14
|
+
ret
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,224 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'scad/btw/concerns/component_args'
|
4
|
+
require 'scad/btw/concerns/part_commons'
|
5
|
+
|
6
|
+
require 'scad/btw/component/axle_hole'
|
7
|
+
require 'scad/btw/component/center'
|
8
|
+
require 'scad/btw/component/counterweight'
|
9
|
+
require 'scad/btw/component/flange'
|
10
|
+
require 'scad/btw/component/joint_base'
|
11
|
+
require 'scad/btw/component/joint'
|
12
|
+
require 'scad/btw/component/o_ring_groove'
|
13
|
+
require 'scad/btw/component/solid'
|
14
|
+
require 'scad/btw/component/spokes'
|
15
|
+
require 'scad/btw/component/tread'
|
16
|
+
|
17
|
+
module Scad
|
18
|
+
module Btw
|
19
|
+
class Base < JennCad::Part
|
20
|
+
include Scad::Btw::Concerns::PartCommons
|
21
|
+
|
22
|
+
# Wheel size mapping
|
23
|
+
# See eurobricks.com forum post https://bit.ly/3ZARZUZ for details
|
24
|
+
OLD_2_NEW_SIZE_MAP = {
|
25
|
+
'XXL' => 13,
|
26
|
+
'XLL' => 12,
|
27
|
+
'XL' => 11,
|
28
|
+
'LL' => 10,
|
29
|
+
'L' => 9,
|
30
|
+
'ML' => 8,
|
31
|
+
'M' => 7,
|
32
|
+
'MS' => 6,
|
33
|
+
'S' => 5
|
34
|
+
}.freeze
|
35
|
+
|
36
|
+
DEFAULTS = {
|
37
|
+
COLOR: :gray,
|
38
|
+
HEIGHT: 8,
|
39
|
+
INNER_HEIGHT_DIFF: -0.5,
|
40
|
+
IS_BLIND: false,
|
41
|
+
IS_THIN: true,
|
42
|
+
THIN_HEIGHT: 5,
|
43
|
+
WITH_COUNTERWEIGHT: false,
|
44
|
+
WITH_JOINT: false,
|
45
|
+
WITH_O_RING_GROOVE: false
|
46
|
+
}.freeze
|
47
|
+
|
48
|
+
COMPONENT_ARGS_MAPPING = {
|
49
|
+
axle: { height: :height },
|
50
|
+
center: { height: :height },
|
51
|
+
counterweight: { height: :inner_height, diameter: :size_2_diameter },
|
52
|
+
flange: { diameter: :size_2_diameter },
|
53
|
+
joint: { height: :height },
|
54
|
+
o_ring_groove: { diameter: :size_2_diameter, thin: :thin? },
|
55
|
+
solid: { height: :inner_height, diameter: :size_2_diameter },
|
56
|
+
spokes: { height: :inner_height, diameter: :size_2_diameter },
|
57
|
+
tread: { diameter: :size_2_diameter, height: :height }
|
58
|
+
}.freeze
|
59
|
+
|
60
|
+
ARGS = {
|
61
|
+
prefix: :wheel,
|
62
|
+
args: {
|
63
|
+
size: {
|
64
|
+
description: 'Wheel size.', required: true, type: :string,
|
65
|
+
enum: OLD_2_NEW_SIZE_MAP.keys + OLD_2_NEW_SIZE_MAP.values.map(&:to_s)
|
66
|
+
},
|
67
|
+
is_thin: {
|
68
|
+
description: 'Whether wheel is thin (5 mm) or not (8 mm).', default: DEFAULTS[:IS_THIN], type: :boolean
|
69
|
+
},
|
70
|
+
inner_height: {
|
71
|
+
description: "Height of spokes or web. Defaults to: Wheel thickness #{DEFAULTS[:INNER_HEIGHT_DIFF]}",
|
72
|
+
type: :numeric
|
73
|
+
},
|
74
|
+
with_o_ring_groove: {
|
75
|
+
description: 'Whether wheel has o-ring groove.', default: DEFAULTS[:WITH_O_RING_GROOVE], type: :boolean
|
76
|
+
},
|
77
|
+
with_joint: {
|
78
|
+
description: 'Whether wheel has joint.', default: DEFAULTS[:WITH_JOINT], type: :boolean
|
79
|
+
},
|
80
|
+
with_counterweight: {
|
81
|
+
description: 'Whether wheel has counterweight.', default: DEFAULTS[:WITH_COUNTERWEIGHT], type: :boolean
|
82
|
+
}
|
83
|
+
}
|
84
|
+
}.freeze
|
85
|
+
|
86
|
+
def initialize(args = {})
|
87
|
+
args = {}.merge(args.transform_keys(&:to_sym))
|
88
|
+
|
89
|
+
super(args)
|
90
|
+
|
91
|
+
@args = args
|
92
|
+
end
|
93
|
+
|
94
|
+
def part
|
95
|
+
(parts_additions - parts_substractions).color(color)
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.component_classes
|
99
|
+
Scad::Btw::Component.constants.map(&Scad::Btw::Component.method(:const_get)).select { |c| c.is_a? Class }
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.skip_components
|
103
|
+
[]
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
attr_reader :args
|
109
|
+
|
110
|
+
def skip_components
|
111
|
+
self.class.skip_components
|
112
|
+
end
|
113
|
+
|
114
|
+
def parts_additions
|
115
|
+
res = nil
|
116
|
+
|
117
|
+
component_classes.each do |c|
|
118
|
+
next if skip_component?(c, :addition)
|
119
|
+
|
120
|
+
res ? res += component_part(c) : res = component_part(c)
|
121
|
+
end
|
122
|
+
|
123
|
+
res
|
124
|
+
end
|
125
|
+
|
126
|
+
def parts_substractions
|
127
|
+
res = nil
|
128
|
+
|
129
|
+
component_classes.each do |c|
|
130
|
+
next if skip_component?(c, :substraction)
|
131
|
+
|
132
|
+
res ? res += component_part(c) : res = component_part(c)
|
133
|
+
end
|
134
|
+
|
135
|
+
res
|
136
|
+
end
|
137
|
+
|
138
|
+
# components
|
139
|
+
|
140
|
+
def component_part(component_class)
|
141
|
+
component_class.new(component_args(component_class)).part
|
142
|
+
end
|
143
|
+
|
144
|
+
def component_args(component_class)
|
145
|
+
component_global_args(component_class).merge(component_class.component_args(args)).merge(misc_args)
|
146
|
+
end
|
147
|
+
|
148
|
+
def component_global_args(component_class)
|
149
|
+
prefix = component_class::ARGS[:prefix]
|
150
|
+
|
151
|
+
COMPONENT_ARGS_MAPPING[prefix].transform_values { |v| send(v) }
|
152
|
+
end
|
153
|
+
|
154
|
+
def skip_component?(component_class, type)
|
155
|
+
return true unless type == component_class::TYPE
|
156
|
+
return true if skip_components.include?(component_class::ARGS[:prefix])
|
157
|
+
return true if not_with?(component_class::ARGS[:prefix])
|
158
|
+
|
159
|
+
false
|
160
|
+
end
|
161
|
+
|
162
|
+
def not_with?(component)
|
163
|
+
return false unless %i[counterweight joint o_ring_groove].include?(component)
|
164
|
+
|
165
|
+
!send("with_#{component}?".to_sym)
|
166
|
+
end
|
167
|
+
|
168
|
+
def component_classes
|
169
|
+
self.class.component_classes
|
170
|
+
end
|
171
|
+
|
172
|
+
# functions
|
173
|
+
|
174
|
+
def misc_args
|
175
|
+
args.except do |key, _|
|
176
|
+
component_classes.join(self.class).map { |c| c.component_args_key_map.values }.flatten.include?(key)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def height
|
181
|
+
thin? ? DEFAULTS[:THIN_HEIGHT] : DEFAULTS[:HEIGHT]
|
182
|
+
end
|
183
|
+
|
184
|
+
def thin?
|
185
|
+
args.fetch(:wheel_is_thin, DEFAULTS[:IS_THIN])
|
186
|
+
end
|
187
|
+
|
188
|
+
def inner_height
|
189
|
+
args[:wheel_inner_height] || (height + DEFAULTS[:INNER_HEIGHT_DIFF])
|
190
|
+
end
|
191
|
+
|
192
|
+
# See eurobricks.com forum post https://bit.ly/3ZARZUZ for details
|
193
|
+
def size_2_diameter
|
194
|
+
(size + 0.5) * 3.2
|
195
|
+
end
|
196
|
+
|
197
|
+
def size
|
198
|
+
provided_size = args.fetch(:wheel_size)
|
199
|
+
|
200
|
+
mapped_size = OLD_2_NEW_SIZE_MAP[provided_size] || provided_size
|
201
|
+
|
202
|
+
raise "Size #{provided_size} not supportet!" unless OLD_2_NEW_SIZE_MAP.values.include?(mapped_size.to_i)
|
203
|
+
|
204
|
+
mapped_size.to_f
|
205
|
+
end
|
206
|
+
|
207
|
+
def color
|
208
|
+
args[:wheel_color] || DEFAULTS[:COLOR]
|
209
|
+
end
|
210
|
+
|
211
|
+
def with_counterweight?
|
212
|
+
args[:wheel_with_counterweight] || with_joint? || DEFAULTS[:WITH_COUNTERWEIGHT]
|
213
|
+
end
|
214
|
+
|
215
|
+
def with_o_ring_groove?
|
216
|
+
args[:wheel_with_o_ring_groove] || DEFAULTS[:WITH_O_RING_GROOVE]
|
217
|
+
end
|
218
|
+
|
219
|
+
def with_joint?
|
220
|
+
args[:wheel_with_joint] || DEFAULTS[:WITH_JOINT]
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require 'extensions/thor'
|
5
|
+
Thor::Option.prepend Extensions::Thor::Option
|
6
|
+
|
7
|
+
require 'scad/btw'
|
8
|
+
require_relative 'presets'
|
9
|
+
require_relative 'solid'
|
10
|
+
require_relative 'spoked'
|
11
|
+
|
12
|
+
module Scad
|
13
|
+
module Btw
|
14
|
+
module Cli
|
15
|
+
class Base < Thor
|
16
|
+
desc 'preset SUBCOMMAND ...ARGS', 'Generate from presets'
|
17
|
+
subcommand 'preset', Scad::Btw::Cli::Presets
|
18
|
+
|
19
|
+
desc 'solid SUBCOMMAND ...ARGS', 'Generate solid wheel'
|
20
|
+
subcommand 'solid', Scad::Btw::Cli::Solid
|
21
|
+
|
22
|
+
desc 'spoked SUBCOMMAND ...ARGS', 'Generate spoked wheel'
|
23
|
+
subcommand 'spoked', Scad::Btw::Cli::Spoked
|
24
|
+
|
25
|
+
def self.exit_on_failure?
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
module Scad
|
6
|
+
module Btw
|
7
|
+
module Cli
|
8
|
+
module Concerns
|
9
|
+
module ExportFormats
|
10
|
+
extend ActiveSupport::Concern
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def export_part(part, file, format = 'scad')
|
15
|
+
case format
|
16
|
+
when 'scad'
|
17
|
+
export_part_to_scad(part, file)
|
18
|
+
when 'stl'
|
19
|
+
export_stl(part, file)
|
20
|
+
else
|
21
|
+
puts "Unknown export format `#{format}`. Choose one of `scad` and `stl`."
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def export_part_to_scad(part, file)
|
26
|
+
JennCad::Exporters::OpenScad.new(part).save(file)
|
27
|
+
end
|
28
|
+
|
29
|
+
def export_stl(part, file)
|
30
|
+
tempfile = Tempfile.new('scad')
|
31
|
+
|
32
|
+
export_part_to_scad(part, tempfile.path)
|
33
|
+
|
34
|
+
Scad::Btw::Converters::Openscad2AsciiStl.convert(in_path: tempfile.path, out_path: file)
|
35
|
+
ensure
|
36
|
+
tempfile.close
|
37
|
+
tempfile.unlink
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Scad
|
4
|
+
module Btw
|
5
|
+
module Cli
|
6
|
+
module Concerns
|
7
|
+
module ExportOptions
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
class_methods do
|
11
|
+
def _gen_options
|
12
|
+
_wheel_options + _component_options
|
13
|
+
end
|
14
|
+
|
15
|
+
def _wheel_options
|
16
|
+
_part_options(klass: Object.const_get(self::WHEEL_CLASS_NAME))
|
17
|
+
end
|
18
|
+
|
19
|
+
def _part_options(klass:)
|
20
|
+
klass::ARGS[:args].keys.map do |key|
|
21
|
+
_option_args(
|
22
|
+
prefix: klass::ARGS[:prefix],
|
23
|
+
name: key,
|
24
|
+
arg: klass::ARGS[:args][key]
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def _component_options
|
30
|
+
Object.const_get(self::WHEEL_CLASS_NAME).component_classes
|
31
|
+
.map do |cc|
|
32
|
+
_component_option(klass: cc)
|
33
|
+
end.flatten
|
34
|
+
end
|
35
|
+
|
36
|
+
def _component_option(klass:)
|
37
|
+
if Object.const_get(self::WHEEL_CLASS_NAME).skip_components
|
38
|
+
.include?(klass::ARGS[:prefix])
|
39
|
+
[]
|
40
|
+
else
|
41
|
+
_part_options(klass: klass)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def _option_args(prefix:, name:, arg:)
|
46
|
+
args = {
|
47
|
+
name: "#{prefix}_#{name}".to_sym,
|
48
|
+
kwargs: { desc: arg[:description] }
|
49
|
+
}
|
50
|
+
|
51
|
+
%i[type default required enum hide].each do |option|
|
52
|
+
args[:kwargs][option] = arg[option] if arg.key?(option)
|
53
|
+
end
|
54
|
+
|
55
|
+
args
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require 'scad/btw/cli/concerns/export_formats'
|
5
|
+
|
6
|
+
module Scad
|
7
|
+
module Btw
|
8
|
+
module Cli
|
9
|
+
class Presets < Thor
|
10
|
+
include ActiveSupport::Inflector
|
11
|
+
include Scad::Btw::Cli::Concerns::ExportFormats
|
12
|
+
|
13
|
+
PRESETS_NAMESPACE = 'Scad::Btw::Presets'
|
14
|
+
|
15
|
+
desc 'list', 'List available presets'
|
16
|
+
def list
|
17
|
+
print list_output
|
18
|
+
end
|
19
|
+
|
20
|
+
option :preset, required: true, type: :string
|
21
|
+
desc 'export FILE [FORMAT]', 'Export preset to file in either `scad` (default) or `stl` format'
|
22
|
+
def export(file, format = 'scad')
|
23
|
+
export_part(part, file, format)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def part
|
29
|
+
preset_class_name = "#{PRESETS_NAMESPACE}::#{camelize(underscore(options[:preset]))}"
|
30
|
+
|
31
|
+
constantize(preset_class_name).to_openscad
|
32
|
+
end
|
33
|
+
|
34
|
+
def list_output
|
35
|
+
<<~LIST_OUTPUT
|
36
|
+
Available presets:
|
37
|
+
|
38
|
+
#{presets.map { |p| " - #{p}" }.join("\n")}
|
39
|
+
|
40
|
+
Use `scad-btw preset export --preset <preset> <file>` to export a
|
41
|
+
preset to openscad.
|
42
|
+
LIST_OUTPUT
|
43
|
+
end
|
44
|
+
|
45
|
+
def presets
|
46
|
+
get_classes(constantize(PRESETS_NAMESPACE)).map do |c|
|
47
|
+
dasherize(underscore(c.name.delete_prefix("#{PRESETS_NAMESPACE}::")))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_classes(mod)
|
52
|
+
mod.constants.map do |c|
|
53
|
+
const = mod.const_get(c)
|
54
|
+
if const.is_a? Class
|
55
|
+
const
|
56
|
+
elsif const.is_a? Module
|
57
|
+
get_classes(const)
|
58
|
+
else
|
59
|
+
next
|
60
|
+
end
|
61
|
+
end.flatten
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require 'scad/btw/cli/concerns/export_options'
|
5
|
+
require 'scad/btw/cli/concerns/export_formats'
|
6
|
+
|
7
|
+
module Scad
|
8
|
+
module Btw
|
9
|
+
module Cli
|
10
|
+
class Solid < Thor
|
11
|
+
include Scad::Btw::Cli::Concerns::ExportOptions
|
12
|
+
include Scad::Btw::Cli::Concerns::ExportFormats
|
13
|
+
include ActiveSupport::Inflector
|
14
|
+
|
15
|
+
WHEEL_CLASS_NAME = 'Scad::Btw::Solid'
|
16
|
+
|
17
|
+
_gen_options.each do |conf|
|
18
|
+
option(conf[:name], conf[:kwargs])
|
19
|
+
end
|
20
|
+
desc 'export FILE [FORMAT]', 'Export solid wheel to file in either `scad` (default) or `stl` format'
|
21
|
+
def export(file, format = 'scad')
|
22
|
+
export_part(part, file, format)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def part
|
28
|
+
constantize(WHEEL_CLASS_NAME).to_openscad(options)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require 'scad/btw/cli/concerns/export_options'
|
5
|
+
require 'scad/btw/cli/concerns/export_formats'
|
6
|
+
|
7
|
+
module Scad
|
8
|
+
module Btw
|
9
|
+
module Cli
|
10
|
+
class Spoked < Thor
|
11
|
+
include Scad::Btw::Cli::Concerns::ExportOptions
|
12
|
+
include Scad::Btw::Cli::Concerns::ExportFormats
|
13
|
+
include ActiveSupport::Inflector
|
14
|
+
|
15
|
+
WHEEL_CLASS_NAME = 'Scad::Btw::Spoked'
|
16
|
+
|
17
|
+
_gen_options.each do |conf|
|
18
|
+
option(conf[:name], conf[:kwargs])
|
19
|
+
end
|
20
|
+
desc 'export FILE [FORMAT]', 'Export solid wheel to file in either `scad` (default) or `stl` format'
|
21
|
+
def export(file, format = 'scad')
|
22
|
+
export_part(part, file, format)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def part
|
28
|
+
constantize(WHEEL_CLASS_NAME).to_openscad(options)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'scad/btw/concerns/component_args'
|
4
|
+
require 'scad/btw/concerns/part_commons'
|
5
|
+
|
6
|
+
module Scad
|
7
|
+
module Btw
|
8
|
+
module Component
|
9
|
+
class AxleHole < JennCad::Part
|
10
|
+
include Scad::Btw::Concerns::PartCommons
|
11
|
+
include Scad::Btw::Concerns::ComponentArgs
|
12
|
+
|
13
|
+
TYPE = :substraction
|
14
|
+
SPLINE_WIDTH = 2
|
15
|
+
DIAMETER = 5
|
16
|
+
|
17
|
+
ARGS = {
|
18
|
+
prefix: :axle,
|
19
|
+
args: {
|
20
|
+
height: {
|
21
|
+
description: 'Wheel height. Defaults to: Wheel height defined ' \
|
22
|
+
'by wheel thickness (`wheel_is_thin` flag).',
|
23
|
+
type: :numeric,
|
24
|
+
hide: true
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
def initialize(args = {})
|
30
|
+
super
|
31
|
+
|
32
|
+
@height = args.fetch(:height)
|
33
|
+
end
|
34
|
+
|
35
|
+
def part
|
36
|
+
res = spline
|
37
|
+
|
38
|
+
res + spline.rz(90)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
attr_reader :height
|
44
|
+
|
45
|
+
# components
|
46
|
+
|
47
|
+
def spline
|
48
|
+
cube(x: DIAMETER, y: SPLINE_WIDTH, z: height + 1).mz(-0.5)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'scad/btw/concerns/component_args'
|
4
|
+
require 'scad/btw/concerns/part_commons'
|
5
|
+
|
6
|
+
module Scad
|
7
|
+
module Btw
|
8
|
+
module Component
|
9
|
+
class Center < JennCad::Part
|
10
|
+
include Scad::Btw::Concerns::PartCommons
|
11
|
+
include Scad::Btw::Concerns::ComponentArgs
|
12
|
+
|
13
|
+
TYPE = :addition
|
14
|
+
MIN_DIAMETER = 7.4
|
15
|
+
|
16
|
+
ARGS = {
|
17
|
+
prefix: :center,
|
18
|
+
args: {
|
19
|
+
height: {
|
20
|
+
description: 'Center height. Defaults to: Wheel height defined ' \
|
21
|
+
'by wheel thickness (`wheel_is_thin` flag).',
|
22
|
+
type: :numeric,
|
23
|
+
hide: true
|
24
|
+
},
|
25
|
+
diameter: {
|
26
|
+
description: 'Center diameter. Minimum diameter of ' \
|
27
|
+
"#{MIN_DIAMETER} will be used if provided value " \
|
28
|
+
'is smaller.',
|
29
|
+
default: MIN_DIAMETER,
|
30
|
+
type: :numeric
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}.freeze
|
34
|
+
|
35
|
+
def initialize(args = {})
|
36
|
+
super
|
37
|
+
|
38
|
+
@diameter = args[:diameter] || 0
|
39
|
+
@height = args.fetch(:height)
|
40
|
+
end
|
41
|
+
|
42
|
+
def part
|
43
|
+
cylinder(d: calculated_diameter, h: height)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
attr_reader :diameter, :height
|
49
|
+
|
50
|
+
# functions
|
51
|
+
|
52
|
+
def calculated_diameter
|
53
|
+
[diameter, MIN_DIAMETER].max
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|