jenncad 1.0.0.pre.alpha19 → 1.0.0.pre.alpha22

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: 2088ad700952d85766093d0d494281c6117c0cf628a6307840131ec38314f832
4
- data.tar.gz: 2a68a98e3fcc5d3c6008f8907ad72eab028e95d8021aa432dec93cd21993dd95
3
+ metadata.gz: 655d1eab8f78d92f18915154cdc36a57fecfcb222e40dc69e663c974d5d85052
4
+ data.tar.gz: 79bd0ecee0ea0b3b691c4953ec33e68e1783248899d1e9417fe9cfac80e6fc46
5
5
  SHA512:
6
- metadata.gz: f96b42ef5e8f8ab836a900c96b83cbee8ed2c91cc0f83631e650adbc27d6e4ec2ba91cf5f94fa8424b420d4951a3a80cae52012e6d7013abdaf8b10e0c141283
7
- data.tar.gz: 80f3f16a02f07b664efed6ba0a25f786720269de165f98532c1ab18b674f11e86fb59cf62bd7a787777e9e71d9dcd9556184b0a637f7ec98aa1b6a494e23dcec
6
+ metadata.gz: 77c14e0645ff92f85f8746830469707d91495b7cf57d8d64210a0c2da7d7a6b0f9c27c3b4eb6fdcfdcd983a6d647b54309d4e10d2d407d70f7e55d02cd72ec9f
7
+ data.tar.gz: dd7538fb2068d4cb15326af37f7324d19c31828e3584b700f78ea585004790ee9033576e235e17774f007722f3b5a729d4a6a4c75f9c9fd2a0e2b0ee33e59bb4
@@ -46,6 +46,7 @@ module JennCad
46
46
 
47
47
  class Build < Run
48
48
  option :binary, type: :boolean, default: false, desc: "run through admesh to create a binary stl"
49
+ option :only_print, type: :boolean, default: true, desc: "If a part has a print orientation set, only build that orientation as STL"
49
50
 
50
51
  def build(options)
51
52
  if options[:binary]
@@ -55,7 +56,13 @@ module JennCad
55
56
  end
56
57
  end
57
58
 
58
- Dir.glob("output/**/*.scad").each do |file|
59
+ files = Dir.glob("output/**/*.scad")
60
+ if options[:only_print]
61
+ # Remove non _print.scad files from the list of files to build if we have a print orientation (and the only_print flag set)
62
+ files -= Dir.glob("output/**/*_print.scad").map{|x| x.gsub("_print.scad",".scad")}
63
+ end
64
+
65
+ files.each do |file|
59
66
  stl = file.gsub(".scad",".stl")
60
67
  build_stl(file, stl)
61
68
  convert_to_binary(stl) if options[:binary] && admesh_installed
@@ -95,6 +95,9 @@ module JennCad::Exporters
95
95
  if v == nil
96
96
  next
97
97
  end
98
+ if v.kind_of?(Symbol)
99
+ v = v.to_s
100
+ end
98
101
  if v.kind_of?(Array)
99
102
  v = handle_args(v)
100
103
  elsif !v.kind_of?(TrueClass) && !v.kind_of?(FalseClass) && v == v.to_i
@@ -172,6 +175,8 @@ module JennCad::Exporters
172
175
  prim('circle', part)
173
176
  when JennCad::Primitives::Square
174
177
  prim('square', part)
178
+ when JennCad::Primitives::Text
179
+ prim('text', part)
175
180
  when JennCad::Primitives::LinearExtrude
176
181
  new_obj(part, :linear_extrude, part.openscad_params, parse(part.parts))
177
182
  when JennCad::Primitives::RotateExtrude
@@ -7,9 +7,6 @@ require "jenncad/features/stl_import"
7
7
  require "jenncad/features/path"
8
8
  require "jenncad/features/multiples_of"
9
9
 
10
-
11
-
12
-
13
10
  module JennCad
14
11
  include Features
15
12
  end
data/lib/jenncad/part.rb CHANGED
@@ -10,6 +10,8 @@ end
10
10
  module JennCad
11
11
  # Part should be inherited from the user when making parts
12
12
  class Part < Thing
13
+ attr_accessor :d
14
+
13
15
  def self.inherited(subclass)
14
16
  subclass.prepend(AutoName) if subclass.superclass == Part
15
17
  end
@@ -0,0 +1,138 @@
1
+ module JennCad
2
+ class Size
3
+ attr_accessor :size
4
+ def initialize(args={})
5
+ @size = {
6
+ x: args[:x].to_d,
7
+ y: args[:y].to_d,
8
+ z: (args[:z] || args[:h]).to_d,
9
+ d: args[:d].to_d,
10
+ }
11
+ end
12
+
13
+ def add(other)
14
+ return self if other.nil?
15
+ @size[:x] += other.x
16
+ @size[:y] += other.y
17
+ @size[:z] += other.z
18
+ @size[:d] += other.d
19
+ self
20
+ end
21
+
22
+ def union(other)
23
+ @size[:x] = [@size[:x], other.x].max
24
+ @size[:y] = [@size[:y], other.y].max
25
+ @size[:z] = [@size[:z], other.z].max
26
+ @size[:d] = [@size[:d], other.d].max
27
+ self
28
+ end
29
+
30
+ def to_point
31
+ Point.new(x: @size[:x], y: @size[:y], z: @size[:z])
32
+ end
33
+
34
+ def set(a, to)
35
+ @size[a] = to
36
+ end
37
+
38
+ def x
39
+ @size[:x]
40
+ end
41
+
42
+ def y
43
+ @size[:y]
44
+ end
45
+
46
+ def z
47
+ @size[:z]
48
+ end
49
+
50
+ def d
51
+ @size[:d]
52
+ end
53
+
54
+ end
55
+
56
+ class Point
57
+ attr_accessor :pos
58
+ def initialize(args={})
59
+ @pos = {x: 0.to_d, y: 0.to_d, z: 0.to_d}
60
+ add(args)
61
+ end
62
+
63
+ def x
64
+ @pos[:x]
65
+ end
66
+
67
+ def y
68
+ @pos[:y]
69
+ end
70
+
71
+ def z
72
+ @pos[:z]
73
+ end
74
+
75
+ def zero?
76
+ return true if x == 0.0 && y == 0.0 && z == 0.0
77
+ false
78
+ end
79
+
80
+ def to_a
81
+ if @z != 0.0
82
+ [@pos[:x], @pos[:y], @pos[:z]]
83
+ else
84
+ [@pos[:x], @pos[:y]]
85
+ end
86
+ end
87
+
88
+ def to_h
89
+ @pos.clone.delete_if{|k,v| v.to_d == 0.0}
90
+ end
91
+
92
+ def add(args)
93
+ if args.kind_of? Point
94
+ @pos[:x] += args.x
95
+ @pos[:y] += args.y
96
+ @pos[:z] += args.z
97
+ return self
98
+ end
99
+
100
+ args.each do |k, val|
101
+ if [:chain, :debug].include? k
102
+ next
103
+ end
104
+ unless val.kind_of? Numeric
105
+ next
106
+ end
107
+ if val.to_d == 0.0
108
+ next
109
+ end
110
+
111
+ keys = k.to_s.chars
112
+ axis = []
113
+ axis << keys.delete("x")
114
+ axis << keys.delete("y")
115
+ axis << keys.delete("z")
116
+ multi = 1
117
+
118
+ if keys.size > 0
119
+ if keys.include?("h")
120
+ multi = 0.5
121
+ elsif keys.include?("q")
122
+ multi = 0.25
123
+ elsif keys.include?("d")
124
+ multi = 2.0
125
+ end
126
+ if keys.include?("n") || keys.include?("i")
127
+ multi *= -1
128
+ end
129
+ end
130
+ axis.compact.each do |a|
131
+ @pos[a.to_sym] += val.to_d * multi.to_d
132
+ end
133
+ end
134
+ self
135
+ end
136
+ end
137
+
138
+ end
@@ -7,11 +7,19 @@ module JennCad::Primitives
7
7
  else
8
8
  @parts = parts
9
9
  end
10
+
11
+ if @parts.first.respond_to? :anchors
12
+ @anchors = @parts.first.anchors
13
+ end
14
+
10
15
  if parts.first && parts.first.respond_to?(:debug?) && parts.first.debug?
11
- $log.debug("Creating new #{self.class} for part #{parts}")
16
+ $log.debug("Creating new #{self.class} for part #{parts.pretty_inspect}")
12
17
  end
13
18
 
14
- @parent = @parts.first.parent
19
+
20
+ @parent = @parts.first.parent if @parts.first
21
+ @csize = @parts.first.csize if @parts.first
22
+ @csize ||= Size.new
15
23
 
16
24
  after_add
17
25
  end
@@ -1,5 +1,7 @@
1
1
  module JennCad::Primitives
2
2
  class Circle < Primitive
3
+ include CircleIsh
4
+
3
5
  attr_accessor :d, :r, :fn
4
6
  def initialize(args)
5
7
  if args.kind_of?(Array) && args[0].kind_of?(Hash)
@@ -36,21 +38,7 @@ module JennCad::Primitives
36
38
  handle_radius_diameter
37
39
  handle_fn
38
40
  set_anchors_2d
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
41
+ @csize = Size.new(d: @opts[:d])
54
42
  end
55
43
 
56
44
  def openscad_params
@@ -61,49 +49,6 @@ module JennCad::Primitives
61
49
  res
62
50
  end
63
51
 
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
52
 
108
53
  end
109
54
  end
@@ -1,6 +1,7 @@
1
1
  module JennCad::Primitives
2
2
  class Cube < Square
3
3
  extend JennCad::Features::Cuttable
4
+ include ZIsh
4
5
 
5
6
  def initialize(args)
6
7
  @opts = {
@@ -26,27 +27,19 @@ module JennCad::Primitives
26
27
  end
27
28
  init
28
29
 
29
-
30
30
  handle_margins
31
31
  @h = @z.dup
32
32
  @calc_h = @z.dup
33
33
 
34
34
  @dimensions = [:x, :y, :z]
35
+ @csize = Size.new(x: @opts[:x], y: @opts[:y], z: @opts[:z])
35
36
 
36
37
  set_anchors
37
38
  end
38
39
 
39
40
  def set_anchors
40
41
  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
44
- else
45
- set_anchor :bottom_face, z: 0
46
- set_anchor :top_face, z: @z
47
- end
48
-
49
-
42
+ set_anchors_z
50
43
  end
51
44
 
52
45
  # used for openscad export
@@ -54,13 +47,6 @@ module JennCad::Primitives
54
47
  [@x, @y, z+z_margin]
55
48
  end
56
49
 
57
- def cz
58
- nc
59
- @opts[:center_z] = true
60
- set_anchors
61
- self
62
- end
63
- alias :center_z :cz
64
50
 
65
51
  end
66
52
  end
@@ -1,5 +1,6 @@
1
1
  module JennCad::Primitives
2
2
  class Cylinder < Circle
3
+ include ZIsh
3
4
  attr_accessor :d, :d1, :d2, :r, :fn, :anchors
4
5
  def initialize(args)
5
6
  if args.kind_of?(Array) && args[0].kind_of?(Hash)
@@ -15,7 +16,7 @@ module JennCad::Primitives
15
16
  end
16
17
 
17
18
  args[:z] ||= args[:h]
18
-
19
+ args[:center_z] ||= args[:cz]
19
20
  @opts = {
20
21
  d: 0,
21
22
  d1: nil,
@@ -24,7 +25,7 @@ module JennCad::Primitives
24
25
  r2: nil,
25
26
  z: nil,
26
27
  r: 0,
27
- cz: false,
28
+ center_z: false,
28
29
  margins: {
29
30
  r: 0,
30
31
  d: 0,
@@ -43,22 +44,16 @@ module JennCad::Primitives
43
44
  handle_fn
44
45
  @dimensions = [:x, :y, :z]
45
46
  set_anchors
47
+ @csize = Size.new(x: @opts[:d], y: @opts[:d], d: @opts[:d], z: @z)
46
48
  end
47
49
 
48
50
  def set_anchors
49
51
  set_anchors_2d
52
+ set_anchors_z
50
53
  # TODO: figure out if we also want to have "corners"
51
54
  # - possibly move it like a cube
52
55
  # - points at 45 ° angles might not be that useful unless you can get the point on the circle at a given angle
53
56
  # - inner/outer points could be useful for small $fn values
54
-
55
- if @opts[:cz]
56
- set_anchor :bottom_face, z: -@z/2.0
57
- set_anchor :top_face, z: @z/2.0
58
- else
59
- set_anchor :bottom_face, z: 0
60
- set_anchor :top_face, z: @z
61
- end
62
57
  end
63
58
 
64
59
  def openscad_params
@@ -78,7 +73,7 @@ module JennCad::Primitives
78
73
  # Centers the cylinder around it's center point by height
79
74
  # This will transform the cylinder around the center point.
80
75
  def cz
81
- @opts[:cz] = true
76
+ @opts[:center_z] = true
82
77
  @transformations ||= []
83
78
  @transformations << Move.new(z: -@z / 2.0)
84
79
  set_anchors
@@ -1,24 +1,36 @@
1
1
  module JennCad::Primitives
2
+ include ZIsh
2
3
  attr_accessor :center_bool, :convexity, :twist, :slices
4
+
3
5
  class LinearExtrude < JennCad::Thing
4
6
  def initialize(part, args={})
5
7
  @transformations = []
6
8
  @parts = [part]
9
+ if args.kind_of? Numeric
10
+ args = {h: args}
11
+ end
7
12
  @z = args[:h] || args[:height] || args[:z]
13
+ @csize = Size.new(z: @z).add(part.csize)
14
+
8
15
  @center_bool = args[:center]
9
16
  @convexity = args[:convexity]
10
17
  @twist = args[:twist]
11
18
  @slices = args[:slices]
12
19
  @fn = args[:fn]
13
20
  @opts = {
21
+ center_z: false,
14
22
  margins: {
15
23
  z: 0,
16
24
  }
17
25
  }.deep_merge(args)
26
+ set_anchors_z
27
+
28
+ @x = part.x
29
+ @y = part.y
18
30
  end
19
31
 
20
32
  def height
21
- @z.to_d + @opts[:margins][:z].to_d
33
+ @z.to_d + z_margin
22
34
  end
23
35
 
24
36
  def openscad_params
@@ -44,6 +44,8 @@ module JennCad::Primitives
44
44
  feed_opts(parse_xyz_shortcuts(args))
45
45
  end
46
46
  init(args)
47
+ @d = opts[:d]
48
+ @csize = Size.new(x: @opts[:x], y: @opts[:y], z: @opts[:z])
47
49
 
48
50
  handle_margins
49
51
  handle_diameter
@@ -52,6 +54,7 @@ module JennCad::Primitives
52
54
  else
53
55
  @dimensions = [:x, :y]
54
56
  end
57
+
55
58
  set_anchors
56
59
  end
57
60
 
@@ -59,28 +62,28 @@ module JennCad::Primitives
59
62
  # FIXME: this check needs to be done on object creation
60
63
  # otherwise it fails to position it
61
64
  if @d == 0
62
- if @z.to_d > 0
65
+ if @csize.z.to_d > 0
63
66
  return cube(@opts)
64
67
  else
65
68
  return square(@opts)
66
69
  end
67
70
  end
68
71
  # make diameter not bigger than any side
69
- d = [@d, @x, @y].min
72
+ d = [@d, @csize.x, @csize.y].min
70
73
  res = HullObject.new(
71
74
  circle(d: d),
72
- circle(d: d).move(x: @x - d, y: 0),
73
- circle(d: d).move(x: 0, y: @y - d),
74
- circle(d: d).move(x: @x - d, y: @y - d),
75
+ circle(d: d).move(x: @csize.x - d, y: 0),
76
+ circle(d: d).move(x: 0, y: @csize.y - d),
77
+ circle(d: d).move(x: @csize.x - d, y: @csize.y - d),
75
78
  )
76
- res = res.move(xy: d/2.0)
79
+ res = res.move(xyh: d)
77
80
 
78
81
  @opts[:flat_edges].each do |edge|
79
82
  res += apply_flat_edge(edge)
80
83
  end
81
84
 
82
- if @z.to_d > 0
83
- res = res.extrude(z: @z + z_margin)
85
+ if @csize.z.to_d > 0
86
+ res = res.extrude(z: @csize.z + z_margin)
84
87
  end
85
88
 
86
89
  res = union(res) # put everything we have in a parent union that we can apply the transformations of this object of
@@ -103,13 +106,13 @@ module JennCad::Primitives
103
106
  def apply_flat_edge(edge)
104
107
  case edge
105
108
  when :up, :top
106
- square(x: @x, y: @y/2.0).nc.moveh(y:@y)
109
+ square(x: @csize.x, y: @csize.y/2.0).nc.moveh(y:@csize.y)
107
110
  when :down, :bottom
108
- square(x: @x, y: @y/2.0).nc
111
+ square(x: @csize.x, y: @csize.y/2.0).nc
109
112
  when :right
110
- square(x: @x/2.0, y: @y).nc.moveh(x:@x)
113
+ square(x: @csize.x/2.0, y: @csize.y).nc.moveh(x:@csize.x)
111
114
  when :left
112
- square(x: @x/2.0, y: @y).nc
115
+ square(x: @csize.x/2.0, y: @csize.y).nc
113
116
  else
114
117
  nil
115
118
  end
@@ -1,5 +1,6 @@
1
1
  module JennCad::Primitives
2
2
  class Slot < Primitive
3
+ include CircleIsh
3
4
  attr_accessor :d, :r, :h, :fn, :len_x, :len_y
4
5
 
5
6
  def initialize(args)
@@ -28,7 +29,11 @@ module JennCad::Primitives
28
29
  x: 0,
29
30
  y: 0,
30
31
  z: nil,
32
+ d1: nil,
33
+ d2: nil,
34
+ mode: :auto,
31
35
  cz: false,
36
+ az: false,
32
37
  margins: {
33
38
  r: 0,
34
39
  d: 0,
@@ -60,9 +65,12 @@ module JennCad::Primitives
60
65
  if ty
61
66
  @len_y = ty - @d
62
67
  end
68
+ if @opts[:z] && opts[:z].to_d > 0
69
+ @dimensions = [:x, :y, :z]
70
+ else
71
+ @dimensions = [:x, :y]
72
+ end
63
73
 
64
- # TODO: this needs anchors like cube
65
- # TODO: color on this needs to apply to hull, not on the cylinders.
66
74
  set_anchors
67
75
  end
68
76
 
@@ -76,11 +84,7 @@ module JennCad::Primitives
76
84
 
77
85
  def set_anchors
78
86
  @anchors = {} # reset anchors
79
- if @opts[:d]
80
- rad = @opts[:d] / 2.0
81
- else
82
- rad = @opts[:r]
83
- end
87
+ rad = radius
84
88
 
85
89
  if @x > 0
86
90
  set_anchor :left, x: - rad
@@ -120,9 +124,39 @@ module JennCad::Primitives
120
124
  end
121
125
  end
122
126
 
127
+ def get_mode
128
+ if @opts[:d1] && @opts[:d2]
129
+ case @opts[:mode]
130
+ when nil, :auto
131
+ :dia1
132
+ when :cyl
133
+ :cyl
134
+ else
135
+ :dia1
136
+ end
137
+ else
138
+ :default
139
+ end
140
+ end
141
+
123
142
  def to_openscad
124
- c1 = cylinder(@opts)
125
- c2 = cylinder(@opts)
143
+ mode = get_mode
144
+
145
+ opts = @opts.clone
146
+ opts.delete(:color)
147
+
148
+ case mode
149
+ when :default
150
+ c1 = ci(opts)
151
+ c2 = ci(opts)
152
+ when :dia1 # new default mode; d1 start dia, d2 end dia
153
+ c1 = ci(opts.merge(d: @opts[:d1]))
154
+ c2 = ci(opts.merge(d: @opts[:d2]))
155
+ when :cyl # old mode; use cylinders
156
+ c1 = cy(opts)
157
+ c2 = cy(opts)
158
+ end
159
+
126
160
  if @len_x
127
161
  c2.move(x:@len_x)
128
162
  end
@@ -130,6 +164,14 @@ module JennCad::Primitives
130
164
  c2.move(y:@len_y)
131
165
  end
132
166
  res = c1 & c2
167
+ if mode != :cyl && @z.to_d > 0
168
+ res = res.e(@z)
169
+ elsif @opts[:az] == true
170
+ # TODO: this needs testing, may not work
171
+ res = res.auto_extrude
172
+ end
173
+ res.inherit_color(self)
174
+
133
175
  if @a != 0.0
134
176
  res = res.rotate(z:@a)
135
177
  end
@@ -28,6 +28,8 @@ module JennCad::Primitives
28
28
  @x = args[:x]
29
29
  @y = args[:y]
30
30
  @dimensions = [:x, :y]
31
+ @sits_on = :bottom
32
+ @csize = Size.new(x: @opts[:x], y: @opts[:y])
31
33
  end
32
34
 
33
35
 
@@ -42,6 +44,8 @@ module JennCad::Primitives
42
44
 
43
45
  def set_anchors_2d
44
46
  @anchors = {} # this resets anchors
47
+ @corners = [:top_right, :top_left, :bottom_right, :bottom_left]
48
+ @sides = [:left, :right, :top, :bottom]
45
49
 
46
50
  if @opts[:center] || @opts[:center_x]
47
51
  left = -@opts[:x] / 2.0
@@ -135,8 +139,6 @@ module JennCad::Primitives
135
139
  self
136
140
  end
137
141
 
138
-
139
-
140
142
  def not_centered
141
143
  @opts[:center] = false
142
144
  set_anchors
@@ -160,8 +162,6 @@ module JennCad::Primitives
160
162
  end
161
163
  alias :center_y :cy
162
164
 
163
-
164
-
165
165
  def centered_axis
166
166
  return [:x, :y] if @opts[:center]
167
167
  a = []
@@ -172,10 +172,8 @@ module JennCad::Primitives
172
172
  end
173
173
 
174
174
  def to_openscad
175
- self.mh(centered_axis.to_h{|a| [a, -@opts[a]] }) # center cube
175
+ self.mh(centered_axis.to_h{|a| [a, -@opts[a]] }.merge(prepend: true)) # center cube
176
176
  end
177
177
 
178
-
179
-
180
178
  end
181
179
  end