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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 59b41052c4c676ae59a808744715a5e10b1c1086350d4c7769b87d054f51d171
4
- data.tar.gz: a620928785ad237699d0afff433912a8b5c5f6d765492d4d1f72d4d4d83fb962
3
+ metadata.gz: 14729ddf8a7adb190fd55bd555bff63515420acd3468daaa2d254a06069f213d
4
+ data.tar.gz: 41237b37c2a7bb301981fce8a44d7772e37fcd75880dba73b47872d4f9729dbe
5
5
  SHA512:
6
- metadata.gz: 2118f2cff401f4874c6dda0f801cfda1666e0b032158e088ff83ecf24072654a7545fc4ecd9e245398d2de2497f7b363a7a2fe4db90856d87a9a2a60ff39816b
7
- data.tar.gz: dd82a60377991ec146d6d9c259e19df75ee752b25eb1b44ed5cc2b33aea3f7b791726dd8ee12182ac323ad7902f75da5b8d5127858efa235d4792ac0755fa52e
6
+ metadata.gz: 58e2c3db175c7fdbcdc34817460f44460766c4469dca347fe4a98163c2dd212e9510069f458ee152475385bb56d80f5a62b119002b8debd9c41b7a05ec567fe0
7
+ data.tar.gz: d094fd51199bb1de45d3952f9fc66f4f2aa685177f3c4064c984459b95ad4082d1af52b202bedf71a749e5a9c8347eea334042703aea5c229e591537fb9e2a5b
data/LICENSE ADDED
@@ -0,0 +1,165 @@
1
+ GNU LESSER GENERAL PUBLIC LICENSE
2
+ Version 3, 29 June 2007
3
+
4
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
5
+ Everyone is permitted to copy and distribute verbatim copies
6
+ of this license document, but changing it is not allowed.
7
+
8
+
9
+ This version of the GNU Lesser General Public License incorporates
10
+ the terms and conditions of version 3 of the GNU General Public
11
+ License, supplemented by the additional permissions listed below.
12
+
13
+ 0. Additional Definitions.
14
+
15
+ As used herein, "this License" refers to version 3 of the GNU Lesser
16
+ General Public License, and the "GNU GPL" refers to version 3 of the GNU
17
+ General Public License.
18
+
19
+ "The Library" refers to a covered work governed by this License,
20
+ other than an Application or a Combined Work as defined below.
21
+
22
+ An "Application" is any work that makes use of an interface provided
23
+ by the Library, but which is not otherwise based on the Library.
24
+ Defining a subclass of a class defined by the Library is deemed a mode
25
+ of using an interface provided by the Library.
26
+
27
+ A "Combined Work" is a work produced by combining or linking an
28
+ Application with the Library. The particular version of the Library
29
+ with which the Combined Work was made is also called the "Linked
30
+ Version".
31
+
32
+ The "Minimal Corresponding Source" for a Combined Work means the
33
+ Corresponding Source for the Combined Work, excluding any source code
34
+ for portions of the Combined Work that, considered in isolation, are
35
+ based on the Application, and not on the Linked Version.
36
+
37
+ The "Corresponding Application Code" for a Combined Work means the
38
+ object code and/or source code for the Application, including any data
39
+ and utility programs needed for reproducing the Combined Work from the
40
+ Application, but excluding the System Libraries of the Combined Work.
41
+
42
+ 1. Exception to Section 3 of the GNU GPL.
43
+
44
+ You may convey a covered work under sections 3 and 4 of this License
45
+ without being bound by section 3 of the GNU GPL.
46
+
47
+ 2. Conveying Modified Versions.
48
+
49
+ If you modify a copy of the Library, and, in your modifications, a
50
+ facility refers to a function or data to be supplied by an Application
51
+ that uses the facility (other than as an argument passed when the
52
+ facility is invoked), then you may convey a copy of the modified
53
+ version:
54
+
55
+ a) under this License, provided that you make a good faith effort to
56
+ ensure that, in the event an Application does not supply the
57
+ function or data, the facility still operates, and performs
58
+ whatever part of its purpose remains meaningful, or
59
+
60
+ b) under the GNU GPL, with none of the additional permissions of
61
+ this License applicable to that copy.
62
+
63
+ 3. Object Code Incorporating Material from Library Header Files.
64
+
65
+ The object code form of an Application may incorporate material from
66
+ a header file that is part of the Library. You may convey such object
67
+ code under terms of your choice, provided that, if the incorporated
68
+ material is not limited to numerical parameters, data structure
69
+ layouts and accessors, or small macros, inline functions and templates
70
+ (ten or fewer lines in length), you do both of the following:
71
+
72
+ a) Give prominent notice with each copy of the object code that the
73
+ Library is used in it and that the Library and its use are
74
+ covered by this License.
75
+
76
+ b) Accompany the object code with a copy of the GNU GPL and this license
77
+ document.
78
+
79
+ 4. Combined Works.
80
+
81
+ You may convey a Combined Work under terms of your choice that,
82
+ taken together, effectively do not restrict modification of the
83
+ portions of the Library contained in the Combined Work and reverse
84
+ engineering for debugging such modifications, if you also do each of
85
+ the following:
86
+
87
+ a) Give prominent notice with each copy of the Combined Work that
88
+ the Library is used in it and that the Library and its use are
89
+ covered by this License.
90
+
91
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
92
+ document.
93
+
94
+ c) For a Combined Work that displays copyright notices during
95
+ execution, include the copyright notice for the Library among
96
+ these notices, as well as a reference directing the user to the
97
+ copies of the GNU GPL and this license document.
98
+
99
+ d) Do one of the following:
100
+
101
+ 0) Convey the Minimal Corresponding Source under the terms of this
102
+ License, and the Corresponding Application Code in a form
103
+ suitable for, and under terms that permit, the user to
104
+ recombine or relink the Application with a modified version of
105
+ the Linked Version to produce a modified Combined Work, in the
106
+ manner specified by section 6 of the GNU GPL for conveying
107
+ Corresponding Source.
108
+
109
+ 1) Use a suitable shared library mechanism for linking with the
110
+ Library. A suitable mechanism is one that (a) uses at run time
111
+ a copy of the Library already present on the user's computer
112
+ system, and (b) will operate properly with a modified version
113
+ of the Library that is interface-compatible with the Linked
114
+ Version.
115
+
116
+ e) Provide Installation Information, but only if you would otherwise
117
+ be required to provide such information under section 6 of the
118
+ GNU GPL, and only to the extent that such information is
119
+ necessary to install and execute a modified version of the
120
+ Combined Work produced by recombining or relinking the
121
+ Application with a modified version of the Linked Version. (If
122
+ you use option 4d0, the Installation Information must accompany
123
+ the Minimal Corresponding Source and Corresponding Application
124
+ Code. If you use option 4d1, you must provide the Installation
125
+ Information in the manner specified by section 6 of the GNU GPL
126
+ for conveying Corresponding Source.)
127
+
128
+ 5. Combined Libraries.
129
+
130
+ You may place library facilities that are a work based on the
131
+ Library side by side in a single library together with other library
132
+ facilities that are not Applications and are not covered by this
133
+ License, and convey such a combined library under terms of your
134
+ choice, if you do both of the following:
135
+
136
+ a) Accompany the combined library with a copy of the same work based
137
+ on the Library, uncombined with any other library facilities,
138
+ conveyed under the terms of this License.
139
+
140
+ b) Give prominent notice with the combined library that part of it
141
+ is a work based on the Library, and explaining where to find the
142
+ accompanying uncombined form of the same work.
143
+
144
+ 6. Revised Versions of the GNU Lesser General Public License.
145
+
146
+ The Free Software Foundation may publish revised and/or new versions
147
+ of the GNU Lesser General Public License from time to time. Such new
148
+ versions will be similar in spirit to the present version, but may
149
+ differ in detail to address new problems or concerns.
150
+
151
+ Each version is given a distinguishing version number. If the
152
+ Library as you received it specifies that a certain numbered version
153
+ of the GNU Lesser General Public License "or any later version"
154
+ applies to it, you have the option of following the terms and
155
+ conditions either of that published version or of any later version
156
+ published by the Free Software Foundation. If the Library as you
157
+ received it does not specify a version number of the GNU Lesser
158
+ General Public License, you may choose any version of the GNU Lesser
159
+ General Public License ever published by the Free Software Foundation.
160
+
161
+ If the Library as you received it specifies that a proxy can decide
162
+ whether future versions of the GNU Lesser General Public License shall
163
+ apply, that proxy's public statement of acceptance of any version is
164
+ permanent authorization for you to choose that version for the
165
+ Library.
data/bin/jenncad CHANGED
@@ -1,6 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
  require "jenncad"
3
-
4
3
  JennCad::Commands.register "", JennCad::Commands::Observe
5
4
  JennCad::Commands.register "run", JennCad::Commands::Observe
6
5
  JennCad::Commands.register "build", JennCad::Commands::Build
data/examples/README ADDED
@@ -0,0 +1,4 @@
1
+ Find the examples at:
2
+
3
+ https://github.com/jglauche/jenncad-examples
4
+
data/jenncad.gemspec CHANGED
@@ -25,4 +25,5 @@ Gem::Specification.new do |gem|
25
25
  gem.add_runtime_dependency "dry-cli"
26
26
  gem.add_runtime_dependency "activesupport"
27
27
  gem.add_runtime_dependency "observr"
28
+ gem.add_runtime_dependency "logger"
28
29
  end
@@ -1,10 +1,11 @@
1
+ require "dry/cli"
1
2
  module JennCad
2
3
  module Commands
3
4
  extend Dry::CLI::Registry
4
5
  MAGIC = "jenncad-append-project-magic"
5
6
 
6
7
  class Run < Dry::CLI::Command
7
- argument :name, required: false
8
+ argument :name, required: false, desc: "project file, defaults to dirname.rb by default"
8
9
 
9
10
  def guess_executable(dir=Dir.pwd)
10
11
  dir.split("/").last.to_s + ".rb"
@@ -41,16 +42,23 @@ module JennCad
41
42
  end
42
43
  end
43
44
 
44
- def build
45
- admesh_installed = system("admesh --version > /dev/null")
46
- unless admesh_installed
47
- puts "Warning: cannot find admesh, stl export will be in ASCII"
45
+ end
46
+
47
+ class Build < Run
48
+ option :binary, type: :boolean, default: false, desc: "run through admesh to create a binary stl"
49
+
50
+ def build(options)
51
+ if options[:binary]
52
+ admesh_installed = system("admesh --version > /dev/null")
53
+ unless admesh_installed
54
+ puts "Warning: cannot find admesh, stl export will be in ASCII"
55
+ end
48
56
  end
49
57
 
50
58
  Dir.glob("output/**/*.scad").each do |file|
51
59
  stl = file.gsub(".scad",".stl")
52
60
  build_stl(file, stl)
53
- convert_to_binary(stl) if admesh_installed
61
+ convert_to_binary(stl) if options[:binary] && admesh_installed
54
62
  end
55
63
  end
56
64
 
@@ -63,16 +71,15 @@ module JennCad
63
71
  system("admesh #{stl} -b #{stl}")
64
72
  end
65
73
 
66
- end
67
74
 
68
- class Build < Run
69
- def call(name: nil, **)
75
+ def call(options)
76
+ name = options[:name]
70
77
  unless name
71
78
  name = guess_executable
72
79
  end
73
80
  if check_executable(name)
74
81
  execute(name)
75
- build
82
+ build(options)
76
83
  end
77
84
  end
78
85
  end
@@ -4,10 +4,14 @@ module JennCad::Features
4
4
 
5
5
  def initialize(name=nil, part=nil)
6
6
  super({})
7
- @name = name
7
+ @name = name.gsub(".","_")
8
8
  @parts = [part] # NOTE: single length arrayto make checking children easier
9
9
  end
10
10
 
11
+ def z
12
+ part.z
13
+ end
14
+
11
15
  def part
12
16
  @parts.first
13
17
  end
@@ -0,0 +1,339 @@
1
+ module JennCad
2
+ class RoundCorner
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)
5
+ @start_point = args[:start_point]
6
+ @end_point = args[:end_point]
7
+ @a = args[:a]
8
+ @ccw = args[:ccw] || false
9
+ @l = args[:l]
10
+ @od = args[:od]
11
+ @id = args[:id]
12
+ @input_a = args[:input_a] || 0
13
+ @output_a = args[:output_a] || 0
14
+ @thing = thing
15
+ @angle = args[:angle]
16
+ @current_angle = args[:current_angle]
17
+ @direction = args[:direction]
18
+ @to = args[:to]
19
+ @from = args[:from]
20
+
21
+ if @a < 0
22
+ @from = case @from
23
+ when :left
24
+ :right
25
+ when :right
26
+ :left
27
+ when :top, :up
28
+ :bottom
29
+ when :down, :bottom
30
+ :up
31
+ else
32
+ # // unimplemented
33
+ @from
34
+ end
35
+ end
36
+
37
+ end
38
+
39
+ def set_angles(cur, total, direction)
40
+ @current_angle = cur
41
+ @angle = normalize(total)
42
+ @direction = direction
43
+ end
44
+
45
+ def normalize(angle)
46
+ if angle < 0
47
+ angle += 360
48
+ end
49
+ if angle >= 360
50
+ angle -= 360
51
+ end
52
+ angle
53
+ end
54
+
55
+ def margin
56
+ return @od
57
+ end
58
+
59
+ 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
65
+ l = td + @id
66
+ l2 = td / 2.0 + @id / 2.0
67
+ r = 0
68
+ ox = 0
69
+ oy = 0
70
+ cr = 180
71
+ case @from
72
+ when :left
73
+ r = 0
74
+ oy = -l
75
+ when :top, :up
76
+ r = -90
77
+ ox = -l
78
+ cr = 0
79
+ when :right
80
+ r = 180
81
+ oy = l
82
+ when :bottom, :down
83
+ cr = 0
84
+ r = 90
85
+ ox = l
86
+ # TODO: so this doesn't work yet,
87
+ # need to figure out the maths to translate this
88
+ when 0..360
89
+ r = 180-@from
90
+ cr = @a
91
+ end
92
+
93
+ r2 = cr + r + @a # 180+@a
94
+ x = - l2 * Math::sin((r2/180.0)*Math::PI)
95
+ y = - l2 * Math::cos((r2/180.0)*Math::PI)
96
+
97
+
98
+
99
+ return r, ox/2.0, oy/2.0, x, y
100
+
101
+ end
102
+
103
+ def part
104
+ d = thing.yield.d
105
+ len = d * 2 + @id
106
+ x = Math::sin((@a/180.0)*Math::PI)*len
107
+ y = Math::cos((@a/180.0)*Math::PI)*len
108
+
109
+ res = circle(d: len)
110
+ res -= circle(d: @id)
111
+ points = [[0,0]]
112
+ points << [0, len]
113
+ points << [x, y]
114
+
115
+ res *= polygon(points:points)
116
+
117
+ r, ox, oy, x, y = positions
118
+ res = res.rotate(z: r).move(x: ox, y: oy)
119
+ res = res.auto_extrude#.color("red")
120
+
121
+ #res += slot(d: 1.2, y: len/2.0, h: 10).rotate(z: r_midpoint).color("red")
122
+ #res += cylinder(d: 1, h: 10).move(x: x+ox,y: y+oy)
123
+
124
+ #res.moveh(x: thing.yield.d, y: -thing.yield.d)
125
+ res.move(x: @start_point[:x], y: @start_point[:y])
126
+
127
+ #res += cylinder(d: 1, h: 15).color("red").move(x: @start_point[:x], y: @start_point[:y]).move(z:-1)
128
+
129
+
130
+ res
131
+
132
+ end
133
+
134
+ end
135
+
136
+ class Line
137
+ attr_accessor :start_point, :end_point, :l, :thing, :angle, :current_angle, :direction
138
+ def initialize(args, &thing)
139
+ @start_point = args[:start_point]
140
+ @end_point = args[:end_point]
141
+ @angle = args[:angle]
142
+ @current_angle = args[:current_angle]
143
+ @direction = args[:direction]
144
+ @l = args[:l]
145
+ @thing = thing
146
+ end
147
+
148
+ def sp_margin(margin)
149
+ @start_point[:x] -= margin[:x]
150
+ @start_point[:y] -= margin[:y]
151
+ end
152
+
153
+ def ep_margin(margin)
154
+ @end_point[:x] -= margin[:x]
155
+ @end_point[:y] -= margin[:y]
156
+ end
157
+
158
+ def shrink_ep(len)
159
+ sx, sy = @start_point[:x], @start_point[:y]
160
+ ex, ey = @end_point[:x], @end_point[:y]
161
+ vx = ex-sx
162
+ vy = ey-sy
163
+ l = Math::sqrt(vx**2 + vy**2)
164
+ factor = len / l
165
+ @end_point[:x] -= vx * factor
166
+ @end_point[:y] -= vy * factor
167
+ #puts "#{sx} x #{sy} => #{ex} x #{ey} , shrink #{factor} "
168
+ end
169
+
170
+ def shrink_sp(len)
171
+ sx, sy = @start_point[:x], @start_point[:y]
172
+ ex, ey = @end_point[:x], @end_point[:y]
173
+ vx = ex-sx
174
+ vy = ey-sy
175
+ l = Math::sqrt(vx**2 + vy**2)
176
+ factor = len / l
177
+ @start_point[:x] -= vx * factor
178
+ @start_point[:y] -= vy * factor
179
+ end
180
+
181
+
182
+ def part
183
+ 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
+ )
187
+ end
188
+ end
189
+
190
+ class Path < Thing
191
+
192
+ attr_accessor :elements, :lpos, :thing, :angle, :current_angle, :direction
193
+ def initialize(args)
194
+ @thing = args[:part] #// cylinder(d: @d, z: @z)
195
+ @part = new_thing
196
+ @angle = args[:a] || 0
197
+ @current_angle = args[:a] || 0
198
+ @direction = 0
199
+ @name = args[:name] || "Path"
200
+ @calc_h = @part.z
201
+ @dir = 0
202
+ @lpos = {x: 0, y: 0, l: 0, a: 0}
203
+ @coords = []
204
+ @steps = []
205
+ @parts = [new_thing]
206
+
207
+ super(args)
208
+ end
209
+
210
+ def new_thing
211
+ r = @thing.clone
212
+ r.transformations = []
213
+ r
214
+ end
215
+
216
+ def corner(args)
217
+ od = args[:od]
218
+ id = args[:id]
219
+ if id.nil? && od
220
+ id = new_thing.d
221
+ #puts "od: #{od} , thing d #{new_thing.d} new id #{id}"
222
+ end
223
+ if od.nil? && id
224
+ od = id + new_thing.d
225
+ end
226
+ rc = RoundCorner.new(
227
+ start_point: { x: @lpos[:x], y: @lpos[:y] },
228
+ end_point: { x: @lpos[:x], y: @lpos[:y] },
229
+ od: od,
230
+ id: id,
231
+ ccw: args[:ccw],
232
+ from: args[:from],
233
+ to: args[:to],
234
+ a: args[:a],
235
+ direction: @direction
236
+ ){ new_thing }
237
+
238
+ _, ox, oy, x, y = rc.positions
239
+ @lpos[:x] += x + ox
240
+ @lpos[:y] += y + oy
241
+
242
+ @steps << rc
243
+ end
244
+
245
+ def line(args)
246
+ if args[:l]
247
+ args[:a] ||= 0
248
+ if args[:a] > 0
249
+ @direction = 1
250
+ elsif args[:a] < 0
251
+ @direction = -1
252
+ else
253
+ @direction = 0
254
+ end
255
+
256
+ @angle += args[:a]
257
+ @current_angle = args[:a]
258
+
259
+ l = args[:l]
260
+ gamma = 90
261
+ alpha = @angle
262
+ beta = gamma - alpha
263
+
264
+ case
265
+ when alpha == 90, alpha == -270
266
+ x = l
267
+ y = 0
268
+ when alpha == 180, alpha == -180
269
+ x = 0
270
+ y = -l
271
+ when alpha == 270, alpha == -90
272
+ x = -l
273
+ y = 0
274
+ when alpha == 360, alpha == 0
275
+ x = 0
276
+ y = l
277
+ else
278
+ y = l/Math::sin(radians(gamma)) * Math::sin(radians(beta))
279
+ x = y/Math::sin(radians(beta)) * Math::sin(radians(alpha))
280
+ end
281
+ elsif args[:x] || args[:y]
282
+ x = args[:x] || 0
283
+ y = args[:y] || 0
284
+
285
+ dx = @lpos[:x] - x
286
+ dy = @lpos[:y] - y
287
+
288
+ l = Math::sqrt(dx*dx + dy*dy)
289
+ alpha = Math::atan2(x, y)*180/Math::PI
290
+ else
291
+ puts "Error in line(): Please specify either :l, :x or :y"
292
+ return
293
+ end
294
+
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 }
296
+
297
+ add_lpos({x: x, y: y})
298
+ end
299
+
300
+ def add_lpos(lpos)
301
+ #puts "x: #{lpos[:x]}, y: #{lpos[:y]}"
302
+ [:x, :y].each do |key|
303
+ @lpos[key] += lpos[key]
304
+ end
305
+ @coords << lpos
306
+ end
307
+
308
+ def pos
309
+ [@lpos[:x], @lpos[:y]]
310
+ end
311
+
312
+ def center
313
+ @steps << Move.new(x: @lpos[:x] * -1, y: @lpos[:y] * -1)
314
+ self
315
+ end
316
+
317
+ def assemble
318
+ @steps.each_with_index do |step, i|
319
+ if @steps[i+1] && @steps[i+1].class == Line && step.class == RoundCorner
320
+ step.set_angles(@steps[i+1].current_angle, @steps[i+1].angle, @steps[i+1].direction)
321
+ end
322
+ end
323
+ res = nil
324
+ @steps.each do |step|
325
+ if step.kind_of? Transformation
326
+ res.transformations << step
327
+ else
328
+ res += step.part
329
+ end
330
+ end
331
+ set_heights_for_auto_extrude([res], self)
332
+ res.transformations << @transformations
333
+ Aggregation.new(@name, res)
334
+ end
335
+
336
+ end
337
+ end
338
+
339
+
@@ -4,6 +4,8 @@ require "jenncad/features/cuttable"
4
4
  require "jenncad/features/openscad_include"
5
5
  require "jenncad/features/climb"
6
6
  require "jenncad/features/stl_import"
7
+ require "jenncad/features/path"
8
+
7
9
 
8
10
 
9
11
  module JennCad
@@ -7,6 +7,8 @@ module JennCad::Primitives
7
7
  else
8
8
  @parts = parts
9
9
  end
10
+ @parent = @parts.first.parent
11
+
10
12
  after_add
11
13
  end
12
14