laser-cutter 0.5.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
![LaserCutter Comparison](doc/comparison.jpg).
|
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
|