jenncad 1.0.0.pre.alpha10 → 1.0.0.pre.alpha13
Sign up to get free protection for your applications and to get access to all the features.
- 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
|