jenncad 1.0.0.pre.alpha4 → 1.0.0.pre.alpha8
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 +35 -11
- data/lib/jenncad/part.rb +2 -3
- data/lib/jenncad/primitives/cube.rb +26 -9
- data/lib/jenncad/primitives/cylinder.rb +7 -0
- data/lib/jenncad/primitives/linear_extrude.rb +7 -3
- data/lib/jenncad/primitives/rounded_cube.rb +12 -7
- data/lib/jenncad/primitives/subtract_object.rb +1 -0
- data/lib/jenncad/shortcuts.rb +1 -1
- data/lib/jenncad/thing.rb +107 -13
- data/lib/jenncad/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f2310cb82dee6ece32a91135d15ffe4c6d69695e4af8ed9aabd91906ce22088
|
4
|
+
data.tar.gz: b36e9d1c8f926fb2858fb017aaced7cfe363b9c7e26fa3bd071eb677bff90e3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e1877c0c6f9f7bc509b8aacc97383ed451bc50b7de61c6dafd49e2b25ec51da4b877b683ddbe0563c69c771aba4e8a543c71aee9be0708d5b08ef593b0053d23
|
7
|
+
data.tar.gz: 0a25cd07dd118d1beb5f819f3ec60262cabb9793b5867d93d642ee95e64ff2f8229d72283ad98ca6d197b79e273f4a00e4aba2c9e709dcb7c17dd7b7e4f4a6e9
|
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,8 +1,10 @@
|
|
1
|
+
require "dry/cli"
|
1
2
|
module JennCad
|
2
3
|
module Commands
|
3
|
-
extend
|
4
|
+
extend Dry::CLI::Registry
|
5
|
+
MAGIC = "jenncad-append-project-magic"
|
4
6
|
|
5
|
-
class Run <
|
7
|
+
class Run < Dry::CLI::Command
|
6
8
|
argument :name, required: false
|
7
9
|
|
8
10
|
def guess_executable(dir=Dir.pwd)
|
@@ -87,7 +89,7 @@ module JennCad
|
|
87
89
|
end
|
88
90
|
end
|
89
91
|
|
90
|
-
class NewPart <
|
92
|
+
class NewPart < Dry::CLI::Command
|
91
93
|
include ActiveSupport::Inflector
|
92
94
|
desc "creates a new part in a project"
|
93
95
|
argument :name, required: true
|
@@ -122,16 +124,40 @@ module JennCad
|
|
122
124
|
f.puts " end"
|
123
125
|
f.puts "end"
|
124
126
|
end
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
127
|
+
|
128
|
+
lines = File.readlines(executable)
|
129
|
+
magic_line = nil;
|
130
|
+
lines.each_with_index do |l, i|
|
131
|
+
if l.rindex(MAGIC)
|
132
|
+
magic_line = i
|
133
|
+
end
|
134
|
+
end
|
135
|
+
puts "part #{filename} created."
|
136
|
+
if !magic_line
|
137
|
+
puts "In your #{executable} add to class #{executable_class}:"
|
138
|
+
puts " def #{name}"
|
139
|
+
puts " #{classname}.new(config)"
|
140
|
+
puts " end"
|
141
|
+
puts ""
|
142
|
+
puts "For jenncad to insert this line automatically, add this line to your project file before the \"end\"-statement of your class:"
|
143
|
+
puts "##{MAGIC}"
|
144
|
+
else
|
145
|
+
data = "\n"
|
146
|
+
data += " def #{name}\n"
|
147
|
+
data += " #{classname}.new(config)\n"
|
148
|
+
data += " end\n"
|
149
|
+
lines.insert(magic_line, data)
|
150
|
+
f = File.open(executable, "w")
|
151
|
+
f.write(lines.join)
|
152
|
+
f.close
|
153
|
+
end
|
154
|
+
|
129
155
|
|
130
156
|
end
|
131
157
|
|
132
158
|
end
|
133
159
|
|
134
|
-
class NewProject <
|
160
|
+
class NewProject < Dry::CLI::Command
|
135
161
|
include ActiveSupport::Inflector
|
136
162
|
desc "generates a new project"
|
137
163
|
argument :name, required: true
|
@@ -152,9 +178,7 @@ module JennCad
|
|
152
178
|
f.puts " {}"
|
153
179
|
f.puts " end"
|
154
180
|
f.puts ""
|
155
|
-
f.puts "
|
156
|
-
f.puts " cube(10,10,10)"
|
157
|
-
f.puts " end"
|
181
|
+
f.puts " # #{MAGIC}"
|
158
182
|
f.puts "end"
|
159
183
|
f.puts ""
|
160
184
|
f.puts "#{classname}.new.run"
|
data/lib/jenncad/part.rb
CHANGED
@@ -2,9 +2,8 @@ module JennCad
|
|
2
2
|
# Part should be inherited from the user when making parts
|
3
3
|
class Part < Thing
|
4
4
|
|
5
|
-
def to_openscad
|
6
|
-
|
7
|
-
a = Aggregation.new(self.class.to_s, self.part) #make_openscad_compatible!(self.part))
|
5
|
+
def to_openscad
|
6
|
+
a = Aggregation.new(self.class.to_s, self.part)
|
8
7
|
a.transformations = @transformations
|
9
8
|
a.color(:auto)
|
10
9
|
a
|
@@ -2,10 +2,9 @@ module JennCad::Primitives
|
|
2
2
|
class Cube < Primitive
|
3
3
|
extend JennCad::Features::Cuttable
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
5
|
+
|
6
|
+
def feed_opts(args)
|
7
|
+
# FIXME: this doesn't seem to work
|
9
8
|
if args.kind_of? Array
|
10
9
|
m = {}
|
11
10
|
if args.last.kind_of? Hash
|
@@ -13,7 +12,13 @@ module JennCad::Primitives
|
|
13
12
|
end
|
14
13
|
args = [:x, :y, :z].zip(args.flatten).to_h
|
15
14
|
args.deep_merge!(m)
|
15
|
+
@opts.deep_merge!(args)
|
16
|
+
else
|
17
|
+
@opts.deep_merge!(args)
|
16
18
|
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(args)
|
17
22
|
@opts = {
|
18
23
|
x: 0,
|
19
24
|
y: 0,
|
@@ -27,10 +32,18 @@ module JennCad::Primitives
|
|
27
32
|
center_y: false,
|
28
33
|
center_x: false,
|
29
34
|
center_z: false,
|
30
|
-
}
|
31
|
-
|
35
|
+
}
|
36
|
+
if args.kind_of? Array
|
37
|
+
args.each do |a|
|
38
|
+
feed_opts(parse_xyz_shortcuts(a))
|
39
|
+
end
|
40
|
+
else
|
41
|
+
feed_opts(parse_xyz_shortcuts(args))
|
42
|
+
end
|
43
|
+
|
32
44
|
|
33
|
-
|
45
|
+
handle_margins
|
46
|
+
super(z: @opts[:z])
|
34
47
|
@h = @z.dup
|
35
48
|
@calc_h = @z.dup
|
36
49
|
end
|
@@ -42,30 +55,34 @@ module JennCad::Primitives
|
|
42
55
|
|
43
56
|
def not_centered
|
44
57
|
@opts[:center] = false
|
58
|
+
self
|
45
59
|
end
|
46
60
|
alias :nc :not_centered
|
47
61
|
|
48
62
|
def cx
|
49
63
|
nc
|
50
64
|
@opts[:center_x] = true
|
65
|
+
self
|
51
66
|
end
|
52
67
|
|
53
68
|
def cy
|
54
69
|
nc
|
55
70
|
@opts[:center_y] = true
|
71
|
+
self
|
56
72
|
end
|
57
73
|
|
58
74
|
def cz
|
59
75
|
nc
|
60
76
|
@opts[:center_z] = true
|
77
|
+
self
|
61
78
|
end
|
62
79
|
|
63
80
|
def centered_axis
|
64
81
|
return [:x, :y] if @opts[:center]
|
65
82
|
a = []
|
66
83
|
a << :x if @opts[:center_x]
|
67
|
-
a << :y if @opts[:
|
68
|
-
a << :z if @opts[:
|
84
|
+
a << :y if @opts[:center_y]
|
85
|
+
a << :z if @opts[:center_z]
|
69
86
|
a
|
70
87
|
end
|
71
88
|
|
@@ -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
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module JennCad::Primitives
|
2
|
-
attr_accessor :center_bool, :convexity, :twist, :slices
|
2
|
+
attr_accessor :center_bool, :convexity, :twist, :slices
|
3
3
|
class LinearExtrude < JennCad::Thing
|
4
|
-
def initialize(part, args)
|
4
|
+
def initialize(part, args={})
|
5
5
|
@transformations = []
|
6
6
|
@parts = [part]
|
7
|
-
@
|
7
|
+
@z = args[:h] || args[:height]
|
8
8
|
@center_bool = args[:center]
|
9
9
|
@convexity = args[:convexity]
|
10
10
|
@twist = args[:twist]
|
@@ -12,6 +12,10 @@ module JennCad::Primitives
|
|
12
12
|
@fn = args[:fn]
|
13
13
|
end
|
14
14
|
|
15
|
+
def height
|
16
|
+
@z
|
17
|
+
end
|
18
|
+
|
15
19
|
def openscad_params
|
16
20
|
res = {}
|
17
21
|
[:height, :convexity, :twist, :slices, :fn].each do |n|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module JennCad::Primitives
|
2
|
-
class RoundedCube <
|
2
|
+
class RoundedCube < Cube
|
3
3
|
attr_accessor :d, :r
|
4
4
|
include JennCad::Features::Cuttable
|
5
5
|
|
@@ -23,6 +23,10 @@ module JennCad::Primitives
|
|
23
23
|
z: nil,
|
24
24
|
r: nil,
|
25
25
|
flat_edges: nil,
|
26
|
+
center: true,
|
27
|
+
center_y: false,
|
28
|
+
center_x: false,
|
29
|
+
center_z: false,
|
26
30
|
margins: {
|
27
31
|
r: 0,
|
28
32
|
d: 0,
|
@@ -39,17 +43,18 @@ module JennCad::Primitives
|
|
39
43
|
def to_openscad
|
40
44
|
return cube(@opts) if @d == 0
|
41
45
|
# make diameter not bigger than any side
|
42
|
-
|
46
|
+
d = [@d, @x, @y].min
|
43
47
|
res = HullObject.new(
|
44
|
-
cylinder(d
|
45
|
-
cylinder(d
|
46
|
-
cylinder(d
|
47
|
-
cylinder(d
|
48
|
-
)
|
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)
|
49
53
|
|
50
54
|
res += flat_edge(@opts[:flat_edges])
|
51
55
|
|
52
56
|
res.transformations = @transformations
|
57
|
+
res.moveh(centered_axis.to_h{|a| [a, -@opts[a]] })
|
53
58
|
res
|
54
59
|
end
|
55
60
|
|
data/lib/jenncad/shortcuts.rb
CHANGED
data/lib/jenncad/thing.rb
CHANGED
@@ -7,6 +7,7 @@ module JennCad
|
|
7
7
|
attr_accessor :calc_x, :calc_y, :calc_z, :calc_h
|
8
8
|
attr_accessor :shape
|
9
9
|
attr_accessor :angle, :fn
|
10
|
+
attr_accessor :anchor
|
10
11
|
|
11
12
|
def initialize(args={})
|
12
13
|
@transformations = []
|
@@ -28,6 +29,41 @@ module JennCad
|
|
28
29
|
@opts[key] = val
|
29
30
|
end
|
30
31
|
|
32
|
+
def set_anchor(args)
|
33
|
+
self.anchor ||= {}
|
34
|
+
args.each do |key, val|
|
35
|
+
self.anchor[key] = val
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def movea(key)
|
40
|
+
a = self.anchor[key]
|
41
|
+
unless a
|
42
|
+
puts "Error: Anchor #{key} not found"
|
43
|
+
puts "Available anchor: #{self.anchor}"
|
44
|
+
return self
|
45
|
+
else
|
46
|
+
self.movei(a)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def movei(args)
|
51
|
+
to = {}
|
52
|
+
[:x, :y, :z].each do |key|
|
53
|
+
if args[key]
|
54
|
+
to[key] = args[key]*-1
|
55
|
+
end
|
56
|
+
end
|
57
|
+
move(to)
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def auto_extrude
|
62
|
+
ret = self.extrude
|
63
|
+
ret.set_option(:auto_extrude, true)
|
64
|
+
ret
|
65
|
+
end
|
66
|
+
|
31
67
|
def rotate(args)
|
32
68
|
@transformations ||= []
|
33
69
|
@transformations << Rotate.new(args)
|
@@ -96,17 +132,43 @@ module JennCad
|
|
96
132
|
[v.x,v.y,v.z]
|
97
133
|
end
|
98
134
|
|
99
|
-
# todo: check if that works
|
100
135
|
def rotate_around(point,args)
|
101
|
-
x,y,z= point
|
136
|
+
x,y,z= point[:x], point[:y], point[:z]
|
102
137
|
self.move(x:-x,y:-y,z:-z).rotate(args).move(x:x,y:y,z:z)
|
103
138
|
end
|
104
139
|
|
140
|
+
def parse_xyz_shortcuts(args)
|
141
|
+
[:x, :y, :z].each do |key|
|
142
|
+
args[key] ||= 0.0
|
143
|
+
end
|
144
|
+
|
145
|
+
if args[:xy]
|
146
|
+
args[:x] += args[:xy]
|
147
|
+
args[:y] += args[:xy]
|
148
|
+
end
|
149
|
+
if args[:xyz]
|
150
|
+
args[:x] += args[:xyz]
|
151
|
+
args[:y] += args[:xyz]
|
152
|
+
args[:z] += args[:xyz]
|
153
|
+
end
|
154
|
+
if args[:xz]
|
155
|
+
args[:x] += args[:xz]
|
156
|
+
args[:z] += args[:xz]
|
157
|
+
end
|
158
|
+
if args[:yz]
|
159
|
+
args[:y] += args[:yz]
|
160
|
+
args[:z] += args[:yz]
|
161
|
+
end
|
162
|
+
return args
|
163
|
+
end
|
164
|
+
|
105
165
|
def move(args)
|
106
166
|
if args.kind_of? Array
|
107
167
|
x,y,z = args
|
108
168
|
return move(x:x, y:y, z:z)
|
109
169
|
end
|
170
|
+
args = parse_xyz_shortcuts(args)
|
171
|
+
|
110
172
|
@transformations ||= []
|
111
173
|
if args[:prepend]
|
112
174
|
@transformations.prepend(Move.new(args))
|
@@ -139,9 +201,9 @@ module JennCad
|
|
139
201
|
x,y,z = args
|
140
202
|
args = {x: x, y: y, z: z}
|
141
203
|
end
|
142
|
-
|
143
|
-
|
144
|
-
|
204
|
+
[:x, :y, :z, :xy, :xyz, :xz, :yz].each do |key|
|
205
|
+
args[key] = args[key] / 2.0 unless args[key] == nil
|
206
|
+
end
|
145
207
|
|
146
208
|
move(args)
|
147
209
|
end
|
@@ -228,8 +290,7 @@ module JennCad
|
|
228
290
|
end
|
229
291
|
res
|
230
292
|
end
|
231
|
-
|
232
|
-
def make_openscad_compatible
|
293
|
+
=begin def make_openscad_compatible
|
233
294
|
make_openscad_compatible!(self)
|
234
295
|
end
|
235
296
|
|
@@ -250,6 +311,7 @@ module JennCad
|
|
250
311
|
end
|
251
312
|
item
|
252
313
|
end
|
314
|
+
=end
|
253
315
|
|
254
316
|
def has_explicit_color?
|
255
317
|
if option(:auto_color) == false
|
@@ -307,11 +369,11 @@ module JennCad
|
|
307
369
|
ac = auto_color
|
308
370
|
unless ac.nil?
|
309
371
|
#puts "auto color to #{ac}"
|
310
|
-
if only_color?(
|
372
|
+
if only_color?(get_contents)
|
311
373
|
set_option :color, ac
|
312
374
|
set_option :auto_color, true
|
313
375
|
else
|
314
|
-
set_auto_color_for_children(ac,
|
376
|
+
set_auto_color_for_children(ac, get_contents)
|
315
377
|
end
|
316
378
|
|
317
379
|
end
|
@@ -361,12 +423,44 @@ module JennCad
|
|
361
423
|
option(:color)
|
362
424
|
end
|
363
425
|
|
364
|
-
def
|
365
|
-
|
366
|
-
|
367
|
-
|
426
|
+
def get_contents
|
427
|
+
return @parts unless @parts.nil?
|
428
|
+
if self.respond_to? :part
|
429
|
+
return [part]
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
def calculated_h
|
434
|
+
return @z unless @z.nil? || @z == 0
|
435
|
+
return @h unless @h.nil? || @h == 0
|
436
|
+
return @calc_h unless @calc_h.nil? || @calc_h == 0
|
437
|
+
return @calc_z unless @calc_z.nil? || @calc_z == 0
|
438
|
+
end
|
439
|
+
|
440
|
+
def find_calculated_h(parts)
|
441
|
+
return if parts == nil
|
442
|
+
parts.each do |part|
|
443
|
+
if z = calculated_h
|
444
|
+
return z
|
445
|
+
end
|
446
|
+
get_calculated_h(part.get_contents)
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
def set_heights_for_auto_extrude(parts, parent=nil)
|
451
|
+
return if parts.nil?
|
452
|
+
parts.each do |part|
|
453
|
+
if part.option(:auto_extrude)
|
454
|
+
part.z = parent.calculated_h
|
368
455
|
end
|
456
|
+
set_heights_for_auto_extrude(part.get_contents, part)
|
369
457
|
end
|
458
|
+
end
|
459
|
+
|
460
|
+
def openscad(file)
|
461
|
+
set_heights_for_auto_extrude(get_contents)
|
462
|
+
|
463
|
+
@parts = get_contents
|
370
464
|
|
371
465
|
JennCad::Exporters::OpenScad.new(self).save(file)
|
372
466
|
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.alpha8
|
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-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: geo3d
|
@@ -39,7 +39,7 @@ 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
|
- - ">="
|