jenncad 1.0.0.pre.alpha1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +1 -0
  3. data/bin/jenncad +10 -0
  4. data/examples/old/cube.rb +12 -0
  5. data/examples/old/slot.rb +10 -0
  6. data/examples/old/test.rb +18 -0
  7. data/examples/old/test1.rb +21 -0
  8. data/examples/old/test2.rb +9 -0
  9. data/examples/old/test3.rb +15 -0
  10. data/examples/old/test4.rb +17 -0
  11. data/examples/old/test5.rb +31 -0
  12. data/jenncad.gemspec +27 -0
  13. data/lib/jenncad/commands.rb +169 -0
  14. data/lib/jenncad/default_profile.rb +40 -0
  15. data/lib/jenncad/extras/din912.rb +89 -0
  16. data/lib/jenncad/extras/din933.rb +64 -0
  17. data/lib/jenncad/extras/din934.rb +99 -0
  18. data/lib/jenncad/extras/hardware.rb +16 -0
  19. data/lib/jenncad/extras/iso7380.rb +58 -0
  20. data/lib/jenncad/jenncad.rb +3 -0
  21. data/lib/jenncad/openscad.rb +274 -0
  22. data/lib/jenncad/part.rb +14 -0
  23. data/lib/jenncad/patches/array.rb +29 -0
  24. data/lib/jenncad/primitives/aggregation.rb +12 -0
  25. data/lib/jenncad/primitives/boolean_object.rb +76 -0
  26. data/lib/jenncad/primitives/circle.rb +11 -0
  27. data/lib/jenncad/primitives/cube.rb +69 -0
  28. data/lib/jenncad/primitives/cylinder.rb +52 -0
  29. data/lib/jenncad/primitives/hull_object.rb +4 -0
  30. data/lib/jenncad/primitives/intersection_object.rb +4 -0
  31. data/lib/jenncad/primitives/linear_extrude.rb +25 -0
  32. data/lib/jenncad/primitives/openscad_include.rb +11 -0
  33. data/lib/jenncad/primitives/polygon.rb +9 -0
  34. data/lib/jenncad/primitives/primitive.rb +24 -0
  35. data/lib/jenncad/primitives/projection.rb +9 -0
  36. data/lib/jenncad/primitives/rotate_extrude.rb +20 -0
  37. data/lib/jenncad/primitives/rounded_cube.rb +77 -0
  38. data/lib/jenncad/primitives/slot.rb +82 -0
  39. data/lib/jenncad/primitives/sphere.rb +11 -0
  40. data/lib/jenncad/primitives/subtract_object.rb +84 -0
  41. data/lib/jenncad/primitives/union_object.rb +5 -0
  42. data/lib/jenncad/profile_loader.rb +34 -0
  43. data/lib/jenncad/project.rb +28 -0
  44. data/lib/jenncad/register.rb +31 -0
  45. data/lib/jenncad/shortcuts.rb +109 -0
  46. data/lib/jenncad/thing.rb +308 -0
  47. data/lib/jenncad/transformation/color.rb +8 -0
  48. data/lib/jenncad/transformation/mirror.rb +7 -0
  49. data/lib/jenncad/transformation/move.rb +7 -0
  50. data/lib/jenncad/transformation/multmatrix.rb +9 -0
  51. data/lib/jenncad/transformation/rotate.rb +7 -0
  52. data/lib/jenncad/transformation/scale.rb +7 -0
  53. data/lib/jenncad/transformation/transformation.rb +14 -0
  54. data/lib/jenncad/version.rb +4 -0
  55. data/lib/jenncad.rb +73 -0
  56. data/todo.txt +29 -0
  57. metadata +155 -0
@@ -0,0 +1,58 @@
1
+ module JennCad::Extras
2
+ class Iso7380 < Hardware
3
+ attr_accessor :height
4
+
5
+ def initialize(size,length,args={})
6
+ super(args)
7
+ @args = args
8
+ # options for output only:
9
+ @args[:additional_length] ||= 0
10
+ @args[:additional_diameter] ||= 0.3
11
+ @args[:head_margin] ||= 0.0
12
+
13
+ # if @args[:washer] == true
14
+ # @washer = Washer.new(size,{:material => @args[:material], :surface => @args[:surface]})
15
+ # end
16
+
17
+ @size = size
18
+ @length = length
19
+ @transformations ||= []
20
+ end
21
+
22
+ def cut
23
+ res = bolt_7380(@args[:additional_length], @args[:additional_diameter], @args[:head_margin])
24
+ Aggregation.new("iso7380c#{@size}#{option_string}", res)
25
+ end
26
+
27
+ def show
28
+ res = bolt_7380(0,0)
29
+ #if @washer
30
+ # res += @washer.show
31
+ # res = res.move(z:-@washer.height)
32
+ # end
33
+ res.color("DarkGray")
34
+ Aggregation.new("iso7380s#{@size}#{option_string}", res)
35
+ end
36
+
37
+ # ISO 7380
38
+ def bolt_7380(additional_length=0, addtional_diameter=0, head_margin=0)
39
+ if head_margin.to_f != 0
40
+ puts "[warning] :head_margin is not implemented for 7380 bolts"
41
+ end
42
+ chart_iso7380 = {
43
+ 3 => {head_dia:5.7,head_length:1.65},
44
+ 4 => {head_dia:7.6,head_length:2.2},
45
+ 5 => {head_dia:9.5,head_length:2.75},
46
+ 6 => {head_dia:10.5,head_length:3.3},
47
+ 8 => {head_dia:14,head_length:4.4},
48
+ 10=> {head_dia:17.5,head_length:5.5},
49
+ 12=> {head_dia:21,head_length:6.6},
50
+
51
+
52
+ }
53
+ res = cylinder(d1:chart_iso7380[@size][:head_dia]/2.0,d2:chart_iso7380[@size][:head_dia],h:chart_iso7380[@size][:head_length]).move(z:-chart_iso7380[@size][:head_length])
54
+ total_length = @length + additional_length
55
+ res+= cylinder(d:@size+addtional_diameter, h:total_length)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ module JennCad
2
+ include Primitives
3
+ end
@@ -0,0 +1,274 @@
1
+ module JennCad
2
+
3
+ class OpenScad
4
+ def initialize(part, fn=64)
5
+ @imports = []
6
+ @modules = {}
7
+ part = part.make_openscad_compatible
8
+ @main = root(part, "$fn=#{fn};\n")
9
+
10
+ @export = ""
11
+ @imports.uniq.each do |val|
12
+ @export += "use <#{val}.scad>\n"
13
+ end
14
+ @modules.each do |key, val|
15
+ @export += val
16
+ end
17
+ @export += @main
18
+ end
19
+
20
+ def save(file)
21
+ File.open(file,"w") do |f|
22
+ f.puts @export
23
+ end
24
+ end
25
+
26
+ def root(part, head="", tabindex=0)
27
+ res = head
28
+
29
+ res += transform(part) do
30
+ parse(part, tabindex)
31
+ end
32
+ res
33
+ end
34
+
35
+ def transform(part, &block)
36
+ res += handle_color(part)
37
+ if part.transformations
38
+ part.transformations.reverse.each do |trans|
39
+ res += transformation(trans)
40
+ end
41
+ end
42
+ res += block.yield
43
+ end
44
+
45
+ def print_tree(part, level=0)
46
+ arr = []
47
+ arr << parse(part) unless level == 0
48
+ if part.respond_to?(:parts)
49
+ part.parts.each do |p|
50
+ arr << print_tree(p,level+1)
51
+ end
52
+ end
53
+ arr
54
+ end
55
+
56
+
57
+ def parse(part, tabindex=0)
58
+ case part
59
+ when JennCad::OpenScadImport
60
+ handle_import(part)
61
+ when JennCad::Aggregation
62
+ handle_aggregation(part)
63
+ when JennCad::UnionObject
64
+ cmd('union', nil, part.parts, tabindex)
65
+ when JennCad::SubtractObject
66
+ part.analyze_z_fighting
67
+ cmd('difference', nil, part.parts, tabindex)
68
+ when JennCad::IntersectionObject
69
+ cmd('intersection', nil, part.parts, tabindex)
70
+ when JennCad::HullObject
71
+ cmd('hull', nil, part.parts, tabindex)
72
+ when JennCad::Primitives::Circle
73
+ cmd('circle', collect_params(part), nil, tabindex)
74
+ when JennCad::Primitives::Cylinder
75
+ cmd('cylinder', collect_params(part), nil, tabindex)
76
+ when JennCad::Primitives::Sphere
77
+ cmd('sphere', collect_params(part), nil, tabindex)
78
+ when JennCad::Primitives::Cube
79
+ handle_cube(part, tabindex)
80
+ when JennCad::Primitives::LinearExtrude
81
+ cmd('linear_extrude', part.openscad_params, part.parts, tabindex)
82
+ when JennCad::Primitives::RotateExtrude
83
+ cmd('rotate_extrude', part.openscad_params, part.parts, tabindex)
84
+ when JennCad::Primitives::Projection
85
+ cmd('projection', collect_params(part), part.parts, tabindex)
86
+ when JennCad::Primitives::Polygon
87
+ cmd('polygon', collect_params(part), nil, tabindex)
88
+ else
89
+ if part.respond_to?(:parts) && part.parts != nil && !part.parts.empty?
90
+ res = ""
91
+ part.parts.each do |p|
92
+ res += root(p, "", tabindex)
93
+ end
94
+ return res
95
+ elsif part.respond_to?(:part)
96
+ return root(part.part, "", tabindex)
97
+ end
98
+ puts "no idea what to do with #{part.inspect}"
99
+ return ""
100
+ end
101
+ end
102
+
103
+ def fmt_params(args)
104
+ return "" if args == nil
105
+ if args.kind_of? String
106
+ return "\"#{args}\""
107
+ elsif args.kind_of? Array
108
+ return args.map do |l|
109
+ if l == nil
110
+ 0
111
+ elsif l.kind_of? Array
112
+ l # skipping check of 2-dmin Arrays for now (used in multmatrix)
113
+ elsif l.to_i == l.to_f
114
+ l.to_i
115
+ else
116
+ l.to_f
117
+ end
118
+ end
119
+ else
120
+ res = []
121
+ args.each do |k,v|
122
+ if k.to_s == "fn"
123
+ k = "$fn"
124
+ end
125
+ if v == nil
126
+ next
127
+ end
128
+ if !v.kind_of?(Array) && !v.kind_of?(TrueClass) && !v.kind_of?(FalseClass) && v == v.to_i
129
+ v = v.to_i
130
+ end
131
+ res << "#{k}=#{v}"
132
+ end
133
+ res.join(",")
134
+ end
135
+ end
136
+
137
+ def cmd(name, args, items, tabindex = 0)
138
+ items ||= []
139
+ res = cmd_call(name,args)
140
+ if items.size > 1
141
+ res << "\n"
142
+ res << tabs(tabindex) { "{\n" }
143
+ items.each do |item|
144
+ res << tabs(tabindex+1) do
145
+ transform(item) do
146
+ parse(item, tabindex+1)
147
+ end
148
+ end
149
+ end
150
+ res << tabs(tabindex) { "}\n" }
151
+ elsif items.size == 1
152
+ item = items.first
153
+ res << transform(item) do
154
+ parse(item, tabindex)
155
+ end
156
+ res << ";\n"
157
+ else
158
+ res << ";\n"
159
+ end
160
+ return res
161
+ end
162
+
163
+ def tabs(i, &block)
164
+ " " * i + block.yield
165
+ end
166
+
167
+ def handle_import(part, tabindex=0)
168
+ @imports << part.import
169
+ return tabs(tabindex){ "#{part.name}(#{fmt_params(part.args)});\n" }
170
+ end
171
+
172
+ def handle_aggregation(part, tabindex=0)
173
+ register_module(part) unless @modules[part.name]
174
+ use_module(part.name, tabindex)
175
+ end
176
+
177
+ # check children for color values
178
+ # if none of the children has a color value, we can apply color to this object and all children
179
+ # if any of the children (excluding children of the kind of BooleanObject) has a color value (that is different from ours), we will apply a fallback color to all children that do not have a color value themselves.
180
+
181
+ def handle_color(part)
182
+ if part && part.respond_to?(:color) && part.color
183
+ if part.respond_to?(:parts)
184
+ if part.children_list(JennCad::Aggregation).map{|l| l.color != nil && l.color != part.color}.include?(true)
185
+ part.children_list(JennCad::Aggregation).each do |child|
186
+ if child.color == nil && child.color != part.color && !child.kind_of?(BooleanObject)
187
+ child.set_option :fallback_color, part.color
188
+ end
189
+ end
190
+ return ""
191
+ end
192
+ end
193
+ end
194
+ return apply_color(part)
195
+ end
196
+
197
+ def apply_color(part)
198
+ if part && part.respond_to?(:color_or_fallback)
199
+ color = part.color_or_fallback
200
+ return "" if color == nil
201
+ # Allowing color to be string, OpenScad compatible RGBA values of 0..1 or RGBA values of 0..255
202
+ if color.kind_of?(Array) && color.map{|l| l.to_f > 1.0 ? true : false}.include?(true)
203
+ color = color.map{|l| l.to_f/255.0}
204
+ end
205
+ return cmd_call("color", color)
206
+ end
207
+ return ""
208
+ end
209
+
210
+ def register_module(part)
211
+ # can only accept aggregation
212
+ @modules[part.name] = "module #{part.name}(){\n"
213
+ @modules[part.name] += root(part.part)
214
+ @modules[part.name] += "}\n"
215
+ end
216
+
217
+ def use_module(name, tabindex)
218
+ tabs(tabindex){ cmd_call(name, nil).to_s+";" }
219
+ end
220
+
221
+ def cmd_call(name, args)
222
+ args = fmt_params(args)
223
+ return "#{name}(#{args})"
224
+ end
225
+
226
+ def collect_params(part)
227
+ res = {}
228
+ [:d, :r, :h, :r1, :r2, :d1, :d2, :size, :fn, :points].each do |var|
229
+ if part.respond_to? var
230
+ res[var] = part.send var
231
+ end
232
+ end
233
+ res
234
+ end
235
+
236
+ def transformation(trans)
237
+ case trans
238
+ when JennCad::Move
239
+ cmd_call("translate",trans.coordinates)
240
+ when JennCad::Rotate
241
+ cmd_call("rotate",trans.coordinates)
242
+ when JennCad::Mirror
243
+ cmd_call("mirror",trans.coordinates)
244
+ when JennCad::Multmatrix
245
+ cmd_call("multmatrix",trans.m)
246
+ else
247
+ puts "[openscad exporter] Unkown transformation #{trans.class}"
248
+ ""
249
+ end
250
+ end
251
+
252
+ # cubes are now centered in xy by default in jenncad
253
+ # TODO: should this not be to_openscad in Cube?
254
+ def handle_cube(part, tabindex)
255
+ res = ""
256
+ if part.option(:center)
257
+ res += transformation(Move.new(x: -part.x/2.0, y: -part.y/2.0))
258
+ else
259
+ if part.option(:center_x)
260
+ res += transformation(Move.new(x: -part.x/2.0))
261
+ end
262
+ if part.option(:center_y)
263
+ res += transformation(Move.new(y: -part.y/2.0))
264
+ end
265
+ if part.option(:center_z)
266
+ res += transformation(Move.new(z: -part.z/2.0))
267
+ end
268
+ end
269
+
270
+ res += cmd('cube', collect_params(part), nil)
271
+ end
272
+
273
+ end
274
+ end
@@ -0,0 +1,14 @@
1
+ module JennCad
2
+ # Part should be inherited from the user when making parts
3
+ class Part < Thing
4
+
5
+ def make_openscad_compatible
6
+ auto_color
7
+ a = Aggregation.new(self.class.to_s, make_openscad_compatible!(self.part))
8
+ a.transformations = @transformations
9
+ a.color(color)
10
+ a
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ class Array
2
+ # Assembles things on top of each other
3
+ def assemble(partlib=nil, skip_z=false, z=0)
4
+ map do |part|
5
+ case part
6
+ when Array
7
+ res = part.assemble(partlib, true)
8
+ when String, Symbol
9
+ res = partlib[part].yield
10
+ when Proc
11
+ res = part.yield
12
+ else
13
+ res = part
14
+ end
15
+ # FIXME: I added 0.01 to all for now to fix z-fighting issues; this should not be hardcoded like this
16
+ res, z = res.move(z:z), z + res.z.to_f + 0.01 unless skip_z
17
+ res
18
+ end
19
+ .union
20
+ end
21
+
22
+ def union(&block)
23
+ if block
24
+ UnionObject.new(block.yield)
25
+ else
26
+ UnionObject.new(self)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,12 @@
1
+ module JennCad::Primitives
2
+ class Aggregation < Primitive
3
+ attr_accessor :part
4
+
5
+ def initialize(name=nil, part=nil)
6
+ super({})
7
+ @name = name
8
+ @part = part
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,76 @@
1
+ module JennCad::Primitives
2
+ class BooleanObject < Primitive
3
+ def initialize(*parts)
4
+ @transformations = []
5
+ if parts.first.kind_of? Array
6
+ @parts = parts.first
7
+ else
8
+ @parts = parts
9
+ end
10
+ after_add
11
+ end
12
+
13
+ def add(part)
14
+ @parts << part
15
+ after_add
16
+ end
17
+
18
+ def after_add
19
+ @parts.flatten!
20
+ @parts.compact!
21
+ inherit_z
22
+ inherit_zref
23
+ end
24
+
25
+ def inherit_z
26
+ heights = @parts.map{|l| l.calc_z.to_f}.uniq
27
+ if heights.size > 1
28
+ total_heights = []
29
+ @parts.each do |p|
30
+ total_heights << p.z.to_f + p.calc_z.to_f
31
+ end
32
+ @z = total_heights.max
33
+ @calc_z = heights.min
34
+ else
35
+ @calc_z = heights.first.to_f
36
+ @z = @parts.map(&:z).compact.max
37
+ end
38
+ end
39
+
40
+ def inherit_zref
41
+ return if @parts.first == nil
42
+ return if @parts.first.z.to_f == 0.0
43
+ get_primitives(@parts[1..-1]).flatten.each do |part|
44
+ if part.z.to_f == 0.0
45
+ part.set_option :zref, @parts.first
46
+ end
47
+ end
48
+ end
49
+
50
+ def get_primitives(obj)
51
+ res = []
52
+ if obj.kind_of? Array
53
+ obj.each do |part|
54
+ res << part.children_list
55
+ end
56
+ else
57
+ res << obj.children_list
58
+ end
59
+ res
60
+ end
61
+
62
+ def only_additives_of(obj)
63
+ res = []
64
+ case obj
65
+ when Array
66
+ res << obj.map{|l| only_additives_of(l)}
67
+ when SubtractObject
68
+ when IntersectionObject
69
+ else
70
+ res << obj
71
+ end
72
+ res.flatten
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,11 @@
1
+ module JennCad::Primitives
2
+ class Circle < Primitive
3
+ attr_accessor :d, :r, :fn
4
+ def initialize(args)
5
+ super
6
+ @d = args[:d]
7
+ @r = args[:r]
8
+ @fn = args[:fn]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,69 @@
1
+ module JennCad::Primitives
2
+ class Cube < Primitive
3
+ attr_accessor :x,:y,:z
4
+
5
+ def initialize(args)
6
+ if args.kind_of?(Array) && args[0].kind_of?(Hash)
7
+ args = args.first
8
+ end
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
+ end
17
+ @opts = {
18
+ x: 0,
19
+ y: 0,
20
+ z: 0,
21
+ margins: {
22
+ x: 0,
23
+ y: 0,
24
+ z: 0,
25
+ },
26
+ center: true,
27
+ center_y: false,
28
+ center_x: false,
29
+ center_z: false,
30
+ }.deep_merge!(args)
31
+ handle_margins
32
+
33
+ super(args)
34
+ @h = @z.dup
35
+ @calc_h = @z.dup
36
+ end
37
+
38
+ # used for openscad export
39
+ def size
40
+ [@x, @y, @z]
41
+ end
42
+
43
+ def center_xy
44
+ set_option :center, true
45
+ self
46
+ end
47
+
48
+ def center_x
49
+ set_option :center_x, true
50
+ self
51
+ end
52
+
53
+ def center_y
54
+ set_option :center_y, true
55
+ self
56
+ end
57
+
58
+ def center_z
59
+ set_option :center_z, true
60
+ self
61
+ end
62
+
63
+ # def center
64
+ # @transformations << Move.new({x:-@x/2,y:-@y/2,z:-@z/2})
65
+ # self
66
+ # end
67
+
68
+ end
69
+ end
@@ -0,0 +1,52 @@
1
+ module JennCad::Primitives
2
+ class Cylinder < Primitive
3
+ attr_accessor :d, :r, :fn
4
+ def initialize(args)
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
+ args[:z] ||= args[:h]
18
+
19
+ @opts = {
20
+ d: 0,
21
+ z: nil,
22
+ r: 0,
23
+ margins: {
24
+ r: 0,
25
+ d: 0,
26
+ z: 0,
27
+ },
28
+ fn: nil,
29
+ }.deep_merge!(args)
30
+
31
+ # FIXME:
32
+ # - margins calculation needs to go to output
33
+ # - assinging these variables has to stop
34
+ # - r/d need to be automatically calculated by each other
35
+ # - r+z margin not implemented atm
36
+ # - need to migrate classes to provide all possible outputs (and non-conflicting ones) to openscad exporter
37
+ @d = args[:d] + @opts[:margins][:d]
38
+ @z = args[:z] || args[:h]
39
+ @r = args[:r]
40
+ @fn = args[:fn]
41
+ if @fn == nil && @d > 16
42
+ @fn = (@d*4).ceil
43
+ end
44
+ super(args)
45
+ end
46
+
47
+ def h
48
+ z
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,4 @@
1
+ module JennCad::Primitives
2
+ class HullObject < BooleanObject
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module JennCad::Primitives
2
+ class IntersectionObject < BooleanObject
3
+ end
4
+ end
@@ -0,0 +1,25 @@
1
+ module JennCad::Primitives
2
+ attr_accessor :center_bool, :convexity, :twist, :slices, :height
3
+ class LinearExtrude < JennCad::Thing
4
+ def initialize(part, args)
5
+ @transformations = []
6
+ @parts = [part]
7
+ @height = args[:h] || args[:height]
8
+ @center_bool = args[:center]
9
+ @convexity = args[:convexity]
10
+ @twist = args[:twist]
11
+ @slices = args[:slices]
12
+ @fn = args[:fn]
13
+ end
14
+
15
+ def openscad_params
16
+ res = {}
17
+ [:height, :convexity, :twist, :slices, :fn].each do |n|
18
+ res[n] = self.send n
19
+ end
20
+ res[:center] = @center_bool
21
+ res
22
+ end
23
+ end
24
+
25
+ end
@@ -0,0 +1,11 @@
1
+ module JennCad::Primitives
2
+ class OpenScadImport < Aggregation
3
+ attr_accessor :import, :args
4
+
5
+ def initialize(import, name, args)
6
+ @import = import
7
+ @name = name
8
+ @args = args
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ module JennCad::Primitives
2
+ class Polygon < Primitive
3
+ attr_accessor :points
4
+ def initialize(args)
5
+ super
6
+ @points = args[:points]
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,24 @@
1
+ module JennCad::Primitives
2
+ class Primitive < JennCad::Thing
3
+ def initialize(*args)
4
+ super(*args)
5
+ end
6
+
7
+ def handle_margins
8
+ @x = @opts[:x] + @opts[:margins][:x]
9
+ @y = @opts[:y] + @opts[:margins][:y]
10
+ @z = @opts[:z] + @opts[:margins][:z]
11
+ end
12
+
13
+ def handle_diameter
14
+ @d = opts[:d]
15
+ @r = opts[:r]
16
+ if @d
17
+ @r = @d/2.0
18
+ elsif @r
19
+ @d = @r*2
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ module JennCad::Primitives
2
+ class Projection < JennCad::Thing
3
+ def initialize(part, args)
4
+ @transformations = []
5
+ @cut = args[:cut]
6
+ @parts = [part]
7
+ end
8
+ end
9
+ end