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
@@ -0,0 +1,58 @@
|
|
1
|
+
module JennCad::Extras
|
2
|
+
class Iso7380 < 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_7380(@args[:additional_length], @args[:additional_diameter], @args[:head_margin])
|
24
|
+
Aggregation.new("iso7380c#{@size}#{option_string}", res)
|
25
|
+
end
|
26
|
+
|
27
|
+
def show
|
28
|
+
res = bolt_7380(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("iso7380s#{@size}#{option_string}", res)
|
35
|
+
end
|
36
|
+
|
37
|
+
# ISO 7380
|
38
|
+
def bolt_7380(additional_length=0, addtional_diameter=0, head_margin=0)
|
39
|
+
if head_margin.to_f != 0
|
40
|
+
puts "[warning] :head_margin is not implemented for 7380 bolts"
|
41
|
+
end
|
42
|
+
chart_iso7380 = {
|
43
|
+
3 => {head_dia:5.7,head_length:1.65},
|
44
|
+
4 => {head_dia:7.6,head_length:2.2},
|
45
|
+
5 => {head_dia:9.5,head_length:2.75},
|
46
|
+
6 => {head_dia:10.5,head_length:3.3},
|
47
|
+
8 => {head_dia:14,head_length:4.4},
|
48
|
+
10=> {head_dia:17.5,head_length:5.5},
|
49
|
+
12=> {head_dia:21,head_length:6.6},
|
50
|
+
|
51
|
+
|
52
|
+
}
|
53
|
+
res = cylinder(d1:chart_iso7380[@size][:head_dia]/2.0,d2:chart_iso7380[@size][:head_dia],h:chart_iso7380[@size][:head_length]).move(z:-chart_iso7380[@size][:head_length])
|
54
|
+
total_length = @length + additional_length
|
55
|
+
res+= cylinder(d:@size+addtional_diameter, h:total_length)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,274 @@
|
|
1
|
+
module JennCad
|
2
|
+
|
3
|
+
class OpenScad
|
4
|
+
def initialize(part, fn=64)
|
5
|
+
@imports = []
|
6
|
+
@modules = {}
|
7
|
+
part = part.make_openscad_compatible
|
8
|
+
@main = root(part, "$fn=#{fn};\n")
|
9
|
+
|
10
|
+
@export = ""
|
11
|
+
@imports.uniq.each do |val|
|
12
|
+
@export += "use <#{val}.scad>\n"
|
13
|
+
end
|
14
|
+
@modules.each do |key, val|
|
15
|
+
@export += val
|
16
|
+
end
|
17
|
+
@export += @main
|
18
|
+
end
|
19
|
+
|
20
|
+
def save(file)
|
21
|
+
File.open(file,"w") do |f|
|
22
|
+
f.puts @export
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def root(part, head="", tabindex=0)
|
27
|
+
res = head
|
28
|
+
|
29
|
+
res += transform(part) do
|
30
|
+
parse(part, tabindex)
|
31
|
+
end
|
32
|
+
res
|
33
|
+
end
|
34
|
+
|
35
|
+
def transform(part, &block)
|
36
|
+
res += handle_color(part)
|
37
|
+
if part.transformations
|
38
|
+
part.transformations.reverse.each do |trans|
|
39
|
+
res += transformation(trans)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
res += block.yield
|
43
|
+
end
|
44
|
+
|
45
|
+
def print_tree(part, level=0)
|
46
|
+
arr = []
|
47
|
+
arr << parse(part) unless level == 0
|
48
|
+
if part.respond_to?(:parts)
|
49
|
+
part.parts.each do |p|
|
50
|
+
arr << print_tree(p,level+1)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
arr
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def parse(part, tabindex=0)
|
58
|
+
case part
|
59
|
+
when JennCad::OpenScadImport
|
60
|
+
handle_import(part)
|
61
|
+
when JennCad::Aggregation
|
62
|
+
handle_aggregation(part)
|
63
|
+
when JennCad::UnionObject
|
64
|
+
cmd('union', nil, part.parts, tabindex)
|
65
|
+
when JennCad::SubtractObject
|
66
|
+
part.analyze_z_fighting
|
67
|
+
cmd('difference', nil, part.parts, tabindex)
|
68
|
+
when JennCad::IntersectionObject
|
69
|
+
cmd('intersection', nil, part.parts, tabindex)
|
70
|
+
when JennCad::HullObject
|
71
|
+
cmd('hull', nil, part.parts, tabindex)
|
72
|
+
when JennCad::Primitives::Circle
|
73
|
+
cmd('circle', collect_params(part), nil, tabindex)
|
74
|
+
when JennCad::Primitives::Cylinder
|
75
|
+
cmd('cylinder', collect_params(part), nil, tabindex)
|
76
|
+
when JennCad::Primitives::Sphere
|
77
|
+
cmd('sphere', collect_params(part), nil, tabindex)
|
78
|
+
when JennCad::Primitives::Cube
|
79
|
+
handle_cube(part, tabindex)
|
80
|
+
when JennCad::Primitives::LinearExtrude
|
81
|
+
cmd('linear_extrude', part.openscad_params, part.parts, tabindex)
|
82
|
+
when JennCad::Primitives::RotateExtrude
|
83
|
+
cmd('rotate_extrude', part.openscad_params, part.parts, tabindex)
|
84
|
+
when JennCad::Primitives::Projection
|
85
|
+
cmd('projection', collect_params(part), part.parts, tabindex)
|
86
|
+
when JennCad::Primitives::Polygon
|
87
|
+
cmd('polygon', collect_params(part), nil, tabindex)
|
88
|
+
else
|
89
|
+
if part.respond_to?(:parts) && part.parts != nil && !part.parts.empty?
|
90
|
+
res = ""
|
91
|
+
part.parts.each do |p|
|
92
|
+
res += root(p, "", tabindex)
|
93
|
+
end
|
94
|
+
return res
|
95
|
+
elsif part.respond_to?(:part)
|
96
|
+
return root(part.part, "", tabindex)
|
97
|
+
end
|
98
|
+
puts "no idea what to do with #{part.inspect}"
|
99
|
+
return ""
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def fmt_params(args)
|
104
|
+
return "" if args == nil
|
105
|
+
if args.kind_of? String
|
106
|
+
return "\"#{args}\""
|
107
|
+
elsif args.kind_of? Array
|
108
|
+
return args.map do |l|
|
109
|
+
if l == nil
|
110
|
+
0
|
111
|
+
elsif l.kind_of? Array
|
112
|
+
l # skipping check of 2-dmin Arrays for now (used in multmatrix)
|
113
|
+
elsif l.to_i == l.to_f
|
114
|
+
l.to_i
|
115
|
+
else
|
116
|
+
l.to_f
|
117
|
+
end
|
118
|
+
end
|
119
|
+
else
|
120
|
+
res = []
|
121
|
+
args.each do |k,v|
|
122
|
+
if k.to_s == "fn"
|
123
|
+
k = "$fn"
|
124
|
+
end
|
125
|
+
if v == nil
|
126
|
+
next
|
127
|
+
end
|
128
|
+
if !v.kind_of?(Array) && !v.kind_of?(TrueClass) && !v.kind_of?(FalseClass) && v == v.to_i
|
129
|
+
v = v.to_i
|
130
|
+
end
|
131
|
+
res << "#{k}=#{v}"
|
132
|
+
end
|
133
|
+
res.join(",")
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def cmd(name, args, items, tabindex = 0)
|
138
|
+
items ||= []
|
139
|
+
res = cmd_call(name,args)
|
140
|
+
if items.size > 1
|
141
|
+
res << "\n"
|
142
|
+
res << tabs(tabindex) { "{\n" }
|
143
|
+
items.each do |item|
|
144
|
+
res << tabs(tabindex+1) do
|
145
|
+
transform(item) do
|
146
|
+
parse(item, tabindex+1)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
res << tabs(tabindex) { "}\n" }
|
151
|
+
elsif items.size == 1
|
152
|
+
item = items.first
|
153
|
+
res << transform(item) do
|
154
|
+
parse(item, tabindex)
|
155
|
+
end
|
156
|
+
res << ";\n"
|
157
|
+
else
|
158
|
+
res << ";\n"
|
159
|
+
end
|
160
|
+
return res
|
161
|
+
end
|
162
|
+
|
163
|
+
def tabs(i, &block)
|
164
|
+
" " * i + block.yield
|
165
|
+
end
|
166
|
+
|
167
|
+
def handle_import(part, tabindex=0)
|
168
|
+
@imports << part.import
|
169
|
+
return tabs(tabindex){ "#{part.name}(#{fmt_params(part.args)});\n" }
|
170
|
+
end
|
171
|
+
|
172
|
+
def handle_aggregation(part, tabindex=0)
|
173
|
+
register_module(part) unless @modules[part.name]
|
174
|
+
use_module(part.name, tabindex)
|
175
|
+
end
|
176
|
+
|
177
|
+
# check children for color values
|
178
|
+
# if none of the children has a color value, we can apply color to this object and all children
|
179
|
+
# if any of the children (excluding children of the kind of BooleanObject) has a color value (that is different from ours), we will apply a fallback color to all children that do not have a color value themselves.
|
180
|
+
|
181
|
+
def handle_color(part)
|
182
|
+
if part && part.respond_to?(:color) && part.color
|
183
|
+
if part.respond_to?(:parts)
|
184
|
+
if part.children_list(JennCad::Aggregation).map{|l| l.color != nil && l.color != part.color}.include?(true)
|
185
|
+
part.children_list(JennCad::Aggregation).each do |child|
|
186
|
+
if child.color == nil && child.color != part.color && !child.kind_of?(BooleanObject)
|
187
|
+
child.set_option :fallback_color, part.color
|
188
|
+
end
|
189
|
+
end
|
190
|
+
return ""
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
return apply_color(part)
|
195
|
+
end
|
196
|
+
|
197
|
+
def apply_color(part)
|
198
|
+
if part && part.respond_to?(:color_or_fallback)
|
199
|
+
color = part.color_or_fallback
|
200
|
+
return "" if color == nil
|
201
|
+
# Allowing color to be string, OpenScad compatible RGBA values of 0..1 or RGBA values of 0..255
|
202
|
+
if color.kind_of?(Array) && color.map{|l| l.to_f > 1.0 ? true : false}.include?(true)
|
203
|
+
color = color.map{|l| l.to_f/255.0}
|
204
|
+
end
|
205
|
+
return cmd_call("color", color)
|
206
|
+
end
|
207
|
+
return ""
|
208
|
+
end
|
209
|
+
|
210
|
+
def register_module(part)
|
211
|
+
# can only accept aggregation
|
212
|
+
@modules[part.name] = "module #{part.name}(){\n"
|
213
|
+
@modules[part.name] += root(part.part)
|
214
|
+
@modules[part.name] += "}\n"
|
215
|
+
end
|
216
|
+
|
217
|
+
def use_module(name, tabindex)
|
218
|
+
tabs(tabindex){ cmd_call(name, nil).to_s+";" }
|
219
|
+
end
|
220
|
+
|
221
|
+
def cmd_call(name, args)
|
222
|
+
args = fmt_params(args)
|
223
|
+
return "#{name}(#{args})"
|
224
|
+
end
|
225
|
+
|
226
|
+
def collect_params(part)
|
227
|
+
res = {}
|
228
|
+
[:d, :r, :h, :r1, :r2, :d1, :d2, :size, :fn, :points].each do |var|
|
229
|
+
if part.respond_to? var
|
230
|
+
res[var] = part.send var
|
231
|
+
end
|
232
|
+
end
|
233
|
+
res
|
234
|
+
end
|
235
|
+
|
236
|
+
def transformation(trans)
|
237
|
+
case trans
|
238
|
+
when JennCad::Move
|
239
|
+
cmd_call("translate",trans.coordinates)
|
240
|
+
when JennCad::Rotate
|
241
|
+
cmd_call("rotate",trans.coordinates)
|
242
|
+
when JennCad::Mirror
|
243
|
+
cmd_call("mirror",trans.coordinates)
|
244
|
+
when JennCad::Multmatrix
|
245
|
+
cmd_call("multmatrix",trans.m)
|
246
|
+
else
|
247
|
+
puts "[openscad exporter] Unkown transformation #{trans.class}"
|
248
|
+
""
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
# cubes are now centered in xy by default in jenncad
|
253
|
+
# TODO: should this not be to_openscad in Cube?
|
254
|
+
def handle_cube(part, tabindex)
|
255
|
+
res = ""
|
256
|
+
if part.option(:center)
|
257
|
+
res += transformation(Move.new(x: -part.x/2.0, y: -part.y/2.0))
|
258
|
+
else
|
259
|
+
if part.option(:center_x)
|
260
|
+
res += transformation(Move.new(x: -part.x/2.0))
|
261
|
+
end
|
262
|
+
if part.option(:center_y)
|
263
|
+
res += transformation(Move.new(y: -part.y/2.0))
|
264
|
+
end
|
265
|
+
if part.option(:center_z)
|
266
|
+
res += transformation(Move.new(z: -part.z/2.0))
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
res += cmd('cube', collect_params(part), nil)
|
271
|
+
end
|
272
|
+
|
273
|
+
end
|
274
|
+
end
|
data/lib/jenncad/part.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module JennCad
|
2
|
+
# Part should be inherited from the user when making parts
|
3
|
+
class Part < Thing
|
4
|
+
|
5
|
+
def make_openscad_compatible
|
6
|
+
auto_color
|
7
|
+
a = Aggregation.new(self.class.to_s, make_openscad_compatible!(self.part))
|
8
|
+
a.transformations = @transformations
|
9
|
+
a.color(color)
|
10
|
+
a
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class Array
|
2
|
+
# Assembles things on top of each other
|
3
|
+
def assemble(partlib=nil, skip_z=false, z=0)
|
4
|
+
map do |part|
|
5
|
+
case part
|
6
|
+
when Array
|
7
|
+
res = part.assemble(partlib, true)
|
8
|
+
when String, Symbol
|
9
|
+
res = partlib[part].yield
|
10
|
+
when Proc
|
11
|
+
res = part.yield
|
12
|
+
else
|
13
|
+
res = part
|
14
|
+
end
|
15
|
+
# FIXME: I added 0.01 to all for now to fix z-fighting issues; this should not be hardcoded like this
|
16
|
+
res, z = res.move(z:z), z + res.z.to_f + 0.01 unless skip_z
|
17
|
+
res
|
18
|
+
end
|
19
|
+
.union
|
20
|
+
end
|
21
|
+
|
22
|
+
def union(&block)
|
23
|
+
if block
|
24
|
+
UnionObject.new(block.yield)
|
25
|
+
else
|
26
|
+
UnionObject.new(self)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module JennCad::Primitives
|
2
|
+
class BooleanObject < Primitive
|
3
|
+
def initialize(*parts)
|
4
|
+
@transformations = []
|
5
|
+
if parts.first.kind_of? Array
|
6
|
+
@parts = parts.first
|
7
|
+
else
|
8
|
+
@parts = parts
|
9
|
+
end
|
10
|
+
after_add
|
11
|
+
end
|
12
|
+
|
13
|
+
def add(part)
|
14
|
+
@parts << part
|
15
|
+
after_add
|
16
|
+
end
|
17
|
+
|
18
|
+
def after_add
|
19
|
+
@parts.flatten!
|
20
|
+
@parts.compact!
|
21
|
+
inherit_z
|
22
|
+
inherit_zref
|
23
|
+
end
|
24
|
+
|
25
|
+
def inherit_z
|
26
|
+
heights = @parts.map{|l| l.calc_z.to_f}.uniq
|
27
|
+
if heights.size > 1
|
28
|
+
total_heights = []
|
29
|
+
@parts.each do |p|
|
30
|
+
total_heights << p.z.to_f + p.calc_z.to_f
|
31
|
+
end
|
32
|
+
@z = total_heights.max
|
33
|
+
@calc_z = heights.min
|
34
|
+
else
|
35
|
+
@calc_z = heights.first.to_f
|
36
|
+
@z = @parts.map(&:z).compact.max
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def inherit_zref
|
41
|
+
return if @parts.first == nil
|
42
|
+
return if @parts.first.z.to_f == 0.0
|
43
|
+
get_primitives(@parts[1..-1]).flatten.each do |part|
|
44
|
+
if part.z.to_f == 0.0
|
45
|
+
part.set_option :zref, @parts.first
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_primitives(obj)
|
51
|
+
res = []
|
52
|
+
if obj.kind_of? Array
|
53
|
+
obj.each do |part|
|
54
|
+
res << part.children_list
|
55
|
+
end
|
56
|
+
else
|
57
|
+
res << obj.children_list
|
58
|
+
end
|
59
|
+
res
|
60
|
+
end
|
61
|
+
|
62
|
+
def only_additives_of(obj)
|
63
|
+
res = []
|
64
|
+
case obj
|
65
|
+
when Array
|
66
|
+
res << obj.map{|l| only_additives_of(l)}
|
67
|
+
when SubtractObject
|
68
|
+
when IntersectionObject
|
69
|
+
else
|
70
|
+
res << obj
|
71
|
+
end
|
72
|
+
res.flatten
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module JennCad::Primitives
|
2
|
+
class Cube < Primitive
|
3
|
+
attr_accessor :x,:y,:z
|
4
|
+
|
5
|
+
def initialize(args)
|
6
|
+
if args.kind_of?(Array) && args[0].kind_of?(Hash)
|
7
|
+
args = args.first
|
8
|
+
end
|
9
|
+
if args.kind_of? Array
|
10
|
+
m = {}
|
11
|
+
if args.last.kind_of? Hash
|
12
|
+
m = args.last
|
13
|
+
end
|
14
|
+
args = [:x, :y, :z].zip(args.flatten).to_h
|
15
|
+
args.deep_merge!(m)
|
16
|
+
end
|
17
|
+
@opts = {
|
18
|
+
x: 0,
|
19
|
+
y: 0,
|
20
|
+
z: 0,
|
21
|
+
margins: {
|
22
|
+
x: 0,
|
23
|
+
y: 0,
|
24
|
+
z: 0,
|
25
|
+
},
|
26
|
+
center: true,
|
27
|
+
center_y: false,
|
28
|
+
center_x: false,
|
29
|
+
center_z: false,
|
30
|
+
}.deep_merge!(args)
|
31
|
+
handle_margins
|
32
|
+
|
33
|
+
super(args)
|
34
|
+
@h = @z.dup
|
35
|
+
@calc_h = @z.dup
|
36
|
+
end
|
37
|
+
|
38
|
+
# used for openscad export
|
39
|
+
def size
|
40
|
+
[@x, @y, @z]
|
41
|
+
end
|
42
|
+
|
43
|
+
def center_xy
|
44
|
+
set_option :center, true
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
def center_x
|
49
|
+
set_option :center_x, true
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def center_y
|
54
|
+
set_option :center_y, true
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
def center_z
|
59
|
+
set_option :center_z, true
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
63
|
+
# def center
|
64
|
+
# @transformations << Move.new({x:-@x/2,y:-@y/2,z:-@z/2})
|
65
|
+
# self
|
66
|
+
# end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module JennCad::Primitives
|
2
|
+
class Cylinder < Primitive
|
3
|
+
attr_accessor :d, :r, :fn
|
4
|
+
def initialize(args)
|
5
|
+
if args.kind_of?(Array) && args[0].kind_of?(Hash)
|
6
|
+
args = args.first
|
7
|
+
end
|
8
|
+
if args.kind_of? Array
|
9
|
+
m = {}
|
10
|
+
if args.last.kind_of? Hash
|
11
|
+
m = args.last
|
12
|
+
end
|
13
|
+
args = [:d, :z].zip(args.flatten).to_h
|
14
|
+
args.deep_merge!(m)
|
15
|
+
end
|
16
|
+
|
17
|
+
args[:z] ||= args[:h]
|
18
|
+
|
19
|
+
@opts = {
|
20
|
+
d: 0,
|
21
|
+
z: nil,
|
22
|
+
r: 0,
|
23
|
+
margins: {
|
24
|
+
r: 0,
|
25
|
+
d: 0,
|
26
|
+
z: 0,
|
27
|
+
},
|
28
|
+
fn: nil,
|
29
|
+
}.deep_merge!(args)
|
30
|
+
|
31
|
+
# FIXME:
|
32
|
+
# - margins calculation needs to go to output
|
33
|
+
# - assinging these variables has to stop
|
34
|
+
# - r/d need to be automatically calculated by each other
|
35
|
+
# - r+z margin not implemented atm
|
36
|
+
# - need to migrate classes to provide all possible outputs (and non-conflicting ones) to openscad exporter
|
37
|
+
@d = args[:d] + @opts[:margins][:d]
|
38
|
+
@z = args[:z] || args[:h]
|
39
|
+
@r = args[:r]
|
40
|
+
@fn = args[:fn]
|
41
|
+
if @fn == nil && @d > 16
|
42
|
+
@fn = (@d*4).ceil
|
43
|
+
end
|
44
|
+
super(args)
|
45
|
+
end
|
46
|
+
|
47
|
+
def h
|
48
|
+
z
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module JennCad::Primitives
|
2
|
+
attr_accessor :center_bool, :convexity, :twist, :slices, :height
|
3
|
+
class LinearExtrude < JennCad::Thing
|
4
|
+
def initialize(part, args)
|
5
|
+
@transformations = []
|
6
|
+
@parts = [part]
|
7
|
+
@height = args[:h] || args[:height]
|
8
|
+
@center_bool = args[:center]
|
9
|
+
@convexity = args[:convexity]
|
10
|
+
@twist = args[:twist]
|
11
|
+
@slices = args[:slices]
|
12
|
+
@fn = args[:fn]
|
13
|
+
end
|
14
|
+
|
15
|
+
def openscad_params
|
16
|
+
res = {}
|
17
|
+
[:height, :convexity, :twist, :slices, :fn].each do |n|
|
18
|
+
res[n] = self.send n
|
19
|
+
end
|
20
|
+
res[:center] = @center_bool
|
21
|
+
res
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module JennCad::Primitives
|
2
|
+
class Primitive < JennCad::Thing
|
3
|
+
def initialize(*args)
|
4
|
+
super(*args)
|
5
|
+
end
|
6
|
+
|
7
|
+
def handle_margins
|
8
|
+
@x = @opts[:x] + @opts[:margins][:x]
|
9
|
+
@y = @opts[:y] + @opts[:margins][:y]
|
10
|
+
@z = @opts[:z] + @opts[:margins][:z]
|
11
|
+
end
|
12
|
+
|
13
|
+
def handle_diameter
|
14
|
+
@d = opts[:d]
|
15
|
+
@r = opts[:r]
|
16
|
+
if @d
|
17
|
+
@r = @d/2.0
|
18
|
+
elsif @r
|
19
|
+
@d = @r*2
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|