jenncad 1.0.0.pre.alpha6 → 1.0.0.pre.alpha9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/jenncad +1 -2
- data/jenncad.gemspec +1 -1
- data/lib/jenncad/commands.rb +5 -4
- data/lib/jenncad/features/aggregation.rb +1 -0
- data/lib/jenncad/features/path.rb +339 -0
- data/lib/jenncad/features.rb +2 -0
- data/lib/jenncad/primitives/cylinder.rb +7 -0
- data/lib/jenncad/primitives/rounded_cube.rb +7 -6
- data/lib/jenncad/primitives/subtract_object.rb +0 -1
- data/lib/jenncad/thing.rb +11 -11
- data/lib/jenncad/version.rb +1 -1
- metadata +8 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93ed5b4cc8c786d306d9fbaa7c0518a607b20c76f08538a0882584ec34955ac4
|
4
|
+
data.tar.gz: 5394a9131feb628a3d8f4a1d099ce75b104d0f0674c4dbb9d57db19fc555486a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29deaf817dfce550a7a3038454ddbca39c520ae1964526f7f7ebcf06edca9dbe056ec13d1f84e4390d3dbe0f043324f48c220e8bcb5a38e201b47853603bcca2
|
7
|
+
data.tar.gz: c4e3a0e515ad6586fbc9919a6f0608375bf4d2babf21b8de202b308227050fae25e3db2d44ca0f4271c67854d9f57508aa5dbf04c576d562b6515ed9da6419d4
|
data/bin/jenncad
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require "jenncad"
|
3
|
-
|
4
3
|
JennCad::Commands.register "", JennCad::Commands::Observe
|
5
4
|
JennCad::Commands.register "run", JennCad::Commands::Observe
|
6
5
|
JennCad::Commands.register "build", JennCad::Commands::Build
|
7
6
|
JennCad::Commands.register "new", JennCad::Commands::NewPart
|
8
7
|
JennCad::Commands.register "create", JennCad::Commands::NewProject
|
9
8
|
|
10
|
-
|
9
|
+
Dry::CLI.new(JennCad::Commands).call
|
data/jenncad.gemspec
CHANGED
@@ -22,7 +22,7 @@ Gem::Specification.new do |gem|
|
|
22
22
|
gem.required_ruby_version = ">= 2.6.0"
|
23
23
|
gem.add_runtime_dependency "geo3d"
|
24
24
|
gem.add_runtime_dependency "deep_merge"
|
25
|
-
gem.add_runtime_dependency "
|
25
|
+
gem.add_runtime_dependency "dry-cli"
|
26
26
|
gem.add_runtime_dependency "activesupport"
|
27
27
|
gem.add_runtime_dependency "observr"
|
28
28
|
end
|
data/lib/jenncad/commands.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
require "dry/cli"
|
1
2
|
module JennCad
|
2
3
|
module Commands
|
3
|
-
extend
|
4
|
+
extend Dry::CLI::Registry
|
4
5
|
MAGIC = "jenncad-append-project-magic"
|
5
6
|
|
6
|
-
class Run <
|
7
|
+
class Run < Dry::CLI::Command
|
7
8
|
argument :name, required: false
|
8
9
|
|
9
10
|
def guess_executable(dir=Dir.pwd)
|
@@ -88,7 +89,7 @@ module JennCad
|
|
88
89
|
end
|
89
90
|
end
|
90
91
|
|
91
|
-
class NewPart <
|
92
|
+
class NewPart < Dry::CLI::Command
|
92
93
|
include ActiveSupport::Inflector
|
93
94
|
desc "creates a new part in a project"
|
94
95
|
argument :name, required: true
|
@@ -156,7 +157,7 @@ module JennCad
|
|
156
157
|
|
157
158
|
end
|
158
159
|
|
159
|
-
class NewProject <
|
160
|
+
class NewProject < Dry::CLI::Command
|
160
161
|
include ActiveSupport::Inflector
|
161
162
|
desc "generates a new project"
|
162
163
|
argument :name, required: true
|
@@ -0,0 +1,339 @@
|
|
1
|
+
module JennCad
|
2
|
+
class RoundCorner
|
3
|
+
attr_accessor :start_point, :end_point, :input_a, :output_a, :a, :l, :od, :id, :thing, :angle, :current_angle, :direction, :from, :ccw
|
4
|
+
def initialize(args, &thing)
|
5
|
+
@start_point = args[:start_point]
|
6
|
+
@end_point = args[:end_point]
|
7
|
+
@a = args[:a]
|
8
|
+
@ccw = args[:ccw] || false
|
9
|
+
@l = args[:l]
|
10
|
+
@od = args[:od]
|
11
|
+
@id = args[:id]
|
12
|
+
@input_a = args[:input_a] || 0
|
13
|
+
@output_a = args[:output_a] || 0
|
14
|
+
@thing = thing
|
15
|
+
@angle = args[:angle]
|
16
|
+
@current_angle = args[:current_angle]
|
17
|
+
@direction = args[:direction]
|
18
|
+
@to = args[:to]
|
19
|
+
@from = args[:from]
|
20
|
+
|
21
|
+
if @a < 0
|
22
|
+
@from = case @from
|
23
|
+
when :left
|
24
|
+
:right
|
25
|
+
when :right
|
26
|
+
:left
|
27
|
+
when :top, :up
|
28
|
+
:bottom
|
29
|
+
when :down, :bottom
|
30
|
+
:up
|
31
|
+
else
|
32
|
+
# // unimplemented
|
33
|
+
@from
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_angles(cur, total, direction)
|
40
|
+
@current_angle = cur
|
41
|
+
@angle = normalize(total)
|
42
|
+
@direction = direction
|
43
|
+
end
|
44
|
+
|
45
|
+
def normalize(angle)
|
46
|
+
if angle < 0
|
47
|
+
angle += 360
|
48
|
+
end
|
49
|
+
if angle >= 360
|
50
|
+
angle -= 360
|
51
|
+
end
|
52
|
+
angle
|
53
|
+
end
|
54
|
+
|
55
|
+
def margin
|
56
|
+
return @od
|
57
|
+
end
|
58
|
+
|
59
|
+
def positions
|
60
|
+
td = thing.yield.d || thing.yield.y
|
61
|
+
unless td
|
62
|
+
puts "ERROR: cannot find diameter or y of thing #{thing.yield.inspect}"
|
63
|
+
return
|
64
|
+
end
|
65
|
+
l = td + @id
|
66
|
+
l2 = td / 2.0 + @id / 2.0
|
67
|
+
r = 0
|
68
|
+
ox = 0
|
69
|
+
oy = 0
|
70
|
+
cr = 180
|
71
|
+
case @from
|
72
|
+
when :left
|
73
|
+
r = 0
|
74
|
+
oy = -l
|
75
|
+
when :top, :up
|
76
|
+
r = -90
|
77
|
+
ox = -l
|
78
|
+
cr = 0
|
79
|
+
when :right
|
80
|
+
r = 180
|
81
|
+
oy = l
|
82
|
+
when :bottom, :down
|
83
|
+
cr = 0
|
84
|
+
r = 90
|
85
|
+
ox = l
|
86
|
+
# TODO: so this doesn't work yet,
|
87
|
+
# need to figure out the maths to translate this
|
88
|
+
when 0..360
|
89
|
+
r = 180-@from
|
90
|
+
cr = @a
|
91
|
+
end
|
92
|
+
|
93
|
+
r2 = cr + r + @a # 180+@a
|
94
|
+
x = - l2 * Math::sin((r2/180.0)*Math::PI)
|
95
|
+
y = - l2 * Math::cos((r2/180.0)*Math::PI)
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
return r, ox/2.0, oy/2.0, x, y
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
def part
|
104
|
+
d = thing.yield.d
|
105
|
+
len = d * 2 + @id
|
106
|
+
x = Math::sin((@a/180.0)*Math::PI)*len
|
107
|
+
y = Math::cos((@a/180.0)*Math::PI)*len
|
108
|
+
|
109
|
+
res = circle(d: len)
|
110
|
+
res -= circle(d: @id)
|
111
|
+
points = [[0,0]]
|
112
|
+
points << [0, len]
|
113
|
+
points << [x, y]
|
114
|
+
|
115
|
+
res *= polygon(points:points)
|
116
|
+
|
117
|
+
r, ox, oy, x, y = positions
|
118
|
+
res = res.rotate(z: r).move(x: ox, y: oy)
|
119
|
+
res = res.auto_extrude#.color("red")
|
120
|
+
|
121
|
+
#res += slot(d: 1.2, y: len/2.0, h: 10).rotate(z: r_midpoint).color("red")
|
122
|
+
#res += cylinder(d: 1, h: 10).move(x: x+ox,y: y+oy)
|
123
|
+
|
124
|
+
#res.moveh(x: thing.yield.d, y: -thing.yield.d)
|
125
|
+
res.move(x: @start_point[:x], y: @start_point[:y])
|
126
|
+
|
127
|
+
#res += cylinder(d: 1, h: 15).color("red").move(x: @start_point[:x], y: @start_point[:y]).move(z:-1)
|
128
|
+
|
129
|
+
|
130
|
+
res
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
class Line
|
137
|
+
attr_accessor :start_point, :end_point, :l, :thing, :angle, :current_angle, :direction
|
138
|
+
def initialize(args, &thing)
|
139
|
+
@start_point = args[:start_point]
|
140
|
+
@end_point = args[:end_point]
|
141
|
+
@angle = args[:angle]
|
142
|
+
@current_angle = args[:current_angle]
|
143
|
+
@direction = args[:direction]
|
144
|
+
@l = args[:l]
|
145
|
+
@thing = thing
|
146
|
+
end
|
147
|
+
|
148
|
+
def sp_margin(margin)
|
149
|
+
@start_point[:x] -= margin[:x]
|
150
|
+
@start_point[:y] -= margin[:y]
|
151
|
+
end
|
152
|
+
|
153
|
+
def ep_margin(margin)
|
154
|
+
@end_point[:x] -= margin[:x]
|
155
|
+
@end_point[:y] -= margin[:y]
|
156
|
+
end
|
157
|
+
|
158
|
+
def shrink_ep(len)
|
159
|
+
sx, sy = @start_point[:x], @start_point[:y]
|
160
|
+
ex, ey = @end_point[:x], @end_point[:y]
|
161
|
+
vx = ex-sx
|
162
|
+
vy = ey-sy
|
163
|
+
l = Math::sqrt(vx**2 + vy**2)
|
164
|
+
factor = len / l
|
165
|
+
@end_point[:x] -= vx * factor
|
166
|
+
@end_point[:y] -= vy * factor
|
167
|
+
#puts "#{sx} x #{sy} => #{ex} x #{ey} , shrink #{factor} "
|
168
|
+
end
|
169
|
+
|
170
|
+
def shrink_sp(len)
|
171
|
+
sx, sy = @start_point[:x], @start_point[:y]
|
172
|
+
ex, ey = @end_point[:x], @end_point[:y]
|
173
|
+
vx = ex-sx
|
174
|
+
vy = ey-sy
|
175
|
+
l = Math::sqrt(vx**2 + vy**2)
|
176
|
+
factor = len / l
|
177
|
+
@start_point[:x] -= vx * factor
|
178
|
+
@start_point[:y] -= vy * factor
|
179
|
+
end
|
180
|
+
|
181
|
+
|
182
|
+
def part
|
183
|
+
hull(
|
184
|
+
@thing.yield.move(x: @start_point[:x], y: @start_point[:y]),
|
185
|
+
@thing.yield.move(x: @end_point[:x], y: @end_point[:y])
|
186
|
+
)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
class Path < Thing
|
191
|
+
|
192
|
+
attr_accessor :elements, :lpos, :thing, :angle, :current_angle, :direction
|
193
|
+
def initialize(args)
|
194
|
+
@thing = args[:part] #// cylinder(d: @d, z: @z)
|
195
|
+
@part = new_thing
|
196
|
+
@angle = args[:a] || 0
|
197
|
+
@current_angle = args[:a] || 0
|
198
|
+
@direction = 0
|
199
|
+
@name = args[:name] || "Path"
|
200
|
+
@calc_h = @part.z
|
201
|
+
@dir = 0
|
202
|
+
@lpos = {x: 0, y: 0, l: 0, a: 0}
|
203
|
+
@coords = []
|
204
|
+
@steps = []
|
205
|
+
@parts = [new_thing]
|
206
|
+
|
207
|
+
super(args)
|
208
|
+
end
|
209
|
+
|
210
|
+
def new_thing
|
211
|
+
r = @thing.clone
|
212
|
+
r.transformations = []
|
213
|
+
r
|
214
|
+
end
|
215
|
+
|
216
|
+
def corner(args)
|
217
|
+
od = args[:od]
|
218
|
+
id = args[:id]
|
219
|
+
if id.nil? && od
|
220
|
+
id = new_thing.d
|
221
|
+
#puts "od: #{od} , thing d #{new_thing.d} new id #{id}"
|
222
|
+
end
|
223
|
+
if od.nil? && id
|
224
|
+
od = id + new_thing.d
|
225
|
+
end
|
226
|
+
rc = RoundCorner.new(
|
227
|
+
start_point: { x: @lpos[:x], y: @lpos[:y] },
|
228
|
+
end_point: { x: @lpos[:x], y: @lpos[:y] },
|
229
|
+
od: od,
|
230
|
+
id: id,
|
231
|
+
ccw: args[:ccw],
|
232
|
+
from: args[:from],
|
233
|
+
to: args[:to],
|
234
|
+
a: args[:a],
|
235
|
+
direction: @direction
|
236
|
+
){ new_thing }
|
237
|
+
|
238
|
+
_, ox, oy, x, y = rc.positions
|
239
|
+
@lpos[:x] += x + ox
|
240
|
+
@lpos[:y] += y + oy
|
241
|
+
|
242
|
+
@steps << rc
|
243
|
+
end
|
244
|
+
|
245
|
+
def line(args)
|
246
|
+
if args[:l]
|
247
|
+
args[:a] ||= 0
|
248
|
+
if args[:a] > 0
|
249
|
+
@direction = 1
|
250
|
+
elsif args[:a] < 0
|
251
|
+
@direction = -1
|
252
|
+
else
|
253
|
+
@direction = 0
|
254
|
+
end
|
255
|
+
|
256
|
+
@angle += args[:a]
|
257
|
+
@current_angle = args[:a]
|
258
|
+
|
259
|
+
l = args[:l]
|
260
|
+
gamma = 90
|
261
|
+
alpha = @angle
|
262
|
+
beta = gamma - alpha
|
263
|
+
|
264
|
+
case
|
265
|
+
when alpha == 90, alpha == -270
|
266
|
+
x = l
|
267
|
+
y = 0
|
268
|
+
when alpha == 180, alpha == -180
|
269
|
+
x = 0
|
270
|
+
y = -l
|
271
|
+
when alpha == 270, alpha == -90
|
272
|
+
x = -l
|
273
|
+
y = 0
|
274
|
+
when alpha == 360, alpha == 0
|
275
|
+
x = 0
|
276
|
+
y = l
|
277
|
+
else
|
278
|
+
y = l/Math::sin(radians(gamma)) * Math::sin(radians(beta))
|
279
|
+
x = y/Math::sin(radians(beta)) * Math::sin(radians(alpha))
|
280
|
+
end
|
281
|
+
elsif args[:x] || args[:y]
|
282
|
+
x = args[:x] || 0
|
283
|
+
y = args[:y] || 0
|
284
|
+
|
285
|
+
dx = @lpos[:x] - x
|
286
|
+
dy = @lpos[:y] - y
|
287
|
+
|
288
|
+
l = Math::sqrt(dx*dx + dy*dy)
|
289
|
+
alpha = Math::atan2(x, y)*180/Math::PI
|
290
|
+
else
|
291
|
+
puts "Error in line(): Please specify either :l, :x or :y"
|
292
|
+
return
|
293
|
+
end
|
294
|
+
|
295
|
+
@steps << Line.new(start_point: { x: @lpos[:x], y: @lpos[:y] }, end_point: { x: @lpos[:x] + x, y: @lpos[:y] + y }, angle: @angle, current_angle: @current_angle, direction: @direction, l: l){ new_thing }
|
296
|
+
|
297
|
+
add_lpos({x: x, y: y})
|
298
|
+
end
|
299
|
+
|
300
|
+
def add_lpos(lpos)
|
301
|
+
#puts "x: #{lpos[:x]}, y: #{lpos[:y]}"
|
302
|
+
[:x, :y].each do |key|
|
303
|
+
@lpos[key] += lpos[key]
|
304
|
+
end
|
305
|
+
@coords << lpos
|
306
|
+
end
|
307
|
+
|
308
|
+
def pos
|
309
|
+
[@lpos[:x], @lpos[:y]]
|
310
|
+
end
|
311
|
+
|
312
|
+
def center
|
313
|
+
@steps << Move.new(x: @lpos[:x] * -1, y: @lpos[:y] * -1)
|
314
|
+
self
|
315
|
+
end
|
316
|
+
|
317
|
+
def assemble
|
318
|
+
@steps.each_with_index do |step, i|
|
319
|
+
if @steps[i+1] && @steps[i+1].class == Line && step.class == RoundCorner
|
320
|
+
step.set_angles(@steps[i+1].current_angle, @steps[i+1].angle, @steps[i+1].direction)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
res = nil
|
324
|
+
@steps.each do |step|
|
325
|
+
if step.kind_of? Transformation
|
326
|
+
res.transformations << step
|
327
|
+
else
|
328
|
+
res += step.part
|
329
|
+
end
|
330
|
+
end
|
331
|
+
set_heights_for_auto_extrude([res], self)
|
332
|
+
res.transformations << @transformations
|
333
|
+
Aggregation.new(@name, res)
|
334
|
+
end
|
335
|
+
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
|
data/lib/jenncad/features.rb
CHANGED
@@ -57,6 +57,13 @@ module JennCad::Primitives
|
|
57
57
|
res
|
58
58
|
end
|
59
59
|
|
60
|
+
# Centers the cylinder around it's center point by height
|
61
|
+
# This will transform the cylinder around the center point.
|
62
|
+
def cz
|
63
|
+
@transformations << Move.new(z: -@z / 2.0)
|
64
|
+
self
|
65
|
+
end
|
66
|
+
|
60
67
|
def handle_fn
|
61
68
|
case @opts[:fn]
|
62
69
|
when nil, 0
|
@@ -43,18 +43,19 @@ module JennCad::Primitives
|
|
43
43
|
def to_openscad
|
44
44
|
return cube(@opts) if @d == 0
|
45
45
|
# make diameter not bigger than any side
|
46
|
-
|
46
|
+
d = [@d, @x, @y].min
|
47
47
|
res = HullObject.new(
|
48
|
-
cylinder(d
|
49
|
-
cylinder(d
|
50
|
-
cylinder(d
|
51
|
-
cylinder(d
|
52
|
-
).moveh(xy:
|
48
|
+
cylinder(d:d, h:z+z_margin),
|
49
|
+
cylinder(d:d).move(x: @x - d, y: 0),
|
50
|
+
cylinder(d:d).move(x: 0, y: @y - d),
|
51
|
+
cylinder(d:d).move(x: @x - d, y: @y - d),
|
52
|
+
).moveh(xy: d)
|
53
53
|
|
54
54
|
res += flat_edge(@opts[:flat_edges])
|
55
55
|
|
56
56
|
res.transformations = @transformations
|
57
57
|
res.moveh(centered_axis.to_h{|a| [a, -@opts[a]] })
|
58
|
+
res
|
58
59
|
end
|
59
60
|
|
60
61
|
def flat_edge(edge)
|
data/lib/jenncad/thing.rb
CHANGED
@@ -47,7 +47,7 @@ module JennCad
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
def movei(args)
|
50
|
+
def movei(args={})
|
51
51
|
to = {}
|
52
52
|
[:x, :y, :z].each do |key|
|
53
53
|
if args[key]
|
@@ -162,7 +162,7 @@ module JennCad
|
|
162
162
|
return args
|
163
163
|
end
|
164
164
|
|
165
|
-
def move(args)
|
165
|
+
def move(args={})
|
166
166
|
if args.kind_of? Array
|
167
167
|
x,y,z = args
|
168
168
|
return move(x:x, y:y, z:z)
|
@@ -183,20 +183,20 @@ module JennCad
|
|
183
183
|
alias :translate :move
|
184
184
|
alias :m :move
|
185
185
|
|
186
|
-
def mx(v)
|
186
|
+
def mx(v=0)
|
187
187
|
move(x:v)
|
188
188
|
end
|
189
189
|
|
190
|
-
def my(v)
|
190
|
+
def my(v=0)
|
191
191
|
move(y:v)
|
192
192
|
end
|
193
193
|
|
194
|
-
def mz(v)
|
194
|
+
def mz(v=0)
|
195
195
|
move(z:v)
|
196
196
|
end
|
197
197
|
|
198
198
|
# move half
|
199
|
-
def moveh(args)
|
199
|
+
def moveh(args={})
|
200
200
|
if args.kind_of? Array
|
201
201
|
x,y,z = args
|
202
202
|
args = {x: x, y: y, z: z}
|
@@ -209,26 +209,26 @@ module JennCad
|
|
209
209
|
end
|
210
210
|
alias :mh :moveh
|
211
211
|
|
212
|
-
def mhx(v)
|
212
|
+
def mhx(v=0)
|
213
213
|
moveh(x:v)
|
214
214
|
end
|
215
215
|
|
216
|
-
def mhy(v)
|
216
|
+
def mhy(v=0)
|
217
217
|
moveh(y:v)
|
218
218
|
end
|
219
219
|
|
220
|
-
def mhz(v)
|
220
|
+
def mhz(v=0)
|
221
221
|
moveh(z:v)
|
222
222
|
end
|
223
223
|
|
224
|
-
def mirror(args)
|
224
|
+
def mirror(args={})
|
225
225
|
@transformations ||= []
|
226
226
|
@transformations << Mirror.new(args)
|
227
227
|
self
|
228
228
|
end
|
229
229
|
alias :mi :mirror
|
230
230
|
|
231
|
-
def scale(args)
|
231
|
+
def scale(args={})
|
232
232
|
if args.kind_of? Numeric or args.kind_of? Array
|
233
233
|
args = {v:args}
|
234
234
|
end
|
data/lib/jenncad/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jenncad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.pre.
|
4
|
+
version: 1.0.0.pre.alpha9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jennifer Glauche
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-04-
|
11
|
+
date: 2022-04-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: geo3d
|
@@ -39,19 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: dry-cli
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0
|
47
|
+
version: '0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0
|
54
|
+
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: activesupport
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,6 +115,7 @@ files:
|
|
115
115
|
- lib/jenncad/features/cuttable.rb
|
116
116
|
- lib/jenncad/features/feature.rb
|
117
117
|
- lib/jenncad/features/openscad_include.rb
|
118
|
+
- lib/jenncad/features/path.rb
|
118
119
|
- lib/jenncad/features/stl_import.rb
|
119
120
|
- lib/jenncad/part.rb
|
120
121
|
- lib/jenncad/patches/array.rb
|