jenncad 1.0.0.pre.alpha14 → 1.0.0.pre.alpha17

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: beb1887d6ae1d3fc87da9c816de1cd2cb54ea5fb3ce7f1277ca6af8bcfc4e687
4
- data.tar.gz: 5cc6fd0fc52de9b8b9087dfadd0387122014b157c9573b091aa7c4570a5f2c6a
3
+ metadata.gz: be56296dfd0c04706441288172b3493d918f76a05ee92fa1004ce0c619e6d1c0
4
+ data.tar.gz: 7b1130259db67a2a0e75e8074265958fac8ada1dbd6a3ce34de2dc4050a1d7a9
5
5
  SHA512:
6
- metadata.gz: 8f86a697557b258219756ba02c0bb0e478d1c240c05fd53ecb1221749caedd4e7bf7c3395c439f9c0d426e33366d104e71c20a89bca894ee8e0c843733a0446d
7
- data.tar.gz: 4ee555b106f36751024a876ece4880b3cea9138e606c541457a809828645f399f3a417cc0f40256e7363bf20f2b212a20f27166429337062a297caddb21931e1
6
+ metadata.gz: 76e84ad22e862bc9b961d4e96382d0c40ebdfe6ab2ff2ee709c5e90faf7eb01b5199612abb4c0950c193cef97c4a43a895b2e071c306a9036d018ac135416adc
7
+ data.tar.gz: df24c4d80c52738a6223dd0ac7d20a8448c06839c7c448e436afa0501d659276d7e28dc5c0a23cf2742babd13475e5afb1be8aa13bf69916fc8b4844306b006e
@@ -118,15 +118,15 @@ module JennCad
118
118
  File.open(filename, "w") do |f|
119
119
  f.puts "class #{classname} < Part"
120
120
  f.puts " def initialize(opts={})"
121
- f.puts " @opts = {"
122
- f.puts " x: 10,"
123
- f.puts " y: 10,"
124
- f.puts " z: 5,"
125
- f.puts " }.merge(opts)"
121
+ f.puts " @x = 10"
122
+ f.puts " @y = 10"
123
+ f.puts " @z = 5"
126
124
  f.puts " end"
127
125
  f.puts ""
128
126
  f.puts " def part"
129
- f.puts " cube(@opts)"
127
+ f.puts " base = cube(x: @x, y: @y, z: @z)"
128
+ f.puts " res = base.fix"
129
+ f.puts " res"
130
130
  f.puts " end"
131
131
  f.puts "end"
132
132
  end
@@ -162,14 +162,16 @@ module JennCad::Exporters
162
162
  bool('intersection', part)
163
163
  when JennCad::HullObject
164
164
  bool('hull', part)
165
- when JennCad::Primitives::Circle
166
- prim('circle', part)
167
165
  when JennCad::Primitives::Cylinder
168
166
  prim('cylinder', part)
169
167
  when JennCad::Primitives::Sphere
170
168
  prim('sphere', part)
171
169
  when JennCad::Primitives::Cube
172
170
  prim('cube', part)
171
+ when JennCad::Primitives::Circle
172
+ prim('circle', part)
173
+ when JennCad::Primitives::Square
174
+ prim('square', part)
173
175
  when JennCad::Primitives::LinearExtrude
174
176
  new_obj(part, :linear_extrude, part.openscad_params, parse(part.parts))
175
177
  when JennCad::Primitives::RotateExtrude
@@ -178,6 +180,8 @@ module JennCad::Exporters
178
180
  new_obj(part, :projection, collect_params(part), parse(part.parts))
179
181
  when JennCad::Primitives::Polygon
180
182
  new_obj(part, :polygon, collect_params(part))
183
+ when JennCad::Primitives::Polyhedron
184
+ new_obj(part, :polyhedron, collect_params(part))
181
185
  when JennCad::StlImport
182
186
  new_obj(part, :import, collect_params(part))
183
187
  when JennCad::Part
@@ -212,7 +216,7 @@ module JennCad::Exporters
212
216
  return part.openscad_params
213
217
  end
214
218
  res = {}
215
- [:d, :h, :d1, :d2, :size, :fn, :points, :file].each do |var|
219
+ [:d, :h, :d1, :d2, :size, :fn, :points, :paths, :faces, :convexity, :file].each do |var|
216
220
  if part.respond_to? var
217
221
  res[var] = part.send var
218
222
  end
@@ -6,6 +6,7 @@ module JennCad::Features
6
6
  super({})
7
7
  @name = name.gsub(".","_")
8
8
  @parts = [part]
9
+ @zref = part
9
10
  end
10
11
 
11
12
  def z
@@ -1,6 +1,8 @@
1
1
  module JennCad::Features
2
2
  class Climb < Feature
3
3
  def initialize(opts, block)
4
+ $log.warn "DEPRECATED feature: climb. Please use x.of (multiples_of example)"
5
+
4
6
  @opts = {
5
7
  offset: :auto,
6
8
  step: nil,
@@ -0,0 +1,14 @@
1
+ class Integer
2
+ def of(part=nil, anchor=:top_face)
3
+ return nil if part.nil?
4
+ num = self - 1
5
+
6
+ res = part.fix
7
+ num.times do
8
+ res += part.movea(anchor)
9
+ end
10
+ res
11
+ end
12
+ end
13
+
14
+
@@ -1,7 +1,7 @@
1
1
  module JennCad
2
2
  class RoundCorner
3
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)
4
+ def initialize(args)
5
5
  @start_point = args[:start_point]
6
6
  @end_point = args[:end_point]
7
7
  @a = args[:a]
@@ -11,7 +11,13 @@ module JennCad
11
11
  @id = args[:id]
12
12
  @input_a = args[:input_a] || 0
13
13
  @output_a = args[:output_a] || 0
14
- @thing = thing
14
+ thing = Marshal.load(args[:thing])
15
+
16
+ @thing_dia = thing.d || thing.y
17
+ unless @thing_dia
18
+ $log.error "ERROR: cannot find diameter or y of thing #{thing.inspect}"
19
+ return
20
+ end
15
21
  @angle = args[:angle]
16
22
  @current_angle = args[:current_angle]
17
23
  @direction = args[:direction]
@@ -57,11 +63,7 @@ module JennCad
57
63
  end
58
64
 
59
65
  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
66
+ td = @thing_dia
65
67
  l = td + @id
66
68
  l2 = td / 2.0 + @id / 2.0
67
69
  r = 0
@@ -101,7 +103,7 @@ module JennCad
101
103
  end
102
104
 
103
105
  def part
104
- d = thing.yield.d
106
+ d = @thing_dia
105
107
  len = d * 2 + @id
106
108
  x = Math::sin((@a/180.0)*Math::PI)*len
107
109
  y = Math::cos((@a/180.0)*Math::PI)*len
@@ -134,15 +136,15 @@ module JennCad
134
136
  end
135
137
 
136
138
  class Line
137
- attr_accessor :start_point, :end_point, :l, :thing, :angle, :current_angle, :direction
138
- def initialize(args, &thing)
139
+ attr_accessor :start_point, :end_point, :l, :angle, :current_angle, :direction
140
+ def initialize(args)
139
141
  @start_point = args[:start_point]
140
142
  @end_point = args[:end_point]
141
143
  @angle = args[:angle]
142
144
  @current_angle = args[:current_angle]
143
145
  @direction = args[:direction]
144
146
  @l = args[:l]
145
- @thing = thing
147
+ @thing = args[:thing]
146
148
  end
147
149
 
148
150
  def sp_margin(margin)
@@ -181,8 +183,8 @@ module JennCad
181
183
 
182
184
  def part
183
185
  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
+ Marshal.load(@thing).move(x: @start_point[:x], y: @start_point[:y]),
187
+ Marshal.load(@thing).move(x: @end_point[:x], y: @end_point[:y])
186
188
  )
187
189
  end
188
190
  end
@@ -191,7 +193,7 @@ module JennCad
191
193
 
192
194
  attr_accessor :elements, :lpos, :thing, :angle, :current_angle, :direction
193
195
  def initialize(args)
194
- @thing = args[:part] #// cylinder(d: @d, z: @z)
196
+ @thing = store_thing_from(args[:part])
195
197
  @part = new_thing
196
198
  @angle = args[:a] || 0
197
199
  @current_angle = args[:a] || 0
@@ -207,10 +209,14 @@ module JennCad
207
209
  super(args)
208
210
  end
209
211
 
210
- def new_thing
211
- r = @thing.clone
212
+ def store_thing_from(thing)
213
+ r = Marshal.load(Marshal.dump(thing)) # make sure we don't edit the object in memory
212
214
  r.transformations = []
213
- r
215
+ Marshal.dump(r)
216
+ end
217
+
218
+ def new_thing
219
+ Marshal.load(@thing)
214
220
  end
215
221
 
216
222
  def corner(args)
@@ -232,8 +238,9 @@ module JennCad
232
238
  from: args[:from],
233
239
  to: args[:to],
234
240
  a: args[:a],
235
- direction: @direction
236
- ){ new_thing }
241
+ direction: @direction,
242
+ thing: thing,
243
+ )
237
244
 
238
245
  _, ox, oy, x, y = rc.positions
239
246
  @lpos[:x] += x + ox
@@ -292,7 +299,7 @@ module JennCad
292
299
  return
293
300
  end
294
301
 
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 }
302
+ @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, thing: thing)
296
303
 
297
304
  add_lpos({x: x, y: y})
298
305
  end
@@ -5,6 +5,8 @@ require "jenncad/features/openscad_include"
5
5
  require "jenncad/features/climb"
6
6
  require "jenncad/features/stl_import"
7
7
  require "jenncad/features/path"
8
+ require "jenncad/features/multiples_of"
9
+
8
10
 
9
11
 
10
12
 
data/lib/jenncad/part.rb CHANGED
@@ -1,9 +1,54 @@
1
+ module AutoName
2
+ def initialize(args={})
3
+ unless args.empty?
4
+ @auto_name = "#{self.class}_#{args.map{|key, val| "#{key}_#{val}"}.join('_')}"
5
+ end
6
+ super(args)
7
+ end
8
+ end
9
+
1
10
  module JennCad
2
11
  # Part should be inherited from the user when making parts
3
12
  class Part < Thing
13
+ def self.inherited(subclass)
14
+ subclass.prepend(AutoName) if subclass.superclass == Part
15
+ end
16
+
17
+ # this function both gets and defines hardware
18
+ def hardware(hw_type=nil, args={})
19
+ @_hw ||= {}
20
+ if hw_type == nil
21
+ return @_hw
22
+ end
23
+
24
+ anchors = args[:anchor] || args[:anchors]
25
+ unless anchors.kind_of? Array
26
+ anchors = [anchors]
27
+ end
28
+
29
+ anchors.each do |a|
30
+ @_hw[a] = {
31
+ hw_type: hw_type,
32
+ size: args[:size],
33
+ d: args[:d],
34
+ len: args[:len],
35
+ pos: anchor(a, args[:from]),
36
+ }
37
+ end
38
+ self
39
+ end
40
+ alias :hw :hardware
41
+
42
+ def fix_name_for_openscad(name)
43
+ [":", ",", ".", "[", "]","-", " "].each do |key|
44
+ name.gsub!(key, "_")
45
+ end
46
+ name
47
+ end
4
48
 
5
49
  def to_openscad
6
- a = Aggregation.new(self.class.to_s, self.get_contents)
50
+ name = @name || @auto_name || self.class.to_s
51
+ a = Aggregation.new(fix_name_for_openscad(name), self.get_contents)
7
52
  a.transformations = @transformations
8
53
  if self.has_explicit_color?
9
54
  a.color(self.color)
@@ -7,6 +7,9 @@ module JennCad::Primitives
7
7
  else
8
8
  @parts = parts
9
9
  end
10
+ if parts.first && parts.first.respond_to?(:debug?) && parts.first.debug?
11
+ $log.debug("Creating new #{self.class} for part #{parts}")
12
+ end
10
13
 
11
14
  @parent = @parts.first.parent
12
15
 
@@ -16,9 +19,11 @@ module JennCad::Primitives
16
19
  def add_or_new(part)
17
20
  case @transformations
18
21
  when nil, []
22
+ $log.debug("adding new part to existing boolean object") if part && part.debug?
19
23
  add(part)
20
24
  self
21
25
  else
26
+ $log.debug("add_or_new: creating new boolean object") if part.debug?
22
27
  self.class.new(self, part)
23
28
  end
24
29
  end
@@ -2,10 +2,108 @@ module JennCad::Primitives
2
2
  class Circle < Primitive
3
3
  attr_accessor :d, :r, :fn
4
4
  def initialize(args)
5
- super
6
- @d = args[:d]
7
- @r = args[:r]
8
- @fn = args[:fn]
5
+ if args.kind_of?(Array) && args[0].kind_of?(Hash)
6
+ args = args.first
7
+ end
8
+ if args.kind_of? Array
9
+ m = {}
10
+ if args.last.kind_of? Hash
11
+ m = args.last
12
+ end
13
+ args = [:d, :z].zip(args.flatten).to_h
14
+ args.deep_merge!(m)
15
+ end
16
+
17
+
18
+ @opts = {
19
+ d: 0,
20
+ d1: nil,
21
+ d2: nil,
22
+ r1: nil,
23
+ r2: nil,
24
+ z: nil,
25
+ r: 0,
26
+ cz: false,
27
+ margins: {
28
+ r: 0,
29
+ d: 0,
30
+ z: 0,
31
+ },
32
+ fn: nil,
33
+ }.deep_merge!(args)
34
+ init(args)
35
+ @dimensions = [:x, :y]
36
+ handle_radius_diameter
37
+ handle_fn
38
+ set_anchors_2d
9
39
  end
40
+
41
+ def set_anchors_2d
42
+ @anchors = {} # reset anchors
43
+ if @opts[:d]
44
+ rad = @opts[:d] / 2.0
45
+ else
46
+ rad = @opts[:r]
47
+ end
48
+
49
+ # Similar to cube
50
+ set_anchor :left, x: -rad
51
+ set_anchor :right, x: rad
52
+ set_anchor :top, y: rad
53
+ set_anchor :bottom, y: -rad
54
+ end
55
+
56
+ def openscad_params
57
+ res = {}
58
+ [:d, :fn].each do |n|
59
+ res[n] = self.send n
60
+ end
61
+ res
62
+ end
63
+
64
+ def handle_fn
65
+ case @opts[:fn]
66
+ when nil, 0
67
+ $fn = auto_dn!
68
+ else
69
+ @fn = @opts[:fn]
70
+ end
71
+ end
72
+
73
+ def auto_dn!
74
+ case @d
75
+ when (16..)
76
+ @fn = (@d*4).ceil
77
+ else
78
+ @fn = 64
79
+ end
80
+ end
81
+
82
+ def handle_radius_diameter
83
+ case @opts[:d]
84
+ when 0, nil
85
+ @r = @opts[:r].to_d + @opts[:margins][:r].to_d
86
+ @d = @r * 2.0
87
+ else
88
+ @d = @opts[:d].to_d + @opts[:margins][:d].to_d
89
+ @r = @d / 2.0
90
+ end
91
+
92
+ case @opts[:d1]
93
+ when 0, nil
94
+ else
95
+ @d1 = @opts[:d1].to_d + @opts[:margins][:d].to_d
96
+ @d2 = @opts[:d2].to_d + @opts[:margins][:d].to_d
97
+ end
98
+
99
+ case @opts[:r1]
100
+ when 0, nil
101
+ else
102
+ @d1 = 2 * @opts[:r1].to_d + @opts[:margins][:d].to_d
103
+ @d2 = 2 * @opts[:r2].to_d + @opts[:margins][:d].to_d
104
+ end
105
+ end
106
+
107
+
10
108
  end
11
109
  end
@@ -1,24 +1,7 @@
1
1
  module JennCad::Primitives
2
- class Cube < Primitive
2
+ class Cube < Square
3
3
  extend JennCad::Features::Cuttable
4
4
 
5
- attr_accessor :corners, :sides
6
-
7
- def feed_opts(args)
8
- # FIXME: this doesn't seem to work
9
- if args.kind_of? Array
10
- m = {}
11
- if args.last.kind_of? Hash
12
- m = args.last
13
- end
14
- args = [:x, :y, :z].zip(args.flatten).to_h
15
- args.deep_merge!(m)
16
- @opts.deep_merge!(args)
17
- else
18
- @opts.deep_merge!(args)
19
- end
20
- end
21
-
22
5
  def initialize(args)
23
6
  @opts = {
24
7
  x: 0,
@@ -41,137 +24,36 @@ module JennCad::Primitives
41
24
  else
42
25
  feed_opts(parse_xyz_shortcuts(args))
43
26
  end
27
+ init
44
28
 
45
29
 
46
30
  handle_margins
47
- super(z: @opts[:z])
48
31
  @h = @z.dup
49
32
  @calc_h = @z.dup
50
33
 
34
+ @dimensions = [:x, :y, :z]
51
35
 
52
36
  set_anchors
53
37
  end
54
38
 
55
39
  def set_anchors
56
- @anchors = {} # this resets anchors
57
-
58
- if @opts[:center] || @opts[:center_x]
59
- left = -@opts[:x] / 2.0
60
- right = @opts[:x] / 2.0
61
- mid_x = 0
62
- else
63
- left = 0
64
- right = @opts[:x]
65
- mid_x = @opts[:x] / 2.0
66
- end
67
- if @opts[:center] || @opts[:center_y]
68
- bottom = -@opts[:y] / 2.0
69
- top = @opts[:y] / 2.0
70
- mid_y = 0
40
+ set_anchors_2d
41
+ if @opts[:center_z]
42
+ set_anchor :bottom_face, z: -@z/2.0
43
+ set_anchor :top_face, z: @z/2.0
71
44
  else
72
- bottom = 0
73
- top = @opts[:y]
74
- mid_y = @opts[:y] / 2.0
45
+ set_anchor :bottom_face, z: 0
46
+ set_anchor :top_face, z: @z
75
47
  end
76
48
 
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
81
- set_anchor :top_left, x: left, y: top
82
- set_anchor :top_right, x: right, y: top
83
- set_anchor :bottom_left, x: left, y: bottom
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
49
 
93
- self
94
50
  end
95
51
 
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
-
146
52
  # used for openscad export
147
53
  def size
148
54
  [@x, @y, z+z_margin]
149
55
  end
150
56
 
151
- def not_centered
152
- @opts[:center] = false
153
- set_anchors
154
- self
155
- end
156
- alias :nc :not_centered
157
-
158
- def cx
159
- nc
160
- @opts[:center_x] = true
161
- set_anchors
162
- self
163
- end
164
- alias :center_x :cx
165
-
166
- def cy
167
- nc
168
- @opts[:center_y] = true
169
- set_anchors
170
- self
171
- end
172
- alias :center_y :cy
173
-
174
-
175
57
  def cz
176
58
  nc
177
59
  @opts[:center_z] = true
@@ -180,18 +62,5 @@ module JennCad::Primitives
180
62
  end
181
63
  alias :center_z :cz
182
64
 
183
- def centered_axis
184
- return [:x, :y] if @opts[:center]
185
- a = []
186
- a << :x if @opts[:center_x]
187
- a << :y if @opts[:center_y]
188
- a << :z if @opts[:center_z]
189
- a
190
- end
191
-
192
- def to_openscad
193
- self.mh(centered_axis.to_h{|a| [a, -@opts[a]] }) # center cube
194
- end
195
-
196
65
  end
197
66
  end