convert_svg_string_to_gcode 0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fffdd21de1f5a9589a8cdb8bae44a8d7f2c114fb
4
+ data.tar.gz: d538bee8a59380ef1d77d2f78c2e778afd0dacf1
5
+ SHA512:
6
+ metadata.gz: bbbacdf173ef099cb5df712d6f5aa1aa08a0af40c51b42511f9395dee176b651e962f5f93fd08b07a3946870f4d0c606cc34390b7f4427f13260ec96a93bb168
7
+ data.tar.gz: e00bf27f2038323e47a4a488dd2a316aedf8df75e5cacc292e772c48ed4b59c08c09946981d8881061bc6de9344fd888db9c2b46ba43823631a9756ea3f408cb
@@ -0,0 +1,16 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'convert_svg_string_to_gcode'
6
+ s.version = '0.0.0'
7
+ s.date = '2016-03-24'
8
+ s.summary = "Converts SVG paths to GCode strings"
9
+ s.description = "A gem that converts SVG paths (passed in as strings) into GCode strings"
10
+ s.authors = ["Jesse Furmanek"]
11
+ s.email = 'jesse@trunkclub.com'
12
+ s.files = `git ls-files`.split($/)
13
+ s.homepage =
14
+ 'http://rubygems.org/gems/svg_path_to_gcode'
15
+ s.license = 'MIT'
16
+ end
@@ -0,0 +1,19 @@
1
+ require 'convert_svg_string_to_gcode/parse_svg_string'
2
+ require 'convert_svg_string_to_gcode/tokenize_parsed_svg'
3
+ require 'convert_svg_string_to_gcode/create_commands_from_tokens'
4
+ require 'convert_svg_string_to_gcode/adjust_svg_commands_for_plotter'
5
+ require 'convert_svg_string_to_gcode/create_gcode_array_from_svg_commands'
6
+ require 'convert_svg_string_to_gcode/create_gcode_from_gcode_array'
7
+
8
+ class ConvertSVGStringToGCode
9
+
10
+ def self.perform(svg_as_string)
11
+ parsed_svg = ParseSVGString.perform(svg_as_string)
12
+ svg_tokens = TokenizeParsedSVG.perform(parsed_svg)
13
+ svg_commands = CreateCommandsFromTokens.perform(svg_tokens)
14
+ adjusted_svg_commands = AdjustSVGCommandsForPlotter.perform(svg_commands, 0.10)
15
+ gcode_array = CreateGCodeArrayFromSVGCommands.perform(adjusted_svg_commands)
16
+ CreateGCodeFromGCodeArray.perform(gcode_array)
17
+ end
18
+
19
+ end
@@ -0,0 +1,9 @@
1
+
2
+ class ConversionConstants
3
+ MOVE = 'M'
4
+ LINE_TO = 'L'
5
+ CURVE = 'C'
6
+ X_LABELS = [:x,:cp0x,:cp1x,:p1x]
7
+ Y_LABELS = [:y,:cp0y,:cp1y,:p1y]
8
+ GCODE_COMMANDS = 'CLM'
9
+ end
@@ -0,0 +1,57 @@
1
+
2
+ class AdjustSVGCommandsForPlotter
3
+ def self.perform(svg_commands,proportion=0.10)
4
+ skewed_svg_commands, min_x, min_y = resize_svg_commands_by_proportion_and_get_min_x_y(svg_commands, proportion)
5
+ min_x, min_y = get_min_x_y(skewed_svg_commands)
6
+ buffered_svg_commands = add_margin_to_svg_commands(skewed_svg_commands, min_x, min_y)
7
+ end
8
+
9
+ def self.resize_svg_commands_by_proportion_and_get_min_x_y(svg_commands, proportion)
10
+ min_x = nil
11
+ min_y = nil
12
+ skewed_svg_commands = svg_commands.map do |command|
13
+ mutated_command = {}
14
+ command.each_key do |k|
15
+ mutated_command[k] = Float(command[k])*proportion unless k==:command
16
+ mutated_command[k] = command[k] if k==:command
17
+ end
18
+ mutated_command
19
+ end
20
+ return skewed_svg_commands, min_x, min_y
21
+ end
22
+
23
+ def self.get_min_x_y(svg_commands)
24
+ min_x = nil
25
+ min_y = nil
26
+
27
+ svg_commands.map do |command|
28
+ command.each_key do |key|
29
+ if ConversionConstants::X_LABELS.include? key
30
+ min_x = command[key] if !min_x || command[key]<min_x
31
+ end
32
+
33
+ if ConversionConstants::Y_LABELS.include? key
34
+ min_y = command[key] if !min_y || command[key]<min_y
35
+ end
36
+ end
37
+ end
38
+ return min_x, min_y
39
+ end
40
+
41
+ def self.add_margin_to_svg_commands(svg_commands, min_x, min_y, buffer=20.0)
42
+ svg_commands.map do |command|
43
+ buffered_command={}
44
+ command.each_key do |k|
45
+ if [:x,:cp0x,:cp1x,:p1x].include? k
46
+ buffered_command[k] = command[k]-min_x+buffer
47
+ elsif [:y,:cp0y,:cp1y,:p1y].include? k
48
+ buffered_command[k] = command[k]-min_y+buffer
49
+ else
50
+ buffered_command[k] = command[k]
51
+ end
52
+ end
53
+ buffered_command
54
+ end
55
+ end
56
+
57
+ end
@@ -0,0 +1,28 @@
1
+
2
+ class CreateCommandsFromTokens
3
+ def self.perform(svg_tokens)
4
+ svg_commands = svg_tokens.each_with_index.map do |token, i|
5
+ svg_command=nil
6
+ if token.match(%r{[#{ConversionConstants::GCODE_COMMANDS}]})
7
+ case token
8
+ when ConversionConstants::MOVE
9
+ svg_command = {command: ConversionConstants::MOVE, x: svg_tokens[i+1], y: svg_tokens[i+2]}
10
+ when ConversionConstants::LINE_TO
11
+ svg_command = {command: ConversionConstants::LINE_TO, x: svg_tokens[i+1], y: svg_tokens[i+2]}
12
+ when ConversionConstants::CURVE
13
+ svg_command = {
14
+ command: ConversionConstants::CURVE,
15
+ cp0x: svg_tokens[i+1],
16
+ cp0y: svg_tokens[i+2],
17
+ cp1x: svg_tokens[i+3],
18
+ cp1y: svg_tokens[i+4],
19
+ p1x: svg_tokens[i+5],
20
+ p1y: svg_tokens[i+6]
21
+ }
22
+ end
23
+ end
24
+ svg_command
25
+ end
26
+ svg_commands.compact
27
+ end
28
+ end
@@ -0,0 +1,72 @@
1
+
2
+ class CreateGCodeArrayFromSVGCommands
3
+ def self.perform(commands, options = {step: 0.20})
4
+ start_point = nil
5
+ step=options[:step]
6
+
7
+ gcode_array = commands.map do |c|
8
+ case c[:command]
9
+ when ConversionConstants::MOVE
10
+ command_array, start_point = move_to_point(c)
11
+ when ConversionConstants::LINE_TO
12
+ command_array, start_point = draw_to_point(c)
13
+ when ConversionConstants::CURVE
14
+ command_array, start_point = create_gcode_path_from_bezier(start_point, c,step)
15
+ else
16
+ throw Error
17
+ end
18
+ command_array
19
+ end
20
+ end
21
+
22
+ def self.move_to_point(new_point)
23
+ x_value = new_point[:x].to_f
24
+ y_value = new_point[:y].to_f
25
+ command = ["G0 X#{x_value} Y#{y_value} #{MakeblockXYConfig::Z_UP}"]
26
+ return command, new_point
27
+ end
28
+
29
+ def self.draw_to_point(new_point)
30
+ x_value = new_point[:x].to_f
31
+ y_value = new_point[:y].to_f
32
+ command = ["G1 X#{x_value} Y#{y_value} #{MakeblockXYConfig::Z_DOWN}"]
33
+ return command, new_point
34
+ end
35
+
36
+ def self.create_gcode_path_from_bezier(start_point, svg_command, step)
37
+
38
+ p0x = start_point[:x].to_f
39
+ p0y = start_point[:y].to_f
40
+ cp0x = svg_command[:cp0x].to_f
41
+ cp0y = svg_command[:cp0y].to_f
42
+ cp1x = svg_command[:cp1x].to_f
43
+ cp1y = svg_command[:cp1y].to_f
44
+ p1x = svg_command[:p1x].to_f
45
+ p1y = svg_command[:p1y].to_f
46
+
47
+ t = step
48
+
49
+ gcode_array = []
50
+
51
+ while t<1 do
52
+ ax = ( (1 - t) * p0x ) + (t * cp0x)
53
+ ay = ( (1 - t) * p0y ) + (t * cp0y)
54
+ bx = ( (1 - t) * cp0x ) + (t * cp1x)
55
+ by = ( (1 - t) * cp0y ) + (t * cp1y)
56
+ cx = ( (1 - t) * cp1x ) + (t * p1x)
57
+ cy = ( (1 - t) * cp1y ) + (t * p1y)
58
+
59
+ dx = ( (1 - t) * ax ) + (t * bx)
60
+ dy = ( (1 - t) * ay ) + (t * by)
61
+ ex = ( (1 - t) * bx ) + (t * cx)
62
+ ey = ( (1 - t) * by ) + (t * cy)
63
+
64
+ new_point_x = ( (1 - t) * dx ) + (t * ex)
65
+ new_point_y = ( (1 - t) * dy ) + (t * ey)
66
+ gcode_array << "G1 X#{new_point_x} Y#{new_point_y} Z0"
67
+ t+=step
68
+ end
69
+ return gcode_array, {x: p1x, y: p1y}
70
+ end
71
+
72
+ end
@@ -0,0 +1,18 @@
1
+
2
+ class CreateGCodeFromGCodeArray
3
+ def self.perform(
4
+ gcode_array,
5
+ options = {
6
+ header: MakeblockXYConfig::HEADER,
7
+ footer: MakeblockXYConfig::FOOTER,
8
+ }
9
+ )
10
+
11
+ header = options.fetch(:header)
12
+ footer = options.fetch(:footer)
13
+
14
+ flattened_gcode_array = header + gcode_array.flatten + footer
15
+ flattened_gcode_array.join("\n")
16
+
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ require 'nokogiri'
2
+
3
+ class ParseSVGString
4
+ def self.perform(svg_string)
5
+ return Nokogiri::XML.parse(svg_string)
6
+ end
7
+ end
@@ -0,0 +1,6 @@
1
+
2
+ class TokenizeParsedSVG
3
+ def self.perform(parsed_svg)
4
+ return (parsed_svg.xpath('//path').attribute("d").value.split(%r{([A-Z ])}) - ["", " "])
5
+ end
6
+ end
metadata ADDED
@@ -0,0 +1,52 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: convert_svg_string_to_gcode
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jesse Furmanek
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A gem that converts SVG paths (passed in as strings) into GCode strings
14
+ email: jesse@trunkclub.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - convert_svg_string_to_gcode.gemspec
20
+ - lib/convert_svg_string_to_gcode.rb
21
+ - lib/convert_svg_string_to_gcode/constants/conversion_constants.rb
22
+ - lib/convert_svg_string_to_gcode/helpers/adjust_svg_commands_for_plotter.rb
23
+ - lib/convert_svg_string_to_gcode/helpers/create_commands_from_tokens.rb
24
+ - lib/convert_svg_string_to_gcode/helpers/create_gcode_array_from_svg_commands.rb
25
+ - lib/convert_svg_string_to_gcode/helpers/create_gcode_from_gcode_array.rb
26
+ - lib/convert_svg_string_to_gcode/helpers/parse_svg_string.rb
27
+ - lib/convert_svg_string_to_gcode/helpers/tokenize_parsed_svg.rb
28
+ homepage: http://rubygems.org/gems/svg_path_to_gcode
29
+ licenses:
30
+ - MIT
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubyforge_project:
48
+ rubygems_version: 2.2.2
49
+ signing_key:
50
+ specification_version: 4
51
+ summary: Converts SVG paths to GCode strings
52
+ test_files: []