laser-cutter 0.5.3 → 1.0.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/README.md +20 -16
- data/bin/laser-cutter +4 -158
- data/lib/laser-cutter.rb +2 -0
- data/lib/laser-cutter/aggregator.rb +57 -0
- data/lib/laser-cutter/box.rb +37 -24
- data/lib/laser-cutter/cli/opt_parser.rb +131 -0
- data/lib/laser-cutter/cli/serializer.rb +51 -0
- data/lib/laser-cutter/configuration.rb +3 -2
- data/lib/laser-cutter/geometry.rb +0 -3
- data/lib/laser-cutter/geometry/dimensions.rb +3 -3
- data/lib/laser-cutter/geometry/point.rb +0 -46
- data/lib/laser-cutter/geometry/shape/line.rb +40 -1
- data/lib/laser-cutter/geometry/shape/rect.rb +2 -2
- data/lib/laser-cutter/geometry/tuple.rb +73 -27
- data/lib/laser-cutter/notching.rb +10 -0
- data/lib/laser-cutter/notching/base.rb +13 -0
- data/lib/laser-cutter/notching/edge.rb +87 -0
- data/lib/laser-cutter/notching/path_generator.rb +249 -0
- data/lib/laser-cutter/renderer/base.rb +1 -1
- data/lib/laser-cutter/renderer/box_renderer.rb +2 -2
- data/lib/laser-cutter/renderer/layout_renderer.rb +19 -8
- data/lib/laser-cutter/renderer/meta_renderer.rb +8 -9
- data/lib/laser-cutter/version.rb +1 -1
- data/spec/aggregator_spec.rb +65 -0
- data/spec/box_spec.rb +5 -1
- data/spec/dimensions_spec.rb +0 -1
- data/spec/edge_spec.rb +43 -0
- data/spec/line_spec.rb +42 -19
- data/spec/path_generator_spec.rb +30 -36
- data/spec/point_spec.rb +2 -2
- data/spec/rect_spec.rb +1 -1
- data/spec/renderer_spec.rb +14 -5
- metadata +13 -5
- data/lib/laser-cutter/geometry/edge.rb +0 -33
- data/lib/laser-cutter/geometry/notched_path.rb +0 -46
- data/lib/laser-cutter/geometry/path_generator.rb +0 -129
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1e42b32bc2ee9759bffa630c87390941e92400e0
|
4
|
+
data.tar.gz: 2c69316654ae0a33f13871be5b401a973db83b76
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e8a25fc98e3e9d4ca9a57a543fe67978cff1981b9e57744406a5d2a5056f3960672b1902d7af27521a4edc889dea077c8c399f10da130f7751f1324bb784173
|
7
|
+
data.tar.gz: cda884dcc0c1328250f3e9dd0542870e4f856d406abd493d1bdd32573460ebc03026a1f88dde37d456bbcdb5fe791a1f6be1f4f4604e56ba1dfd43da33ac608b
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -50,29 +50,33 @@ Or install it yourself as:
|
|
50
50
|
## Usage
|
51
51
|
|
52
52
|
```bash
|
53
|
+
|
53
54
|
Usage: laser-cutter [options] -o filename.pdf
|
54
|
-
eg: laser-cutter -
|
55
|
+
eg: laser-cutter -z 1x1.5x2/0.125 -O -o box.pdf
|
55
56
|
|
56
57
|
Specific Options:
|
57
58
|
-w, --width WIDTH Internal width of the box
|
58
59
|
-h, --height HEIGHT Internal height of the box
|
59
60
|
-d, --depth DEPTH Internal depth of the box
|
60
61
|
-t, --thickness THICKNESS Thickness of the box material
|
61
|
-
-n, --notch NOTCH
|
62
|
+
-n, --notch NOTCH Optional notch length (aka "tab width"), guide only
|
63
|
+
-k, --kerf KERF Kerf - cut width (default is 0.007in)
|
62
64
|
|
63
65
|
-m, --margin MARGIN Margins from the edge of the document
|
64
66
|
-p, --padding PADDING Space between the boxes on the page
|
65
|
-
-
|
66
|
-
-
|
67
|
-
-
|
67
|
+
-s, --stroke WIDTH Numeric stroke width of the line
|
68
|
+
-i, --page_size LETTER Document page size, default is autofit the box.
|
69
|
+
-l, --page_layout portrait Page layout, other option is 'landscape'
|
68
70
|
|
69
71
|
-O, --open Open generated file with system viewer before exiting
|
70
|
-
-W, --write
|
71
|
-
-R, --read
|
72
|
+
-W, --write CONFIG_FILE Save provided configuration to a file, use '-' for STDOUT
|
73
|
+
-R, --read CONFIG_FILE Read configuration from a file, or use '-' for STDIN
|
72
74
|
|
73
|
-
-
|
75
|
+
-L, --list-all-page-sizes Print all available page sizes with dimensions and exit
|
74
76
|
-M, --no-metadata Do not print box metadata on the PDF
|
75
77
|
-v, --[no-]verbose Run verbosely
|
78
|
+
-B, --inside-box Draw the inside boxes (helpful to verify kerfing)
|
79
|
+
-D, --debug Show full exception stack trace on error
|
76
80
|
|
77
81
|
--examples Show detailed usage examples
|
78
82
|
--help Show this message
|
@@ -80,37 +84,37 @@ Specific Options:
|
|
80
84
|
|
81
85
|
Common Options:
|
82
86
|
-o, --file FILE Required output filename of the PDF
|
83
|
-
-
|
84
|
-
D = depth, T = thickness, N = notch length
|
87
|
+
-z, --size WxHxD/T[/N] Combined internal dimensions: W = width, H = height,
|
88
|
+
D = depth, T = thickness, and optional N = notch length
|
85
89
|
|
86
90
|
-u, --units UNITS Either 'in' for inches (default) or 'mm'
|
87
91
|
```
|
88
92
|
|
89
93
|
### Examples
|
90
94
|
|
91
|
-
Create a box defined in inches, and open PDF in preview right after:
|
95
|
+
Create a box defined in inches, with kerf (cut width) set to 0.008", and open PDF in preview right after:
|
92
96
|
|
93
97
|
```bash
|
94
|
-
laser-cutter -
|
98
|
+
laser-cutter -z 3x2x2/0.125 -k 0.008 -O -o box.pdf
|
95
99
|
```
|
96
100
|
|
97
101
|
Create a box defined in millimeters, print verbose info, and set
|
98
102
|
page size to A3, and layout to landscape, and stroke width to 1/2mm:
|
99
103
|
|
100
104
|
```bash
|
101
|
-
laser-cutter -u mm -w70 -h20 -d50 -t4.3 -n5 -
|
105
|
+
laser-cutter -u mm -w70 -h20 -d50 -t4.3 -n5 -iA3 -l landscape -s0.5 -v -O -o box.pdf
|
102
106
|
```
|
103
107
|
|
104
108
|
List all possible page sizes in metric system:
|
105
109
|
|
106
110
|
```bash
|
107
|
-
laser-cutter -
|
111
|
+
laser-cutter -L -u mm
|
108
112
|
```
|
109
113
|
|
110
114
|
Create a box with provided dimensions, and save the config to a file for later use:
|
111
115
|
|
112
116
|
```bash
|
113
|
-
laser-cutter -
|
117
|
+
laser-cutter -z 1.1x2.5x1.5/0.125/0.125 -p 0.1 -O -o box.pdf -W box-settings.json
|
114
118
|
```
|
115
119
|
|
116
120
|
Read settings from a previously saved file:
|
@@ -171,7 +175,7 @@ And laser-cutter:
|
|
171
175
|
|
172
176
|
```bash
|
173
177
|
gem install laser-cutter
|
174
|
-
laser-cutter -
|
178
|
+
laser-cutter -z 1x1.5x2/0.125/0.125 -O -o box.pdf
|
175
179
|
```
|
176
180
|
|
177
181
|
.
|
data/bin/laser-cutter
CHANGED
@@ -1,162 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
require 'laser-cutter'
|
3
|
-
require '
|
4
|
-
require 'colored'
|
5
|
-
require 'json'
|
6
|
-
require 'hashie/mash'
|
2
|
+
require File.expand_path('../../lib/laser-cutter', __FILE__)
|
3
|
+
require File.expand_path('../../lib/laser-cutter/cli/opt_parser', __FILE__)
|
7
4
|
|
8
|
-
|
9
|
-
module Cutter
|
10
|
-
class OptParse
|
11
|
-
def self.puts_error(e)
|
12
|
-
STDERR.puts "Whoops, #{e}".red
|
13
|
-
STDERR.puts "Try --help or --examples for more info...".yellow
|
14
|
-
end
|
15
|
-
|
16
|
-
def self.parse(args)
|
17
|
-
banner_text = <<-EOF
|
18
|
-
#{('Laser-Cutter v'+ Laser::Cutter::VERSION).bold}
|
19
|
-
|
20
|
-
Usage: laser-cutter [options] -o filename.pdf
|
21
|
-
eg: laser-cutter -s 1x1.5x2/0.125 -O -o box.pdf
|
22
|
-
EOF
|
23
|
-
|
24
|
-
examples = <<-EOF
|
25
|
-
|
26
|
-
Examples:
|
27
|
-
1. Create a box defined in inches, and open PDF in preview right after:
|
28
|
-
|
29
|
-
laser-cutter -s 3x2x2/0.125 -O -o box.pdf
|
30
|
-
|
31
|
-
2. Create a box defined in millimeters, print verbose info, and set
|
32
|
-
page size to A3, and layout to landscape, and stroke width to 1/2mm:
|
33
|
-
|
34
|
-
laser-cutter -u mm -w70 -h20 -d50 -t4.3 -n5 -zA3 -y landscape -k0.5 -v -O -o box.pdf
|
35
|
-
|
36
|
-
3. List all possible page sizes in metric systems:
|
37
|
-
|
38
|
-
laser-cutter -l -u mm
|
39
|
-
|
40
|
-
4. Create a box with provided dimensions, and save the config to a file
|
41
|
-
for later use:
|
42
|
-
|
43
|
-
laser-cutter -s 1.1x2.5x1.5/0.125/0.125 -p 0.1 -O -o box.pdf -W box-settings.json
|
44
|
-
|
45
|
-
5. Read settings from a previously saved file:
|
46
|
-
|
47
|
-
laser-cutter -O -o box.pdf -R box-settings.json
|
48
|
-
cat box-settings.json | laser-cutter -O -o box.pdf -R -
|
49
|
-
|
50
|
-
EOF
|
51
|
-
options = Hashie::Mash.new
|
52
|
-
options.verbose = false
|
53
|
-
options.units = 'in'
|
54
|
-
|
55
|
-
opt_parser = OptionParser.new do |opts|
|
56
|
-
opts.banner = banner_text.blue
|
57
|
-
opts.separator "Specific Options:"
|
58
|
-
opts.on("-w", "--width WIDTH", "Internal width of the box") { |value| options.width = value }
|
59
|
-
opts.on("-h", "--height HEIGHT", "Internal height of the box") { |value| options.height = value }
|
60
|
-
opts.on("-d", "--depth DEPTH", "Internal depth of the box") { |value| options.depth= value }
|
61
|
-
opts.on("-t", "--thickness THICKNESS", "Thickness of the box material") { |value| options.thickness = value }
|
62
|
-
opts.on("-n", "--notch NOTCH", "Optional notch length (used as a guide)") { |value| options.notch = value }
|
63
|
-
opts.separator ""
|
64
|
-
opts.on("-m", "--margin MARGIN", "Margins from the edge of the document") { |value| options.margin = value }
|
65
|
-
opts.on("-p", "--padding PADDING", "Space between the boxes on the page") { |value| options.padding = value }
|
66
|
-
opts.on("-k", "--stroke WIDTH", "Numeric stroke width of the line") { |value| options.stroke = value }
|
67
|
-
opts.on("-z", "--page_size LETTER", "Page size, see --list-all-page-sizes for more info.") { |value| options.page_size = value }
|
68
|
-
opts.on("-y", "--page_layout portrait", "Page layout, other option is 'landscape' ") { |value| options.page_layout = value }
|
69
|
-
opts.separator ""
|
70
|
-
opts.on("-O", "--open", "Open generated file with system viewer before exiting") { |v| options.open = v }
|
71
|
-
opts.on("-W", "--write FILE", "Save provided configuration to a file, use '-' for STDOUT") { |v| options.write_file = v }
|
72
|
-
opts.on("-R", "--read FILE", "Read configuration from a file, or use '-' for STDIN") { |v| options.read_file = v }
|
73
|
-
opts.separator ""
|
74
|
-
opts.on("-l", "--list-all-page-sizes", "Print all available page sizes with dimensions and exit") { |v| options.list_all_page_sizes = true }
|
75
|
-
opts.on("-M", "--no-metadata", "Do not print box metadata on the PDF") { |value| options.metadata = value }
|
76
|
-
opts.on("-v", "--[no-]verbose", "Run verbosely") { |v| options.verbose = v }
|
77
|
-
opts.separator ""
|
78
|
-
opts.on("--examples", "Show detailed usage examples") { puts opts; puts examples.yellow; exit }
|
79
|
-
opts.on("--help", "Show this message") { puts opts; exit }
|
80
|
-
opts.on("--version", "Show version") { puts Laser::Cutter::VERSION; exit }
|
81
|
-
opts.separator ""
|
82
|
-
opts.separator "Common Options:"
|
83
|
-
opts.on_tail("-o", "--file FILE", "Required output filename of the PDF") { |value| options.file = value }
|
84
|
-
opts.on_tail("-s", "--size WxHxD/T[/N]",
|
85
|
-
"Combined internal dimensions: W = width, H = height,\n#{" " * 37}D = depth, T = thickness, and optional N = notch length\n\n") do |size|
|
86
|
-
options.size = size
|
87
|
-
end
|
88
|
-
opts.on_tail("-u", "--units UNITS", "Either 'in' for inches (default) or 'mm'") { |value| options.units = value }
|
89
|
-
end
|
90
|
-
|
91
|
-
opt_parser.parse!(args)
|
92
|
-
|
93
|
-
if options.read_file
|
94
|
-
read_options_from_file(options)
|
95
|
-
end
|
96
|
-
|
97
|
-
config = Laser::Cutter::Configuration.new(options.to_hash)
|
98
|
-
if config.list_all_page_sizes
|
99
|
-
puts PageManager.new(config.units).all_page_sizes
|
100
|
-
exit 0
|
101
|
-
end
|
102
|
-
|
103
|
-
if options.verbose
|
104
|
-
puts "Starting with the following configuration:"
|
105
|
-
puts JSON.pretty_generate(config.to_hash).green
|
106
|
-
end
|
107
|
-
|
108
|
-
config.validate!
|
109
|
-
|
110
|
-
if config.write_file
|
111
|
-
write_options_to_file(config)
|
112
|
-
end
|
113
|
-
|
114
|
-
config
|
115
|
-
rescue OptionParser::InvalidOption, OptionParser::MissingArgument, Laser::Cutter::MissingOption => e
|
116
|
-
puts opt_parser.banner.blue
|
117
|
-
puts_error(e)
|
118
|
-
exit 1
|
119
|
-
end
|
120
|
-
|
121
|
-
def self.read_options_from_file(options)
|
122
|
-
string = if options.read_file.eql?('-')
|
123
|
-
$stdin.read
|
124
|
-
elsif File.exist?(options.read_file)
|
125
|
-
File.read(options.read_file)
|
126
|
-
end
|
127
|
-
if string
|
128
|
-
options.replace(JSON.load(string))
|
129
|
-
end
|
130
|
-
rescue Exception => e
|
131
|
-
STDERR.puts "Error reading options from file #{options.read_file}, #{e.message}".red
|
132
|
-
if options.verbose
|
133
|
-
STDERR.puts e.backtrace.join("\n").red
|
134
|
-
end
|
135
|
-
exit 1
|
136
|
-
end
|
137
|
-
|
138
|
-
def self.write_options_to_file(options)
|
139
|
-
output = if options.write_file.eql?('-')
|
140
|
-
$stdout
|
141
|
-
elsif options.write_file
|
142
|
-
File.open(options.write_file, 'w')
|
143
|
-
else
|
144
|
-
nil
|
145
|
-
end
|
146
|
-
output.puts(JSON.pretty_generate(options))
|
147
|
-
output.close if output != $stdout
|
148
|
-
rescue Exception => e
|
149
|
-
STDERR.puts "Error writing options to file #{options.write_file}, #{e.message}".red
|
150
|
-
if options.verbose
|
151
|
-
STDERR.puts e.backtrace.join("\n").red
|
152
|
-
end
|
153
|
-
exit 1
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end # class OptParse
|
158
|
-
|
159
|
-
config = Laser::Cutter::OptParse.parse(ARGV)
|
5
|
+
config = Laser::Cutter::CLI::OptParser.parse(ARGV)
|
160
6
|
|
161
7
|
begin
|
162
8
|
Laser::Cutter::Renderer::LayoutRenderer.new(config).render
|
@@ -164,7 +10,7 @@ begin
|
|
164
10
|
`open #{config.file}`
|
165
11
|
end
|
166
12
|
rescue Exception => e
|
167
|
-
STDERR.puts "#{e.
|
13
|
+
STDERR.puts "Whoops, #{e.message}".red
|
168
14
|
if config.verbose
|
169
15
|
STDERR.puts e.backtrace.join("\n").red
|
170
16
|
end
|
data/lib/laser-cutter.rb
CHANGED
@@ -0,0 +1,57 @@
|
|
1
|
+
module Laser
|
2
|
+
module Cutter
|
3
|
+
class Aggregator
|
4
|
+
attr_accessor :lines
|
5
|
+
|
6
|
+
def initialize(array_of_lines = [])
|
7
|
+
self.lines = array_of_lines.sort
|
8
|
+
end
|
9
|
+
|
10
|
+
# This method finds lines that are identical (same p1/p2)
|
11
|
+
def dedup!
|
12
|
+
lines_to_delete = []
|
13
|
+
count = lines.size
|
14
|
+
for i in 0..(count - 1) do
|
15
|
+
for j in (i + 1)..(count - 1) do
|
16
|
+
l1 = lines[i]
|
17
|
+
l2 = lines[j]
|
18
|
+
if l1.eql?(l2)
|
19
|
+
lines_to_delete << l1
|
20
|
+
lines_to_delete << l2
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
self.lines = self.lines - lines_to_delete
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
# Find overlapping (intersecting) sections of lines and
|
29
|
+
# remove them.
|
30
|
+
def deoverlap!
|
31
|
+
lines_to_delete = []
|
32
|
+
lines_to_add = []
|
33
|
+
count = lines.size
|
34
|
+
for i in 0..(count - 1) do
|
35
|
+
for j in (i + 1)..(count - 1) do
|
36
|
+
l1 = lines[i]
|
37
|
+
l2 = lines[j]
|
38
|
+
if l1.overlaps?(l2)
|
39
|
+
lines_to_delete << l1
|
40
|
+
lines_to_delete << l2
|
41
|
+
lines_to_add << l1.xor(l2)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
lines_to_delete.uniq!
|
47
|
+
lines_to_delete.flatten!
|
48
|
+
lines_to_add.uniq!
|
49
|
+
lines_to_add.flatten!
|
50
|
+
|
51
|
+
self.lines = (self.lines - lines_to_delete + lines_to_add).flatten
|
52
|
+
self.lines.sort!
|
53
|
+
self
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/laser-cutter/box.rb
CHANGED
@@ -5,8 +5,8 @@ module Laser
|
|
5
5
|
class Box
|
6
6
|
# Everything is in millimeters
|
7
7
|
|
8
|
-
attr_accessor :dim, :thickness, :notch_width
|
9
|
-
attr_accessor :padding, :units
|
8
|
+
attr_accessor :dim, :thickness, :notch_width, :kerf
|
9
|
+
attr_accessor :padding, :units, :inside_box
|
10
10
|
|
11
11
|
attr_accessor :front, :back, :top, :bottom, :left, :right
|
12
12
|
attr_accessor :faces, :bounds, :conf, :corner_face
|
@@ -17,10 +17,12 @@ module Laser
|
|
17
17
|
self.thickness = config['thickness']
|
18
18
|
|
19
19
|
self.notch_width = config['notch'] || (1.0 * self.longest / 5.0)
|
20
|
+
self.kerf = config['kerf'] || 0.0
|
20
21
|
self.padding = config['padding']
|
21
22
|
self.units = config['units']
|
23
|
+
self.inside_box = config['inside_box']
|
22
24
|
|
23
|
-
|
25
|
+
self.notches = []
|
24
26
|
|
25
27
|
self.metadata = Geometry::Point[config['metadata_width'] || 0, config['metadata_height'] || 0]
|
26
28
|
|
@@ -39,6 +41,7 @@ module Laser
|
|
39
41
|
end
|
40
42
|
|
41
43
|
def enclosure
|
44
|
+
generate_notches if self.notches.empty?
|
42
45
|
p1 = notches.first.p1.to_a
|
43
46
|
p2 = notches.first.p2.to_a
|
44
47
|
|
@@ -51,32 +54,40 @@ module Laser
|
|
51
54
|
Geometry::Rect[Geometry::Point.new(p1), Geometry::Point.new(p2)]
|
52
55
|
end
|
53
56
|
|
54
|
-
|
55
|
-
def notches
|
56
|
-
generate_notches! if @notches.empty?
|
57
|
-
@notches
|
58
|
-
end
|
59
|
-
|
60
|
-
def generate_notches!
|
57
|
+
def generate_notches
|
61
58
|
position_faces!
|
62
|
-
|
63
59
|
corner_face = pick_corners_face
|
64
|
-
|
65
|
-
@notches = []
|
60
|
+
self.notches = []
|
66
61
|
faces.each_with_index do |face, face_index|
|
67
62
|
bound = face_bounding_rect(face)
|
63
|
+
side_lines = []
|
64
|
+
edges = []
|
68
65
|
bound.sides.each_with_index do |bounding_side, side_index |
|
66
|
+
include_corners = (self.conf[:corners][corner_face][face_index] == :yes && side_index.odd?)
|
69
67
|
key = side_index.odd? ? :valign : :halign
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
68
|
+
center_out = (self.conf[key][face_index] == :out)
|
69
|
+
edges << Notching::Edge.new(bounding_side, face.sides[side_index],
|
70
|
+
{:notch_width => notch_width,
|
71
|
+
:thickness => thickness,
|
72
|
+
:kerf => kerf,
|
73
|
+
:center_out => center_out,
|
74
|
+
:corners => include_corners
|
75
|
+
})
|
76
76
|
end
|
77
|
-
end
|
78
77
|
|
79
|
-
|
78
|
+
if edges.any?{|e| e.corners} && !edges.all?{|e| e.first_notch_out? }
|
79
|
+
edges.each {|e| e.adjust_corners = true }
|
80
|
+
end
|
81
|
+
|
82
|
+
edges.each do |edge|
|
83
|
+
side_lines << Notching::PathGenerator.new(edge).generate
|
84
|
+
end
|
85
|
+
|
86
|
+
aggregator = Aggregator.new(side_lines.flatten)
|
87
|
+
aggregator.dedup!.deoverlap!.dedup!
|
88
|
+
self.notches << aggregator.lines
|
89
|
+
end
|
90
|
+
self.notches.flatten!
|
80
91
|
end
|
81
92
|
|
82
93
|
def w; dim.w; end
|
@@ -95,8 +106,8 @@ module Laser
|
|
95
106
|
|
96
107
|
def face_bounding_rect(face)
|
97
108
|
b = face.clone
|
98
|
-
b.move_to(b.position.
|
99
|
-
b.p2 = b.p2.
|
109
|
+
b.move_to(b.position.plus(-thickness, -thickness))
|
110
|
+
b.p2 = b.p2.plus(2 * thickness, 2 * thickness)
|
100
111
|
b.relocate!
|
101
112
|
end
|
102
113
|
|
@@ -154,11 +165,13 @@ module Laser
|
|
154
165
|
self.right = Geometry::Rect.create(zero, dim.d, dim.h, "right")
|
155
166
|
end
|
156
167
|
|
168
|
+
# Choose which face will be responsible for filling out the little square overlap
|
169
|
+
# in the corners. Only one of the 3 possible sides need to be picked.
|
157
170
|
def pick_corners_face
|
158
171
|
b = face_bounding_rect(front)
|
159
172
|
edges = []
|
160
173
|
front.sides[0..1].each_with_index do |face, index|
|
161
|
-
edges <<
|
174
|
+
edges << Notching::Edge.new(b.sides[index], face, :notch_width => notch_width, :kerf => kerf )
|
162
175
|
end
|
163
176
|
edges.map(&:notch_count).all?{|c| c % 4 == 3} ? :top : :front
|
164
177
|
end
|