jenncad 1.0.0.pre.alpha3 → 1.0.0.pre.alpha7
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 +4 -4
- data/README.md +83 -0
- data/bin/jenncad +1 -1
- data/jenncad.gemspec +1 -1
- data/lib/jenncad/commands.rb +34 -11
- data/lib/jenncad/exporters/openscad.rb +13 -3
- data/lib/jenncad/features/aggregation.rb +6 -2
- data/lib/jenncad/features/stl_import.rb +10 -0
- data/lib/jenncad/features.rb +2 -0
- data/lib/jenncad/part.rb +3 -4
- data/lib/jenncad/primitives/cube.rb +26 -9
- data/lib/jenncad/primitives/cylinder.rb +29 -1
- data/lib/jenncad/primitives/linear_extrude.rb +7 -3
- data/lib/jenncad/primitives/rotate_extrude.rb +1 -1
- data/lib/jenncad/primitives/rounded_cube.rb +11 -7
- data/lib/jenncad/primitives/subtract_object.rb +1 -0
- data/lib/jenncad/shortcuts.rb +5 -1
- data/lib/jenncad/thing.rb +190 -25
- data/lib/jenncad/version.rb +1 -1
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59b41052c4c676ae59a808744715a5e10b1c1086350d4c7769b87d054f51d171
|
4
|
+
data.tar.gz: a620928785ad237699d0afff433912a8b5c5f6d765492d4d1f72d4d4d83fb962
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2118f2cff401f4874c6dda0f801cfda1666e0b032158e088ff83ecf24072654a7545fc4ecd9e245398d2de2497f7b363a7a2fe4db90856d87a9a2a60ff39816b
|
7
|
+
data.tar.gz: dd82a60377991ec146d6d9c259e19df75ee752b25eb1b44ed5cc2b33aea3f7b791726dd8ee12182ac323ad7902f75da5b8d5127858efa235d4792ac0755fa52e
|
data/README.md
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
|
2
|
+
# jenncad
|
3
|
+
Create physical objects in Ruby, OpenScad export
|
4
|
+
|
5
|
+
This is a successor to my older project CrystalScad.
|
6
|
+
|
7
|
+
# Installation
|
8
|
+
|
9
|
+
A packaged release is not yet available, please build your own package in the meantime:
|
10
|
+
|
11
|
+
$ git clone git@github.com:jglauche/jenncad.git
|
12
|
+
$ cd jenncad
|
13
|
+
$ rake install
|
14
|
+
|
15
|
+
This will create a gem and a binary jenncad.
|
16
|
+
|
17
|
+
# Using Jenncad
|
18
|
+
|
19
|
+
**To create a new project directory, run:**
|
20
|
+
|
21
|
+
$ jenncad create meow
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
This will generate a directory meow/ and an executable ruby file meow.rb in its directory
|
27
|
+
|
28
|
+
$ cd meow
|
29
|
+
$ ./meow
|
30
|
+
|
31
|
+
This will generate a dummy project which generates a dummy cube as OpenSCAD output:
|
32
|
+
|
33
|
+
$ cat output/meow.scad
|
34
|
+
> $fn=64;
|
35
|
+
> translate([-5, -5, 0])cube([10, 10, 10.0]);
|
36
|
+
|
37
|
+
**Automatically refresh OpenSCAD output while developing**
|
38
|
+
|
39
|
+
Jenncad bundles the observr gem which will check if files were changed while developing. In the project directory run:
|
40
|
+
|
41
|
+
$ jenncad
|
42
|
+
This should display something like:
|
43
|
+
> refreshing...
|
44
|
+
> ok
|
45
|
+
> JennCad running, refreshing on file changes. Press ctrl+c to exit
|
46
|
+
|
47
|
+
**Note:** This does not check for new files in the project. You will have to restart it when you create a new part in a new file
|
48
|
+
|
49
|
+
**Create new part**
|
50
|
+
|
51
|
+
In your project directory, run:
|
52
|
+
|
53
|
+
$ jenncad new cat
|
54
|
+
part parts/cat.rb created. In your meow.rb add to class Meow:
|
55
|
+
def cat
|
56
|
+
Cat.new(config)
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
You will have to link the part to the project manually into the meow.rb file in your project directory. When you add it, your meow.rb should look like this:
|
61
|
+
|
62
|
+
#!/usr/bin/env ruby
|
63
|
+
require "jenncad"
|
64
|
+
include JennCad
|
65
|
+
|
66
|
+
class Meow < Project
|
67
|
+
def config
|
68
|
+
{}
|
69
|
+
end
|
70
|
+
|
71
|
+
def meow
|
72
|
+
cube(10,10,10)
|
73
|
+
end
|
74
|
+
|
75
|
+
def cat
|
76
|
+
Cat.new(config)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
Meow.new.run
|
81
|
+
|
82
|
+
|
83
|
+
|
data/bin/jenncad
CHANGED
@@ -7,4 +7,4 @@ JennCad::Commands.register "build", JennCad::Commands::Build
|
|
7
7
|
JennCad::Commands.register "new", JennCad::Commands::NewPart
|
8
8
|
JennCad::Commands.register "create", JennCad::Commands::NewProject
|
9
9
|
|
10
|
-
|
10
|
+
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,9 @@
|
|
1
1
|
module JennCad
|
2
2
|
module Commands
|
3
|
-
extend
|
3
|
+
extend Dry::CLI::Registry
|
4
|
+
MAGIC = "jenncad-append-project-magic"
|
4
5
|
|
5
|
-
class Run <
|
6
|
+
class Run < Dry::CLI::Command
|
6
7
|
argument :name, required: false
|
7
8
|
|
8
9
|
def guess_executable(dir=Dir.pwd)
|
@@ -87,7 +88,7 @@ module JennCad
|
|
87
88
|
end
|
88
89
|
end
|
89
90
|
|
90
|
-
class NewPart <
|
91
|
+
class NewPart < Dry::CLI::Command
|
91
92
|
include ActiveSupport::Inflector
|
92
93
|
desc "creates a new part in a project"
|
93
94
|
argument :name, required: true
|
@@ -122,16 +123,40 @@ module JennCad
|
|
122
123
|
f.puts " end"
|
123
124
|
f.puts "end"
|
124
125
|
end
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
126
|
+
|
127
|
+
lines = File.readlines(executable)
|
128
|
+
magic_line = nil;
|
129
|
+
lines.each_with_index do |l, i|
|
130
|
+
if l.rindex(MAGIC)
|
131
|
+
magic_line = i
|
132
|
+
end
|
133
|
+
end
|
134
|
+
puts "part #{filename} created."
|
135
|
+
if !magic_line
|
136
|
+
puts "In your #{executable} add to class #{executable_class}:"
|
137
|
+
puts " def #{name}"
|
138
|
+
puts " #{classname}.new(config)"
|
139
|
+
puts " end"
|
140
|
+
puts ""
|
141
|
+
puts "For jenncad to insert this line automatically, add this line to your project file before the \"end\"-statement of your class:"
|
142
|
+
puts "##{MAGIC}"
|
143
|
+
else
|
144
|
+
data = "\n"
|
145
|
+
data += " def #{name}\n"
|
146
|
+
data += " #{classname}.new(config)\n"
|
147
|
+
data += " end\n"
|
148
|
+
lines.insert(magic_line, data)
|
149
|
+
f = File.open(executable, "w")
|
150
|
+
f.write(lines.join)
|
151
|
+
f.close
|
152
|
+
end
|
153
|
+
|
129
154
|
|
130
155
|
end
|
131
156
|
|
132
157
|
end
|
133
158
|
|
134
|
-
class NewProject <
|
159
|
+
class NewProject < Dry::CLI::Command
|
135
160
|
include ActiveSupport::Inflector
|
136
161
|
desc "generates a new project"
|
137
162
|
argument :name, required: true
|
@@ -152,9 +177,7 @@ module JennCad
|
|
152
177
|
f.puts " {}"
|
153
178
|
f.puts " end"
|
154
179
|
f.puts ""
|
155
|
-
f.puts "
|
156
|
-
f.puts " cube(10,10,10)"
|
157
|
-
f.puts " end"
|
180
|
+
f.puts " # #{MAGIC}"
|
158
181
|
f.puts "end"
|
159
182
|
f.puts ""
|
160
183
|
f.puts "#{classname}.new.run"
|
@@ -94,7 +94,12 @@ module JennCad::Exporters
|
|
94
94
|
if !v.kind_of?(Array) && !v.kind_of?(TrueClass) && !v.kind_of?(FalseClass) && v == v.to_i
|
95
95
|
v = v.to_i
|
96
96
|
end
|
97
|
-
|
97
|
+
if v.kind_of? String
|
98
|
+
q = "\""
|
99
|
+
else
|
100
|
+
q = ""
|
101
|
+
end
|
102
|
+
res << "#{k}=#{q}#{v}#{q}"
|
98
103
|
end
|
99
104
|
res.join(",").gsub("size=","")
|
100
105
|
else
|
@@ -165,6 +170,8 @@ module JennCad::Exporters
|
|
165
170
|
new_obj(part, :projection, collect_params(part), parse(part.parts))
|
166
171
|
when JennCad::Primitives::Polygon
|
167
172
|
new_obj(part, :polygon, collect_params(part))
|
173
|
+
when JennCad::StlImport
|
174
|
+
new_obj(part, :import, collect_params(part))
|
168
175
|
when JennCad::Part
|
169
176
|
parse(part.part)
|
170
177
|
when nil
|
@@ -192,8 +199,11 @@ module JennCad::Exporters
|
|
192
199
|
end
|
193
200
|
|
194
201
|
def collect_params(part)
|
202
|
+
if part.respond_to? :openscad_params
|
203
|
+
return part.openscad_params
|
204
|
+
end
|
195
205
|
res = {}
|
196
|
-
[:d, :h, :d1, :d2, :size, :fn, :points].each do |var|
|
206
|
+
[:d, :h, :d1, :d2, :size, :fn, :points, :file].each do |var|
|
197
207
|
if part.respond_to? var
|
198
208
|
res[var] = part.send var
|
199
209
|
end
|
@@ -239,7 +249,7 @@ module JennCad::Exporters
|
|
239
249
|
|
240
250
|
# accept aggregation
|
241
251
|
def register_module(part)
|
242
|
-
@modules[part.name] = OpenScadObject.new(:module,part.name, parse(part.part))
|
252
|
+
@modules[part.name] = OpenScadObject.new(:module, part.name, parse(part.part))
|
243
253
|
end
|
244
254
|
|
245
255
|
def handle_import(part)
|
@@ -1,11 +1,15 @@
|
|
1
1
|
module JennCad::Features
|
2
2
|
class Aggregation < Feature
|
3
|
-
attr_accessor :
|
3
|
+
attr_accessor :parts
|
4
4
|
|
5
5
|
def initialize(name=nil, part=nil)
|
6
6
|
super({})
|
7
7
|
@name = name
|
8
|
-
@
|
8
|
+
@parts = [part] # NOTE: single length arrayto make checking children easier
|
9
|
+
end
|
10
|
+
|
11
|
+
def part
|
12
|
+
@parts.first
|
9
13
|
end
|
10
14
|
|
11
15
|
end
|
data/lib/jenncad/features.rb
CHANGED
data/lib/jenncad/part.rb
CHANGED
@@ -2,11 +2,10 @@ 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
|
-
a.color(
|
8
|
+
a.color(:auto)
|
10
9
|
a
|
11
10
|
end
|
12
11
|
|
@@ -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
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module JennCad::Primitives
|
2
2
|
class Cylinder < Primitive
|
3
|
-
attr_accessor :d, :r, :fn
|
3
|
+
attr_accessor :d, :d1, :d2, :r, :fn
|
4
4
|
def initialize(args)
|
5
5
|
if args.kind_of?(Array) && args[0].kind_of?(Hash)
|
6
6
|
args = args.first
|
@@ -43,6 +43,20 @@ module JennCad::Primitives
|
|
43
43
|
super(args)
|
44
44
|
end
|
45
45
|
|
46
|
+
def openscad_params
|
47
|
+
res = {}
|
48
|
+
if @opts[:d1]
|
49
|
+
[:d1, :d2, :h, :fn].each do |n|
|
50
|
+
res[n] = self.send n
|
51
|
+
end
|
52
|
+
else
|
53
|
+
[:d, :h, :fn].each do |n|
|
54
|
+
res[n] = self.send n
|
55
|
+
end
|
56
|
+
end
|
57
|
+
res
|
58
|
+
end
|
59
|
+
|
46
60
|
def handle_fn
|
47
61
|
case @opts[:fn]
|
48
62
|
when nil, 0
|
@@ -70,6 +84,20 @@ module JennCad::Primitives
|
|
70
84
|
@d = @opts[:d].to_f + @opts[:margins][:d].to_f
|
71
85
|
@r = @d / 2.0
|
72
86
|
end
|
87
|
+
|
88
|
+
case @opts[:d1]
|
89
|
+
when 0, nil
|
90
|
+
else
|
91
|
+
@d1 = @opts[:d1].to_f + @opts[:margins][:d].to_f
|
92
|
+
@d2 = @opts[:d2].to_f + @opts[:margins][:d].to_f
|
93
|
+
end
|
94
|
+
|
95
|
+
case @opts[:r1]
|
96
|
+
when 0, nil
|
97
|
+
else
|
98
|
+
@d1 = 2 * @opts[:r1].to_f + @opts[:margins][:d].to_f
|
99
|
+
@d2 = 2 * @opts[:r2].to_f + @opts[:margins][:d].to_f
|
100
|
+
end
|
73
101
|
end
|
74
102
|
|
75
103
|
def h
|
@@ -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,
|
@@ -41,16 +45,16 @@ module JennCad::Primitives
|
|
41
45
|
# make diameter not bigger than any side
|
42
46
|
@d = [@d, @x, @y].min
|
43
47
|
res = HullObject.new(
|
44
|
-
cylinder(d:@d, h:z+z_margin)
|
45
|
-
cylinder(d:@d).
|
46
|
-
cylinder(d:@d).
|
47
|
-
cylinder(d:@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
|
53
|
-
res
|
57
|
+
res.moveh(centered_axis.to_h{|a| [a, -@opts[a]] })
|
54
58
|
end
|
55
59
|
|
56
60
|
def flat_edge(edge)
|
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,39 +311,111 @@ module JennCad
|
|
250
311
|
end
|
251
312
|
item
|
252
313
|
end
|
314
|
+
=end
|
315
|
+
|
316
|
+
def has_explicit_color?
|
317
|
+
if option(:auto_color) == false
|
318
|
+
return true
|
319
|
+
end
|
320
|
+
return false
|
321
|
+
end
|
322
|
+
|
323
|
+
def only_color?(parts, lvl=0)
|
324
|
+
return true if parts == nil
|
325
|
+
|
326
|
+
parts.each do |part|
|
327
|
+
# puts " " * lvl + "[only_color?] #{part}"
|
328
|
+
if part.has_explicit_color?
|
329
|
+
# puts " " * lvl + "found explicit color here"
|
330
|
+
return false
|
331
|
+
end
|
332
|
+
if !only_color?(part.parts, lvl+1)
|
333
|
+
return false
|
334
|
+
end
|
335
|
+
end
|
336
|
+
true
|
337
|
+
end
|
338
|
+
|
339
|
+
def set_auto_color_for_children(col, parts, lvl=0)
|
340
|
+
return if parts == nil
|
341
|
+
|
342
|
+
parts.each do |part|
|
343
|
+
unless part.has_explicit_color?
|
344
|
+
if only_color?(part.parts, lvl+1)
|
345
|
+
# puts " " * lvl + "children have no explicit color, setting it here"
|
346
|
+
part.set_auto_color(col)
|
347
|
+
else
|
348
|
+
# puts " " * lvl + "[set_auto_color_for_children] #{part}"
|
349
|
+
set_auto_color_for_children(col, part.parts, lvl+1)
|
350
|
+
end
|
351
|
+
else
|
352
|
+
# puts " " * lvl + "[set_auto_color_for_children] this part has a color, ignoring their children"
|
353
|
+
end
|
354
|
+
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
def set_auto_color(col)
|
359
|
+
set_option :color, col
|
360
|
+
set_option :auto_color, true
|
361
|
+
end
|
253
362
|
|
254
363
|
def color(args=nil)
|
255
|
-
|
256
|
-
when nil
|
364
|
+
if args == nil
|
257
365
|
return option(:color)
|
258
|
-
|
259
|
-
|
366
|
+
end
|
367
|
+
|
368
|
+
if args == :auto
|
369
|
+
ac = auto_color
|
370
|
+
unless ac.nil?
|
371
|
+
#puts "auto color to #{ac}"
|
372
|
+
if only_color?(get_contents)
|
373
|
+
set_option :color, ac
|
374
|
+
set_option :auto_color, true
|
375
|
+
else
|
376
|
+
set_auto_color_for_children(ac, get_contents)
|
377
|
+
end
|
378
|
+
|
379
|
+
end
|
380
|
+
return self
|
381
|
+
end
|
382
|
+
|
383
|
+
c = color_parse(args)
|
384
|
+
unless c.nil?
|
385
|
+
set_option :color, c
|
386
|
+
set_option :auto_color, false
|
387
|
+
end
|
388
|
+
|
389
|
+
self
|
390
|
+
end
|
391
|
+
|
392
|
+
def color_parse(args=nil)
|
393
|
+
case args
|
260
394
|
when :none
|
261
395
|
set_option :no_auto_color, true
|
262
396
|
when :random
|
263
|
-
|
397
|
+
return Color.random
|
264
398
|
when Array
|
265
|
-
|
399
|
+
return Color.parse(args)
|
266
400
|
when /(?<=#)(?<!^)(\h{6}|\h{3})/
|
267
|
-
|
401
|
+
return args
|
268
402
|
when /(?<!^)(\h{6}|\h{3})/
|
269
|
-
|
403
|
+
return "##{args}"
|
270
404
|
when String
|
271
|
-
|
272
|
-
else
|
273
|
-
puts "meow"
|
405
|
+
return args
|
274
406
|
end
|
275
|
-
|
407
|
+
nil
|
276
408
|
end
|
277
409
|
|
278
410
|
def auto_color
|
279
411
|
if option(:color) == nil && !option(:no_auto_color)
|
280
|
-
auto_color!
|
412
|
+
return auto_color!
|
281
413
|
end
|
414
|
+
nil
|
282
415
|
end
|
283
416
|
|
284
417
|
def auto_color!
|
285
|
-
|
418
|
+
color_parse($jenncad_profile.colors.pop)
|
286
419
|
end
|
287
420
|
|
288
421
|
def color_or_fallback
|
@@ -290,12 +423,44 @@ module JennCad
|
|
290
423
|
option(:color)
|
291
424
|
end
|
292
425
|
|
293
|
-
def
|
294
|
-
|
295
|
-
|
296
|
-
|
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
|
297
455
|
end
|
456
|
+
set_heights_for_auto_extrude(part.get_contents, part)
|
298
457
|
end
|
458
|
+
end
|
459
|
+
|
460
|
+
def openscad(file)
|
461
|
+
set_heights_for_auto_extrude(get_contents)
|
462
|
+
|
463
|
+
@parts = get_contents
|
299
464
|
|
300
465
|
JennCad::Exporters::OpenScad.new(self).save(file)
|
301
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.alpha7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jennifer Glauche
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-22 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
|
- - ">="
|
@@ -88,6 +88,7 @@ executables:
|
|
88
88
|
extensions: []
|
89
89
|
extra_rdoc_files: []
|
90
90
|
files:
|
91
|
+
- README.md
|
91
92
|
- Rakefile
|
92
93
|
- bin/jenncad
|
93
94
|
- examples/old/cube.rb
|
@@ -114,6 +115,7 @@ files:
|
|
114
115
|
- lib/jenncad/features/cuttable.rb
|
115
116
|
- lib/jenncad/features/feature.rb
|
116
117
|
- lib/jenncad/features/openscad_include.rb
|
118
|
+
- lib/jenncad/features/stl_import.rb
|
117
119
|
- lib/jenncad/part.rb
|
118
120
|
- lib/jenncad/patches/array.rb
|
119
121
|
- lib/jenncad/primitives.rb
|
@@ -151,7 +153,7 @@ homepage: ''
|
|
151
153
|
licenses:
|
152
154
|
- LGPL-3
|
153
155
|
metadata: {}
|
154
|
-
post_install_message:
|
156
|
+
post_install_message:
|
155
157
|
rdoc_options: []
|
156
158
|
require_paths:
|
157
159
|
- lib
|
@@ -166,8 +168,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
168
|
- !ruby/object:Gem::Version
|
167
169
|
version: 1.3.1
|
168
170
|
requirements: []
|
169
|
-
rubygems_version: 3.
|
170
|
-
signing_key:
|
171
|
+
rubygems_version: 3.2.3
|
172
|
+
signing_key:
|
171
173
|
specification_version: 4
|
172
174
|
summary: TBD
|
173
175
|
test_files: []
|