jenncad 1.0.0.pre.alpha8 → 1.0.0.pre.alpha11

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -46,8 +47,102 @@ module JennCad::Primitives
46
47
  super(z: @opts[:z])
47
48
  @h = @z.dup
48
49
  @calc_h = @z.dup
50
+
51
+
52
+ set_anchors
53
+ end
54
+
55
+ 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
71
+ else
72
+ bottom = 0
73
+ top = @opts[:y]
74
+ mid_y = @opts[:y] / 2.0
75
+ end
76
+
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
+
93
+ self
49
94
  end
50
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
+
51
146
  # used for openscad export
52
147
  def size
53
148
  [@x, @y, z+z_margin]
@@ -55,6 +150,7 @@ module JennCad::Primitives
55
150
 
56
151
  def not_centered
57
152
  @opts[:center] = false
153
+ set_anchors
58
154
  self
59
155
  end
60
156
  alias :nc :not_centered
@@ -62,20 +158,27 @@ module JennCad::Primitives
62
158
  def cx
63
159
  nc
64
160
  @opts[:center_x] = true
161
+ set_anchors
65
162
  self
66
163
  end
164
+ alias :center_x :cx
67
165
 
68
166
  def cy
69
167
  nc
70
168
  @opts[:center_y] = true
169
+ set_anchors
71
170
  self
72
171
  end
172
+ alias :center_y :cy
173
+
73
174
 
74
175
  def cz
75
176
  nc
76
177
  @opts[:center_z] = true
178
+ set_anchors
77
179
  self
78
180
  end
181
+ alias :center_z :cz
79
182
 
80
183
  def centered_axis
81
184
  return [:x, :y] if @opts[:center]
@@ -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,
@@ -45,32 +45,42 @@ module JennCad::Primitives
45
45
  # make diameter not bigger than any side
46
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)
58
64
  res
59
65
  end
60
66
 
61
- def flat_edge(edge)
67
+ def flat(edge)
68
+ @opts[:flat_edges] ||= []
69
+ @opts[:flat_edges] << edge
70
+ self
71
+ end
72
+
73
+ private
74
+ def apply_flat_edge(edge)
62
75
  case edge
63
- when Array
64
- #ruby2.7 test- edge.map(&self.:flat_edge)
65
- edge.map{|x| flat_edge(x) }
66
76
  when :up
67
- 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)
68
78
  when :down
69
- cube(@x, @y/2.0, @z).moveh(y:-@y/2.0)
79
+ cube(x: @x, y: @y/2.0, z: @z).nc
70
80
  when :right
71
- 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)
72
82
  when :left
73
- cube(@x/2.0, @y, @z).moveh(x:-@x/2.0)
83
+ cube(x: @x/2.0, y: @y, z: @z).nc
74
84
  else
75
85
  nil
76
86
  end
@@ -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)
@@ -57,9 +63,8 @@ module JennCad::Primitives
57
63
  case part
58
64
  when JennCad::Circle
59
65
  when JennCad::BooleanObject
60
- when JennCad::Aggregation
61
66
  else
62
- pp part if part.opts[:debug]
67
+ $log.debug part if part.opts[:debug]
63
68
  part.opts[:margins][:z] ||= 0.0
64
69
  unless part.opts[:margins][:z] == 0.2
65
70
  part.opts[:margins][:z] = 0.2
@@ -67,7 +72,7 @@ module JennCad::Primitives
67
72
  end
68
73
  end
69
74
  elsif part.z == compare_h
70
- # puts "fixing possible z fighting: #{part.class} #{part.z}"
75
+ $log.debug "fixing possible z fighting: #{part.class} #{part.z}" if part.opts[:debug]
71
76
  part.opts[:margins][:z] += 0.008
72
77
  part.mz(-0.004)
73
78
  elsif part.calc_z == compare_z
@@ -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,8 @@ 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]
19
22
  @opts ||= args
20
23
  end
21
24
 
@@ -29,34 +32,30 @@ module JennCad
29
32
  @opts[key] = val
30
33
  end
31
34
 
32
- def set_anchor(args)
33
- self.anchor ||= {}
34
- args.each do |key, val|
35
- self.anchor[key] = val
36
- end
35
+ def set_parent(parent)
36
+ @parent = parent
37
+ self
37
38
  end
38
39
 
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)
40
+ def anchor(name, thing=nil)
41
+ if thing
42
+ return thing.anchor(name)
47
43
  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
44
+ @anchors ||= {}
45
+ if anch = @anchors[name]
46
+ return anch
47
+ elsif @parent
48
+ return @parent.anchor(name)
56
49
  end
57
- move(to)
58
50
  end
51
+ alias :a :anchor
59
52
 
53
+ def set_anchor(name, args={})
54
+ @anchors ||= {}
55
+ @anchors[name] = args
56
+ self
57
+ end
58
+ alias :sa :set_anchor
60
59
 
61
60
  def auto_extrude
62
61
  ret = self.extrude
@@ -138,10 +137,18 @@ module JennCad
138
137
  end
139
138
 
140
139
  def parse_xyz_shortcuts(args)
140
+ unless args.kind_of? Hash
141
+ $log.warn "parse_xyz_shortcuts called for type #{args.class} #{args.inspect}"
142
+ return args
143
+ end
141
144
  [:x, :y, :z].each do |key|
142
145
  args[key] ||= 0.0
143
146
  end
144
147
 
148
+ if args[:debug]
149
+ $log.debug "Args: #{args}"
150
+ end
151
+
145
152
  if args[:xy]
146
153
  args[:x] += args[:xy]
147
154
  args[:y] += args[:xy]
@@ -159,10 +166,14 @@ module JennCad
159
166
  args[:y] += args[:yz]
160
167
  args[:z] += args[:yz]
161
168
  end
162
- return args
169
+ if args[:debug]
170
+ $log.debug "After xyz shortcuts #{args}"
171
+ end
172
+
173
+ return args
163
174
  end
164
175
 
165
- def move(args)
176
+ def move(args={})
166
177
  if args.kind_of? Array
167
178
  x,y,z = args
168
179
  return move(x:x, y:y, z:z)
@@ -183,20 +194,45 @@ module JennCad
183
194
  alias :translate :move
184
195
  alias :m :move
185
196
 
186
- def mx(v)
197
+ def mx(v=0)
187
198
  move(x:v)
188
199
  end
189
200
 
190
- def my(v)
201
+ def my(v=0)
191
202
  move(y:v)
192
203
  end
193
204
 
194
- def mz(v)
205
+ def mz(v=0)
195
206
  move(z:v)
196
207
  end
197
208
 
209
+ # move to anchor
210
+ def movea(key, thing=nil)
211
+ an = anchor(key, thing)
212
+ unless an
213
+ $log.error "Error: Anchor #{key} not found"
214
+ $log.error "Available anchors: #{@anchors}"
215
+ return self
216
+ else
217
+ self.move(an.dup)
218
+ end
219
+ end
220
+
221
+ # move to anchor - inverted
222
+ def moveai(key, thing=nil)
223
+ an = anchor(key, thing)
224
+ unless an
225
+ $log.error "Error: Anchor #{key} not found"
226
+ $log.error "Available anchors: #{@anchors}"
227
+ return self
228
+ else
229
+ self.movei(an.dup)
230
+ end
231
+ end
232
+
233
+
198
234
  # move half
199
- def moveh(args)
235
+ def moveh(args={})
200
236
  if args.kind_of? Array
201
237
  x,y,z = args
202
238
  args = {x: x, y: y, z: z}
@@ -209,26 +245,49 @@ module JennCad
209
245
  end
210
246
  alias :mh :moveh
211
247
 
212
- def mhx(v)
248
+ def mhx(v=0)
213
249
  moveh(x:v)
214
250
  end
215
251
 
216
- def mhy(v)
252
+ def mhy(v=0)
217
253
  moveh(y:v)
218
254
  end
219
255
 
220
- def mhz(v)
256
+ def mhz(v=0)
221
257
  moveh(z:v)
222
258
  end
223
259
 
224
- def mirror(args)
260
+ def movei(args={})
261
+ to = {}
262
+ [:x, :y, :z, :xy, :xz, :yz, :xyz].each do |key|
263
+ if args[key]
264
+ to[key] = args[key]*-1
265
+ end
266
+ end
267
+ move(to)
268
+ end
269
+
270
+ def mirror(args={})
225
271
  @transformations ||= []
226
272
  @transformations << Mirror.new(args)
227
273
  self
228
274
  end
229
275
  alias :mi :mirror
230
276
 
231
- def scale(args)
277
+ def miz
278
+ mirror(z:1)
279
+ end
280
+
281
+ def miy
282
+ mirror(y:1)
283
+ end
284
+
285
+ def miz
286
+ mirror(z:1)
287
+ end
288
+
289
+
290
+ def scale(args={})
232
291
  if args.kind_of? Numeric or args.kind_of? Array
233
292
  args = {v:args}
234
293
  end
@@ -313,6 +372,11 @@ module JennCad
313
372
  end
314
373
  =end
315
374
 
375
+ def inherit_color(other)
376
+ self.set_option(:color, other.option(:color))
377
+ self.set_option(:auto_color, other.option(:auto_color))
378
+ end
379
+
316
380
  def has_explicit_color?
317
381
  if option(:auto_color) == false
318
382
  return true
@@ -1,4 +1,4 @@
1
1
  module JennCad
2
- VERSION = "1.0.0-alpha8"
2
+ VERSION = "1.0.0-alpha11"
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.alpha8
4
+ version: 1.0.0.pre.alpha11
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-23 00:00:00.000000000 Z
11
+ date: 2022-04-30 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
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")