jenncad 1.0.0.pre.alpha7 → 1.0.0.pre.alpha10

Sign up to get free protection for your applications and to get access to all the features.
@@ -46,6 +46,36 @@ module JennCad::Primitives
46
46
  super(z: @opts[:z])
47
47
  @h = @z.dup
48
48
  @calc_h = @z.dup
49
+
50
+ set_anchors
51
+ end
52
+
53
+ def set_anchors
54
+ @anchors = {} # this resets anchors
55
+
56
+ if @opts[:center] || @opts[:center_x]
57
+ left = -@opts[:x] / 2.0
58
+ right = @opts[:x] / 2.0
59
+ else
60
+ left = 0
61
+ right = @opts[:x]
62
+ end
63
+ if @opts[:center] || @opts[:center_y]
64
+ bottom = -@opts[:y] / 2.0
65
+ top = @opts[:y] / 2.0
66
+ else
67
+ bottom = 0
68
+ top = @opts[:y]
69
+ end
70
+
71
+ set_anchor :left, x: left
72
+ set_anchor :right, x: right
73
+ set_anchor :top, y: top
74
+ set_anchor :bottom, y: bottom
75
+ set_anchor :top_left, x: left, y: top
76
+ set_anchor :top_right, x: right, y: top
77
+ set_anchor :bottom_left, x: left, y: bottom
78
+ set_anchor :bottom_right, x: right, y: bottom
49
79
  end
50
80
 
51
81
  # used for openscad export
@@ -55,6 +85,7 @@ module JennCad::Primitives
55
85
 
56
86
  def not_centered
57
87
  @opts[:center] = false
88
+ set_anchors
58
89
  self
59
90
  end
60
91
  alias :nc :not_centered
@@ -62,20 +93,27 @@ module JennCad::Primitives
62
93
  def cx
63
94
  nc
64
95
  @opts[:center_x] = true
96
+ set_anchors
65
97
  self
66
98
  end
99
+ alias :center_x :cx
67
100
 
68
101
  def cy
69
102
  nc
70
103
  @opts[:center_y] = true
104
+ set_anchors
71
105
  self
72
106
  end
107
+ alias :center_y :cy
108
+
73
109
 
74
110
  def cz
75
111
  nc
76
112
  @opts[:center_z] = true
113
+ set_anchors
77
114
  self
78
115
  end
116
+ alias :center_z :cz
79
117
 
80
118
  def centered_axis
81
119
  return [:x, :y] if @opts[:center]
@@ -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
@@ -22,7 +22,7 @@ module JennCad::Primitives
22
22
  y: 0,
23
23
  z: nil,
24
24
  r: nil,
25
- flat_edges: nil,
25
+ flat_edges: [],
26
26
  center: true,
27
27
  center_y: false,
28
28
  center_x: false,
@@ -43,33 +43,44 @@ module JennCad::Primitives
43
43
  def to_openscad
44
44
  return cube(@opts) if @d == 0
45
45
  # make diameter not bigger than any side
46
- @d = [@d, @x, @y].min
46
+ d = [@d, @x, @y].min
47
47
  res = HullObject.new(
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)
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
+ )
53
+ res = res.move(xy: d/2.0)
53
54
 
54
- res += flat_edge(@opts[:flat_edges])
55
+ @opts[:flat_edges].each do |edge|
56
+ res += apply_flat_edge(edge)
57
+ end
55
58
 
59
+ res = union(res) # put everything we have in a parent union that we can apply the transformations of this object of
56
60
  res.transformations = @transformations
61
+
57
62
  res.moveh(centered_axis.to_h{|a| [a, -@opts[a]] })
63
+ res.inherit_color(self)
64
+ res
65
+ end
66
+
67
+ def flat(edge)
68
+ @opts[:flat_edges] ||= []
69
+ @opts[:flat_edges] << edge
70
+ self
58
71
  end
59
72
 
60
- def flat_edge(edge)
73
+ private
74
+ def apply_flat_edge(edge)
61
75
  case edge
62
- when Array
63
- #ruby2.7 test- edge.map(&self.:flat_edge)
64
- edge.map{|x| flat_edge(x) }
65
76
  when :up
66
- cube(@x, @y/2.0, @z).moveh(y:@y/2.0)
77
+ cube(x: @x, y: @y/2.0, z: @z).nc.moveh(y:@y)
67
78
  when :down
68
- cube(@x, @y/2.0, @z).moveh(y:-@y/2.0)
79
+ cube(x: @x, y: @y/2.0, z: @z).nc
69
80
  when :right
70
- cube(@x/2.0, @y, @z).moveh(x:@x/2.0)
81
+ cube(x: @x/2.0, y: @y, z: @z).nc.moveh(x:@x)
71
82
  when :left
72
- cube(@x/2.0, @y, @z).moveh(x:-@x/2.0)
83
+ cube(x: @x/2.0, y: @y, z: @z).nc
73
84
  else
74
85
  nil
75
86
  end
@@ -57,7 +57,6 @@ module JennCad::Primitives
57
57
  case part
58
58
  when JennCad::Circle
59
59
  when JennCad::BooleanObject
60
- when JennCad::Aggregation
61
60
  else
62
61
  pp part if part.opts[:debug]
63
62
  part.opts[:margins][:z] ||= 0.0
@@ -1,34 +1,34 @@
1
1
  module JennCad
2
2
  def circle(args)
3
- Circle.new(args)
3
+ Circle.new(args).set_parent(self)
4
4
  end
5
5
 
6
6
  def cylinder(*args)
7
- Cylinder.new(args)
7
+ Cylinder.new(args).set_parent(self)
8
8
  end
9
9
  alias :cy :cylinder
10
10
  alias :cyl :cylinder
11
11
 
12
12
  def sphere(args)
13
- Sphere.new(args)
13
+ Sphere.new(args).set_parent(self)
14
14
  end
15
15
  alias :sp :sphere
16
16
 
17
17
  def polygon(args)
18
- Polygon.new(args)
18
+ Polygon.new(args).set_parent(self)
19
19
  end
20
20
 
21
21
  def slot(*args)
22
- Slot.new(args)
22
+ Slot.new(args).set_parent(self)
23
23
  end
24
24
 
25
25
  def cube(*args)
26
- Cube.new(args)
26
+ Cube.new(args).set_parent(self)
27
27
  end
28
28
  alias :cu :cube
29
29
 
30
30
  def rounded_cube(*args)
31
- RoundedCube.new(args)
31
+ RoundedCube.new(args).set_parent(self)
32
32
  end
33
33
  alias :rcube :rounded_cube
34
34
  alias :rc :rounded_cube
data/lib/jenncad/thing.rb CHANGED
@@ -7,7 +7,8 @@ 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
+ attr_accessor :anchors
11
+ attr_accessor :parent
11
12
 
12
13
  def initialize(args={})
13
14
  @transformations = []
@@ -16,6 +17,11 @@ module JennCad
16
17
  @calc_y = 0
17
18
  @calc_z = 0
18
19
  @calc_h = args[:z] || 0
20
+ @anchors = {}
21
+ @parent = args[:parent]
22
+ if @parent
23
+ log.info "Parent: #{@parent}"
24
+ end
19
25
  @opts ||= args
20
26
  end
21
27
 
@@ -29,34 +35,30 @@ module JennCad
29
35
  @opts[key] = val
30
36
  end
31
37
 
32
- def set_anchor(args)
33
- self.anchor ||= {}
34
- args.each do |key, val|
35
- self.anchor[key] = val
36
- end
38
+ def set_parent(parent)
39
+ @parent = parent
40
+ self
37
41
  end
38
42
 
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)
43
+ def anchor(name, thing=nil)
44
+ if thing
45
+ return thing.anchor(name)
47
46
  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
47
+ @anchors ||= {}
48
+ if anch = @anchors[name]
49
+ return anch
50
+ elsif @parent
51
+ return @parent.anchor(name)
56
52
  end
57
- move(to)
58
53
  end
54
+ alias :a :anchor
59
55
 
56
+ def set_anchor(name, args={})
57
+ @anchors ||= {}
58
+ @anchors[name] = args
59
+ self
60
+ end
61
+ alias :sa :set_anchor
60
62
 
61
63
  def auto_extrude
62
64
  ret = self.extrude
@@ -138,10 +140,18 @@ module JennCad
138
140
  end
139
141
 
140
142
  def parse_xyz_shortcuts(args)
143
+ unless args.kind_of? Hash
144
+ $log.warn "parse_xyz_shortcuts called for type #{args.class} #{args.inspect}"
145
+ return args
146
+ end
141
147
  [:x, :y, :z].each do |key|
142
148
  args[key] ||= 0.0
143
149
  end
144
150
 
151
+ if args[:debug]
152
+ $log.debug "Args: #{args}"
153
+ end
154
+
145
155
  if args[:xy]
146
156
  args[:x] += args[:xy]
147
157
  args[:y] += args[:xy]
@@ -159,10 +169,14 @@ module JennCad
159
169
  args[:y] += args[:yz]
160
170
  args[:z] += args[:yz]
161
171
  end
162
- return args
172
+ if args[:debug]
173
+ $log.debug "After xyz shortcuts #{args}"
174
+ end
175
+
176
+ return args
163
177
  end
164
178
 
165
- def move(args)
179
+ def move(args={})
166
180
  if args.kind_of? Array
167
181
  x,y,z = args
168
182
  return move(x:x, y:y, z:z)
@@ -183,20 +197,45 @@ module JennCad
183
197
  alias :translate :move
184
198
  alias :m :move
185
199
 
186
- def mx(v)
200
+ def mx(v=0)
187
201
  move(x:v)
188
202
  end
189
203
 
190
- def my(v)
204
+ def my(v=0)
191
205
  move(y:v)
192
206
  end
193
207
 
194
- def mz(v)
208
+ def mz(v=0)
195
209
  move(z:v)
196
210
  end
197
211
 
212
+ # move to anchor
213
+ def movea(key, thing=nil)
214
+ an = anchor(key, thing)
215
+ unless an
216
+ $log.error "Error: Anchor #{key} not found"
217
+ $log.error "Available anchors: #{@anchors}"
218
+ return self
219
+ else
220
+ self.move(an.dup)
221
+ end
222
+ end
223
+
224
+ # move to anchor - inverted
225
+ def moveai(key, thing=nil)
226
+ an = anchor(key, thing)
227
+ unless an
228
+ $log.error "Error: Anchor #{key} not found"
229
+ $log.error "Available anchors: #{@anchors}"
230
+ return self
231
+ else
232
+ self.movei(an.dup)
233
+ end
234
+ end
235
+
236
+
198
237
  # move half
199
- def moveh(args)
238
+ def moveh(args={})
200
239
  if args.kind_of? Array
201
240
  x,y,z = args
202
241
  args = {x: x, y: y, z: z}
@@ -209,26 +248,49 @@ module JennCad
209
248
  end
210
249
  alias :mh :moveh
211
250
 
212
- def mhx(v)
251
+ def mhx(v=0)
213
252
  moveh(x:v)
214
253
  end
215
254
 
216
- def mhy(v)
255
+ def mhy(v=0)
217
256
  moveh(y:v)
218
257
  end
219
258
 
220
- def mhz(v)
259
+ def mhz(v=0)
221
260
  moveh(z:v)
222
261
  end
223
262
 
224
- def mirror(args)
263
+ def movei(args={})
264
+ to = {}
265
+ [:x, :y, :z, :xy, :xz, :yz, :xyz].each do |key|
266
+ if args[key]
267
+ to[key] = args[key]*-1
268
+ end
269
+ end
270
+ move(to)
271
+ end
272
+
273
+ def mirror(args={})
225
274
  @transformations ||= []
226
275
  @transformations << Mirror.new(args)
227
276
  self
228
277
  end
229
278
  alias :mi :mirror
230
279
 
231
- def scale(args)
280
+ def miz
281
+ mirror(z:1)
282
+ end
283
+
284
+ def miy
285
+ mirror(y:1)
286
+ end
287
+
288
+ def miz
289
+ mirror(z:1)
290
+ end
291
+
292
+
293
+ def scale(args={})
232
294
  if args.kind_of? Numeric or args.kind_of? Array
233
295
  args = {v:args}
234
296
  end
@@ -313,6 +375,11 @@ module JennCad
313
375
  end
314
376
  =end
315
377
 
378
+ def inherit_color(other)
379
+ self.set_option(:color, other.option(:color))
380
+ self.set_option(:auto_color, other.option(:auto_color))
381
+ end
382
+
316
383
  def has_explicit_color?
317
384
  if option(:auto_color) == false
318
385
  return true
@@ -1,4 +1,4 @@
1
1
  module JennCad
2
- VERSION = "1.0.0-alpha7"
2
+ VERSION = "1.0.0-alpha10"
3
3
  end
4
4
 
data/lib/jenncad.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require "logger"
2
+ $log = Logger.new(STDOUT)
3
+
1
4
  require "geo3d"
2
5
  require "deep_merge"
3
6
  require "fileutils"
data/todo.txt CHANGED
@@ -1,29 +1,59 @@
1
1
  1.0 required features
2
2
  ===================
3
3
 
4
- - cli needs to be a package manager for existing parts from a public library (i.e. bolts, motors go here), able to
5
- -- query
6
- -- download
7
- -- update
8
- (upload? -> probably git pull request for now)
9
- - add external projects into one another (for example: make parts, show arrangement of a shelf in another project)
10
-
11
4
  - slot with square ends -> rounded cube with one side = d + flat_edges does that. Should slot do that in reverse?
12
5
 
13
- - de-centering a cube in one direction sucks, you have to add both center: false, center_x: true
14
- -> decenter ?
15
-
16
6
  - bolt library needs to get a rewrite,
17
7
  - fetching dimensions from the imported Bolt library should be less awful
18
8
 
19
9
  - needs a documentation and showcase
20
10
 
11
+ Features wanted
12
+ ===================
13
+ 28.4.22:
14
+ - Parts often come with 4 holes around a center, and I often do something like:
15
+
16
+ [-1, 1].each do |i|
17
+ [-1, 1].each do |j|
18
+ res += @bolt.cut.move(x: @hole_center*i, y: @hole_center*j)
19
+ end
20
+ end
21
+
22
+ there should be a shorter way to do this.
23
+
24
+
25
+ - instead of moving Bolts output, make it the default to make their positions an anchor
26
+
27
+ - Bolt size data should be in a constant instead of one "Data" constant i.e.
28
+ M2_5.head_dia
29
+ M2_5.head_h
30
+ M2_5_hole
31
+
32
+ - Bolt sizes should follow user configuration that can change margins
33
+ - Bolts should have an easier way to align than mirror them, maybe from :top
34
+ - but also, when you have a part that can be mounted in any top/bottom direction, you always end up having the bolts facing the wrong direction..
35
+ - Bolts should be able to also make thread inserts
36
+
37
+
38
+
39
+
21
40
  other awful things
22
41
  ===================
23
42
 
24
- - command line interface isn't capable of adding parts to the output automatically
43
+ - cli needs to use templates and user defined templates, profile loader needs to have this.
25
44
 
26
45
  - user profile file should be auto generated with examples
27
46
 
28
- - switching back and forth from and to openscad for preview sucks (that being said, switching from vim to something else would be awful to me)
47
+
48
+ Future plans
49
+ ==================
50
+
51
+ - cli needs to be a package manager for existing parts from a public library (i.e. bolts, motors go here), able to
52
+ -- query
53
+ -- download
54
+ -- update
55
+ (upload? -> probably git pull request for now)
56
+ - add external projects into one another (for example: make parts, show arrangement of a shelf in another project)
57
+
58
+
29
59
 
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.alpha7
4
+ version: 1.0.0.pre.alpha10
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-22 00:00:00.000000000 Z
11
+ date: 2022-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: geo3d
@@ -80,6 +80,20 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: logger
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
83
97
  description: TBD
84
98
  email:
85
99
  - "=^.^=@jenncad.kittenme.ws"
@@ -88,17 +102,11 @@ executables:
88
102
  extensions: []
89
103
  extra_rdoc_files: []
90
104
  files:
105
+ - LICENSE
91
106
  - README.md
92
107
  - Rakefile
93
108
  - bin/jenncad
94
- - examples/old/cube.rb
95
- - examples/old/slot.rb
96
- - examples/old/test.rb
97
- - examples/old/test1.rb
98
- - examples/old/test2.rb
99
- - examples/old/test3.rb
100
- - examples/old/test4.rb
101
- - examples/old/test5.rb
109
+ - examples/README
102
110
  - jenncad.gemspec
103
111
  - lib/jenncad.rb
104
112
  - lib/jenncad/commands.rb
@@ -115,6 +123,7 @@ files:
115
123
  - lib/jenncad/features/cuttable.rb
116
124
  - lib/jenncad/features/feature.rb
117
125
  - lib/jenncad/features/openscad_include.rb
126
+ - lib/jenncad/features/path.rb
118
127
  - lib/jenncad/features/stl_import.rb
119
128
  - lib/jenncad/part.rb
120
129
  - lib/jenncad/patches/array.rb
@@ -168,7 +177,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
177
  - !ruby/object:Gem::Version
169
178
  version: 1.3.1
170
179
  requirements: []
171
- rubygems_version: 3.2.3
180
+ rubygems_version: 3.0.9
172
181
  signing_key:
173
182
  specification_version: 4
174
183
  summary: TBD
data/examples/old/cube.rb DELETED
@@ -1,12 +0,0 @@
1
- require 'rubygems'
2
- require 'jenncad'
3
- include JennCad
4
-
5
- # cubes are centered in x,y and flat to z=0 by default
6
- res = cube(40,30,20)
7
- # if symbols are omitted first argument of cylinder is d (diameter), second is height
8
- # if height is omitted, it will assume height of first suitable parent object. This only works for z direction
9
- # if height is omitted, it will also reward you with automatic z-fighting. For other cuts it'll try to do the same but is not so smart
10
- res -= cylinder(5)
11
-
12
- res.openscad("cube.scad")
data/examples/old/slot.rb DELETED
@@ -1,10 +0,0 @@
1
- require 'rubygems'
2
- require 'jenncad'
3
- include JennCad
4
-
5
- res = cube(30,30,10)
6
-
7
- res -= slot(d:10, x:20, a:30).move(x:5)
8
- res -= slot(d:10, x:20, a:-30).move(x:5)
9
-
10
- res.openscad("slot.scad")
data/examples/old/test.rb DELETED
@@ -1,18 +0,0 @@
1
- require 'jenncad'
2
- include JennCad
3
- include JennCad::Extras
4
- Nut = Din934
5
-
6
- res = cylinder(d:40,h:20)
7
-
8
- n = Nut.new(4)
9
- res -= n.cut
10
-
11
- n = Nut.new(4)
12
- res -= n.cut.translate(x:20)
13
- res += n.show.translate(x:20)
14
-
15
-
16
-
17
- a = OpenScad.new(res)
18
- a.save("examples/test1.scad")
@@ -1,21 +0,0 @@
1
- require 'rubygems'
2
- require 'jenncad'
3
- include JennCad
4
- include JennCad::Extras
5
- Nut = Din934
6
-
7
- h1 = 10
8
- h2 = 20
9
- res = cube([10,20,h1])
10
- res += cylinder(d:40,h:h2).move(z:h1)
11
-
12
-
13
- n = Nut.new(4)
14
- res -= n.cut
15
-
16
- n = Nut.new(4)
17
- res -= n.cut.move(z:h1+h2-n.height)
18
-
19
-
20
-
21
- res.openscad("examples/test1.scad")
@@ -1,9 +0,0 @@
1
- require 'jenncad'
2
- include JennCad
3
-
4
- res = import("involute_gears","bevel_gear",number_of_teeth:13, bore_diameter:10)
5
- res += import("involute_gears","bevel_gear",number_of_teeth:6, bore_diameter:5).rotate(x:90).translate(y:50,z:30)
6
-
7
-
8
- a = OpenScad.new(res)
9
- a.save("examples/test2.scad")
@@ -1,15 +0,0 @@
1
- require 'rubygems'
2
- require 'jenncad'
3
- include JennCad
4
- include JennCad::Extras
5
- Nut = Din934
6
-
7
- res = cylinder(d:40,h:20)
8
- res &= cylinder(d:40,h:20).translate(x:20)
9
- res &= cube([20,20,20]).translate(y:20)
10
-
11
- res.skew(y:-0.3)
12
-
13
-
14
- a = OpenScad.new(res)
15
- a.save("examples/test3.scad")