jenncad 1.0.0.pre.alpha10 → 1.0.0.pre.alpha13
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/lib/jenncad/exporters/openscad.rb +10 -6
- data/lib/jenncad/features/aggregation.rb +1 -1
- data/lib/jenncad/part.rb +6 -2
- data/lib/jenncad/primitives/boolean_object.rb +11 -0
- data/lib/jenncad/primitives/cube.rb +69 -4
- data/lib/jenncad/primitives/slot.rb +16 -1
- data/lib/jenncad/primitives/subtract_object.rb +8 -2
- data/lib/jenncad/shortcuts.rb +6 -1
- data/lib/jenncad/thing.rb +66 -35
- data/lib/jenncad/version.rb +1 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c4383fe5f1fe2d17d69eccd66bd28db4678281fd542bd13434064d4051044727
|
4
|
+
data.tar.gz: 0eb4435e845c47ec9b75d113c04b7beae9ce762a2dfa57b598412a243ded0163
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35001c199911e59f66a2ef3ce3b8c6193e5654ebc5463f52add3cb11a5aa3c1684c51dbaad7a3edaf4c0042cf2b2d35410ea01bfdce45e5adc72a96f30ec002b
|
7
|
+
data.tar.gz: 163e8e50aa1dd6ba930fd41e93075aca9f8bed93c6650f3a9984fbc86ddb34f0ae4a499d7fc981a38dfe9bdb1f56a0667a4cec018a530b701f4707141d79233c
|
@@ -1,8 +1,10 @@
|
|
1
1
|
module JennCad::Exporters
|
2
2
|
class OpenScadObject
|
3
|
-
def initialize(cmd, args, children=[])
|
3
|
+
def initialize(cmd, args, children=[], modifier=nil)
|
4
4
|
@command = cmd
|
5
5
|
@args = args
|
6
|
+
@modifier = modifier || ""
|
7
|
+
|
6
8
|
case children
|
7
9
|
when Array
|
8
10
|
@children = children
|
@@ -43,11 +45,11 @@ module JennCad::Exporters
|
|
43
45
|
def handle_command(i=1)
|
44
46
|
case @children.size
|
45
47
|
when 0
|
46
|
-
"#{@command}(#{handle_args});"
|
48
|
+
"#{@modifier}#{@command}(#{handle_args});"
|
47
49
|
when 1
|
48
|
-
"#{@command}(#{handle_args})#{@children.first.handle_command(i+1)}"
|
50
|
+
"#{@modifier}#{@command}(#{handle_args})#{@children.first.handle_command(i+1)}"
|
49
51
|
when (1..)
|
50
|
-
res = "#{@command}(#{handle_args}){"
|
52
|
+
res = "#{@modifier}#{@command}(#{handle_args}){"
|
51
53
|
res += nl
|
52
54
|
inner = @children.map do |c|
|
53
55
|
next if c == nil
|
@@ -185,7 +187,8 @@ module JennCad::Exporters
|
|
185
187
|
def new_obj(part, cmd, args=nil, children=[])
|
186
188
|
transform(part) do
|
187
189
|
apply_color(part) do
|
188
|
-
|
190
|
+
modifier = part.openscad_modifier || nil
|
191
|
+
OpenScadObject.new(cmd, args, children, modifier)
|
189
192
|
end
|
190
193
|
end
|
191
194
|
end
|
@@ -242,7 +245,8 @@ module JennCad::Exporters
|
|
242
245
|
|
243
246
|
def handle_aggregation(part, tabindex=0)
|
244
247
|
register_module(part) unless @modules[part.name]
|
245
|
-
|
248
|
+
$log.debug "aggregation #{part.name} transformations: #{part.transformations.inspect}" if part && part.option(:debug)
|
249
|
+
transform(part.clone) do
|
246
250
|
new_obj(part, part.name, nil)
|
247
251
|
end
|
248
252
|
end
|
data/lib/jenncad/part.rb
CHANGED
@@ -3,9 +3,13 @@ module JennCad
|
|
3
3
|
class Part < Thing
|
4
4
|
|
5
5
|
def to_openscad
|
6
|
-
a = Aggregation.new(self.class.to_s, self.
|
6
|
+
a = Aggregation.new(self.class.to_s, self.get_contents)
|
7
7
|
a.transformations = @transformations
|
8
|
-
|
8
|
+
if self.has_explicit_color?
|
9
|
+
a.color(self.color)
|
10
|
+
else
|
11
|
+
a.color(:auto)
|
12
|
+
end
|
9
13
|
a
|
10
14
|
end
|
11
15
|
|
@@ -7,6 +7,7 @@ module JennCad::Primitives
|
|
7
7
|
else
|
8
8
|
@parts = parts
|
9
9
|
end
|
10
|
+
|
10
11
|
@parent = @parts.first.parent
|
11
12
|
|
12
13
|
after_add
|
@@ -23,6 +24,7 @@ module JennCad::Primitives
|
|
23
24
|
end
|
24
25
|
|
25
26
|
def add(part)
|
27
|
+
return if part.nil?
|
26
28
|
@parts << part
|
27
29
|
after_add
|
28
30
|
end
|
@@ -30,10 +32,17 @@ module JennCad::Primitives
|
|
30
32
|
def after_add
|
31
33
|
@parts.flatten!
|
32
34
|
@parts.compact!
|
35
|
+
inherit_debug
|
33
36
|
inherit_z
|
34
37
|
inherit_zref
|
35
38
|
end
|
36
39
|
|
40
|
+
def inherit_debug
|
41
|
+
if @parts.map{|l| l.option(:debug)}.include? true
|
42
|
+
set_option(:debug, true)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
37
46
|
def inherit_z
|
38
47
|
heights = @parts.map{|l| l.calc_z.to_f}.uniq
|
39
48
|
if heights.size > 1
|
@@ -77,6 +86,8 @@ module JennCad::Primitives
|
|
77
86
|
when Array
|
78
87
|
res << obj.map{|l| only_additives_of(l)}
|
79
88
|
when SubtractObject
|
89
|
+
# include the thing that something was subtracted from to get the Z height if that is behind another layer of SubtractObject
|
90
|
+
res << only_additives_of(obj.parts.first)
|
80
91
|
when IntersectionObject
|
81
92
|
else
|
82
93
|
res << obj
|
@@ -2,6 +2,7 @@ module JennCad::Primitives
|
|
2
2
|
class Cube < Primitive
|
3
3
|
extend JennCad::Features::Cuttable
|
4
4
|
|
5
|
+
attr_accessor :corners, :sides
|
5
6
|
|
6
7
|
def feed_opts(args)
|
7
8
|
# FIXME: this doesn't seem to work
|
@@ -47,6 +48,7 @@ module JennCad::Primitives
|
|
47
48
|
@h = @z.dup
|
48
49
|
@calc_h = @z.dup
|
49
50
|
|
51
|
+
|
50
52
|
set_anchors
|
51
53
|
end
|
52
54
|
|
@@ -56,28 +58,91 @@ module JennCad::Primitives
|
|
56
58
|
if @opts[:center] || @opts[:center_x]
|
57
59
|
left = -@opts[:x] / 2.0
|
58
60
|
right = @opts[:x] / 2.0
|
61
|
+
mid_x = 0
|
59
62
|
else
|
60
63
|
left = 0
|
61
64
|
right = @opts[:x]
|
65
|
+
mid_x = @opts[:x] / 2.0
|
62
66
|
end
|
63
67
|
if @opts[:center] || @opts[:center_y]
|
64
68
|
bottom = -@opts[:y] / 2.0
|
65
69
|
top = @opts[:y] / 2.0
|
70
|
+
mid_y = 0
|
66
71
|
else
|
67
72
|
bottom = 0
|
68
73
|
top = @opts[:y]
|
74
|
+
mid_y = @opts[:y] / 2.0
|
69
75
|
end
|
70
76
|
|
71
|
-
set_anchor :left, x: left
|
72
|
-
set_anchor :right, x: right
|
73
|
-
set_anchor :top, y: top
|
74
|
-
set_anchor :bottom, y: bottom
|
77
|
+
set_anchor :left, x: left, y: mid_y
|
78
|
+
set_anchor :right, x: right, y: mid_y
|
79
|
+
set_anchor :top, x: mid_x, y: top
|
80
|
+
set_anchor :bottom, x: mid_x, y: bottom
|
75
81
|
set_anchor :top_left, x: left, y: top
|
76
82
|
set_anchor :top_right, x: right, y: top
|
77
83
|
set_anchor :bottom_left, x: left, y: bottom
|
78
84
|
set_anchor :bottom_right, x: right, y: bottom
|
85
|
+
|
86
|
+
# we need to re-do the inner ones, if they were defined
|
87
|
+
if @inner_anchor_defs && @inner_anchor_defs.size > 0
|
88
|
+
@inner_anchor_defs.each do |anch|
|
89
|
+
inner_anchors(anch[:dist], anch[:prefix], true)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
self
|
79
94
|
end
|
80
95
|
|
96
|
+
def inner_anchors(dist, prefix=:inner_, recreate=false)
|
97
|
+
@inner_anchor_defs ||= []
|
98
|
+
@inner_anchor_defs << { "dist": dist, "prefix": prefix } unless recreate
|
99
|
+
|
100
|
+
# $log.info "dist: #{dist}, prefix: #{prefix}"
|
101
|
+
sides = {
|
102
|
+
left: {x: dist, y: 0},
|
103
|
+
right: {x: -dist, y: 0},
|
104
|
+
top: {x: 0, y: -dist},
|
105
|
+
bottom: {x: 0, y: dist},
|
106
|
+
}
|
107
|
+
corners = {
|
108
|
+
top_left: {x: dist, y: -dist},
|
109
|
+
top_right: {x: -dist, y: -dist},
|
110
|
+
bottom_left: {x: dist, y: dist},
|
111
|
+
bottom_right: {x: -dist, y: dist},
|
112
|
+
}
|
113
|
+
new_sides = []
|
114
|
+
new_corners = []
|
115
|
+
|
116
|
+
sides.merge(corners).each do |key, vals|
|
117
|
+
new_dist = anchor(key).dup
|
118
|
+
new_dist[:x] += vals[:x]
|
119
|
+
new_dist[:y] += vals[:y]
|
120
|
+
name = [prefix, key].join.to_sym
|
121
|
+
# $log.info "Set anchor #{name} , new dist #{new_dist}"
|
122
|
+
set_anchor name, new_dist
|
123
|
+
if sides.include? key
|
124
|
+
new_sides << name
|
125
|
+
end
|
126
|
+
if corners.include? key
|
127
|
+
new_corners << name
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
sides_name = [prefix, "sides"].join
|
132
|
+
corners_name = [prefix, "corners"].join
|
133
|
+
all_name = [prefix, "all"].join
|
134
|
+
self.class.__send__(:attr_accessor, sides_name.to_sym)
|
135
|
+
self.class.__send__(:attr_accessor, corners_name.to_sym)
|
136
|
+
self.class.__send__(:attr_accessor, all_name.to_sym)
|
137
|
+
self.__send__("#{sides_name}=", new_sides)
|
138
|
+
self.__send__("#{corners_name}=", new_corners)
|
139
|
+
self.__send__("#{all_name}=", new_corners+new_sides)
|
140
|
+
|
141
|
+
|
142
|
+
self
|
143
|
+
end
|
144
|
+
|
145
|
+
|
81
146
|
# used for openscad export
|
82
147
|
def size
|
83
148
|
[@x, @y, z+z_margin]
|
@@ -36,10 +36,25 @@ module JennCad::Primitives
|
|
36
36
|
@d = @opts[:d]
|
37
37
|
@a = @opts[:a]
|
38
38
|
@h = @opts[:h]
|
39
|
-
@r = @opts[:r]
|
39
|
+
@r = @opts[:r] || nil
|
40
|
+
if @r
|
41
|
+
@d = @r * 2
|
42
|
+
end
|
40
43
|
@fn = @opts[:fn]
|
41
44
|
@len_x = @opts[:x]
|
42
45
|
@len_y = @opts[:y]
|
46
|
+
tx = @opts[:tx] || @opts[:total_x] || nil
|
47
|
+
ty = @opts[:ty] || @opts[:total_y] || nil
|
48
|
+
if tx
|
49
|
+
@len_x = tx - @d
|
50
|
+
end
|
51
|
+
if ty
|
52
|
+
@len_y = ty - @d
|
53
|
+
end
|
54
|
+
|
55
|
+
# TODO: this needs anchors like cube
|
56
|
+
# TODO: color on this needs to apply to hull, not on the cylinders.
|
57
|
+
|
43
58
|
end
|
44
59
|
|
45
60
|
def to_openscad
|
@@ -3,10 +3,16 @@ module JennCad::Primitives
|
|
3
3
|
def inherit_z
|
4
4
|
@z = 0
|
5
5
|
@calc_z = parts.first.calc_z.to_f
|
6
|
+
|
6
7
|
only_additives_of(@parts).each do |p|
|
8
|
+
if option(:debug)
|
9
|
+
$log.debug "inherit_z checks for: #{p}"
|
10
|
+
end
|
7
11
|
z = p.z.to_f
|
8
12
|
@z = z if z > @z
|
9
13
|
end
|
14
|
+
$log.debug "inherit_z called, biggest z found: #{@z}" if option(:debug)
|
15
|
+
|
10
16
|
end
|
11
17
|
|
12
18
|
def get_heights(obj)
|
@@ -58,7 +64,7 @@ module JennCad::Primitives
|
|
58
64
|
when JennCad::Circle
|
59
65
|
when JennCad::BooleanObject
|
60
66
|
else
|
61
|
-
|
67
|
+
$log.debug part if part.opts[:debug]
|
62
68
|
part.opts[:margins][:z] ||= 0.0
|
63
69
|
unless part.opts[:margins][:z] == 0.2
|
64
70
|
part.opts[:margins][:z] = 0.2
|
@@ -66,7 +72,7 @@ module JennCad::Primitives
|
|
66
72
|
end
|
67
73
|
end
|
68
74
|
elsif part.z == compare_h
|
69
|
-
|
75
|
+
$log.debug "fixing possible z fighting: #{part.class} #{part.z}" if part.opts[:debug]
|
70
76
|
part.opts[:margins][:z] += 0.008
|
71
77
|
part.mz(-0.004)
|
72
78
|
elsif part.calc_z == compare_z
|
data/lib/jenncad/shortcuts.rb
CHANGED
@@ -39,7 +39,7 @@ module JennCad
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def stl(file, args={})
|
42
|
-
StlImport.new(file, args)
|
42
|
+
StlImport.new(file, args).set_parent(self)
|
43
43
|
end
|
44
44
|
|
45
45
|
def extrude(args={})
|
@@ -92,6 +92,11 @@ module JennCad
|
|
92
92
|
|
93
93
|
private
|
94
94
|
def boolean_operation(part, klass)
|
95
|
+
if part.respond_to? :transformations
|
96
|
+
# Since ruby doesn't provide a way to make a deep clone, this seems to be the simplest solution that will effectively do that:
|
97
|
+
part = Marshal.load(Marshal.dump(part))
|
98
|
+
end
|
99
|
+
|
95
100
|
case self
|
96
101
|
when nil
|
97
102
|
part
|
data/lib/jenncad/thing.rb
CHANGED
@@ -19,10 +19,8 @@ module JennCad
|
|
19
19
|
@calc_h = args[:z] || 0
|
20
20
|
@anchors = {}
|
21
21
|
@parent = args[:parent]
|
22
|
-
if @parent
|
23
|
-
log.info "Parent: #{@parent}"
|
24
|
-
end
|
25
22
|
@opts ||= args
|
23
|
+
@cache = nil
|
26
24
|
end
|
27
25
|
|
28
26
|
def option(key)
|
@@ -42,13 +40,19 @@ module JennCad
|
|
42
40
|
|
43
41
|
def anchor(name, thing=nil)
|
44
42
|
if thing
|
45
|
-
|
43
|
+
res = thing.anchor(name)
|
44
|
+
return res unless res.nil?
|
46
45
|
end
|
47
46
|
@anchors ||= {}
|
48
47
|
if anch = @anchors[name]
|
49
48
|
return anch
|
50
49
|
elsif @parent
|
51
50
|
return @parent.anchor(name)
|
51
|
+
elsif self.respond_to? :get_contents
|
52
|
+
con = get_contents
|
53
|
+
if con.respond_to? :anchor
|
54
|
+
con.anchor(name)
|
55
|
+
end
|
52
56
|
end
|
53
57
|
end
|
54
58
|
alias :a :anchor
|
@@ -212,6 +216,7 @@ module JennCad
|
|
212
216
|
# move to anchor
|
213
217
|
def movea(key, thing=nil)
|
214
218
|
an = anchor(key, thing)
|
219
|
+
|
215
220
|
unless an
|
216
221
|
$log.error "Error: Anchor #{key} not found"
|
217
222
|
$log.error "Available anchors: #{@anchors}"
|
@@ -344,36 +349,14 @@ module JennCad
|
|
344
349
|
def get_children(item, stop_at)
|
345
350
|
res = [item]
|
346
351
|
if item.respond_to?(:parts) && item.parts != nil
|
347
|
-
item.parts.each do |
|
348
|
-
unless stop_at != nil &&
|
349
|
-
res << get_children(
|
352
|
+
item.parts.each do |pa|
|
353
|
+
unless stop_at != nil && pa.kind_of?(stop_at)
|
354
|
+
res << get_children(pa, stop_at)
|
350
355
|
end
|
351
356
|
end
|
352
357
|
end
|
353
358
|
res
|
354
359
|
end
|
355
|
-
=begin def make_openscad_compatible
|
356
|
-
make_openscad_compatible!(self)
|
357
|
-
end
|
358
|
-
|
359
|
-
def make_openscad_compatible!(item)
|
360
|
-
if item.respond_to?(:parts) && item.parts != nil
|
361
|
-
item.parts.each_with_index do |part, i|
|
362
|
-
if part.respond_to? :to_openscad
|
363
|
-
item.parts[i] = part.to_openscad
|
364
|
-
else
|
365
|
-
item.parts[i] = part.make_openscad_compatible
|
366
|
-
end
|
367
|
-
end
|
368
|
-
elsif item.respond_to? :part
|
369
|
-
item = item.part.make_openscad_compatible
|
370
|
-
end
|
371
|
-
if item.respond_to? :to_openscad
|
372
|
-
item = item.to_openscad
|
373
|
-
end
|
374
|
-
item
|
375
|
-
end
|
376
|
-
=end
|
377
360
|
|
378
361
|
def inherit_color(other)
|
379
362
|
self.set_option(:color, other.option(:color))
|
@@ -389,11 +372,14 @@ module JennCad
|
|
389
372
|
|
390
373
|
def only_color?(parts, lvl=0)
|
391
374
|
return true if parts == nil
|
375
|
+
unless parts.kind_of? Array
|
376
|
+
parts = [parts]
|
377
|
+
end
|
392
378
|
|
393
379
|
parts.each do |part|
|
394
|
-
#
|
380
|
+
#puts " " * lvl + "[only_color?] #{part}"
|
395
381
|
if part.has_explicit_color?
|
396
|
-
#
|
382
|
+
#puts " " * lvl + "found explicit color here: #{part.color}"
|
397
383
|
return false
|
398
384
|
end
|
399
385
|
if !only_color?(part.parts, lvl+1)
|
@@ -409,14 +395,14 @@ module JennCad
|
|
409
395
|
parts.each do |part|
|
410
396
|
unless part.has_explicit_color?
|
411
397
|
if only_color?(part.parts, lvl+1)
|
412
|
-
#
|
398
|
+
#puts " " * lvl + "children have no explicit color, setting it here"
|
413
399
|
part.set_auto_color(col)
|
414
400
|
else
|
415
|
-
#
|
401
|
+
#puts " " * lvl + "[set_auto_color_for_children] #{part}"
|
416
402
|
set_auto_color_for_children(col, part.parts, lvl+1)
|
417
403
|
end
|
418
404
|
else
|
419
|
-
#
|
405
|
+
#puts " " * lvl + "[set_auto_color_for_children] this part has a color #{part.color}, ignoring their children"
|
420
406
|
end
|
421
407
|
|
422
408
|
end
|
@@ -492,8 +478,15 @@ module JennCad
|
|
492
478
|
|
493
479
|
def get_contents
|
494
480
|
return @parts unless @parts.nil?
|
481
|
+
|
482
|
+
if @cache
|
483
|
+
return @cache
|
484
|
+
end
|
485
|
+
|
495
486
|
if self.respond_to? :part
|
496
|
-
|
487
|
+
# cache things to prevent calling the code in #part multiple times
|
488
|
+
@cache = part
|
489
|
+
return @cache
|
497
490
|
end
|
498
491
|
end
|
499
492
|
|
@@ -506,6 +499,9 @@ module JennCad
|
|
506
499
|
|
507
500
|
def find_calculated_h(parts)
|
508
501
|
return if parts == nil
|
502
|
+
unless parts.kind_of? Array
|
503
|
+
parts = [parts]
|
504
|
+
end
|
509
505
|
parts.each do |part|
|
510
506
|
if z = calculated_h
|
511
507
|
return z
|
@@ -516,6 +512,10 @@ module JennCad
|
|
516
512
|
|
517
513
|
def set_heights_for_auto_extrude(parts, parent=nil)
|
518
514
|
return if parts.nil?
|
515
|
+
unless parts.kind_of? Array
|
516
|
+
parts = [parts]
|
517
|
+
end
|
518
|
+
|
519
519
|
parts.each do |part|
|
520
520
|
if part.option(:auto_extrude)
|
521
521
|
part.z = parent.calculated_h
|
@@ -532,6 +532,37 @@ module JennCad
|
|
532
532
|
JennCad::Exporters::OpenScad.new(self).save(file)
|
533
533
|
end
|
534
534
|
|
535
|
+
def ghost
|
536
|
+
set_option :ghost, true
|
537
|
+
set_option :no_auto_color, true
|
538
|
+
set_option :color, nil
|
539
|
+
set_option :auto_color, false
|
540
|
+
self
|
541
|
+
end
|
542
|
+
|
543
|
+
def hide
|
544
|
+
set_option :hide, true
|
545
|
+
self
|
546
|
+
end
|
547
|
+
|
548
|
+
def only
|
549
|
+
set_option :only, true
|
550
|
+
self
|
551
|
+
end
|
552
|
+
|
553
|
+
def hl
|
554
|
+
set_option :highlight, true
|
555
|
+
self
|
556
|
+
end
|
557
|
+
|
558
|
+
def openscad_modifier
|
559
|
+
return "%" if option(:ghost)
|
560
|
+
return "#" if option(:highlight)
|
561
|
+
return "!" if option(:only)
|
562
|
+
return "*" if option(:hide)
|
563
|
+
nil
|
564
|
+
end
|
565
|
+
|
535
566
|
def referenced_z
|
536
567
|
return false if @z.to_f != 0.0
|
537
568
|
return option(:zref) if option(:zref)
|
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.alpha13
|
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-
|
11
|
+
date: 2022-05-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: geo3d
|