├── config ├── global.yml ├── acylic.yml └── .DS_Store ├── lib ├── .DS_Store └── general.rb ├── README.md ├── test.g ├── board.rb └── console /config/global.yml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config/acylic.yml: -------------------------------------------------------------------------------- 1 | material: 2 | max_feedrate: 123 -------------------------------------------------------------------------------- /lib/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/em/rg/master/lib/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | rg 2 | == 3 | 4 | This is a dead project. Check out gcanvas. 5 | -------------------------------------------------------------------------------- /config/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/em/rg/master/config/.DS_Store -------------------------------------------------------------------------------- /test.g: -------------------------------------------------------------------------------- 1 | G90 2 | G0 X0 Y0 Z0 F2200 3 | G1 Z-50.0 F2200 4 | G1 X1000.0 Y0 F2200 5 | G0 Z0 F2200 6 | G0 X0 Y0 Z0 F2200 7 | -------------------------------------------------------------------------------- /board.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require_relative 'lib/general.rb' 4 | 5 | GcodeGenerator.new do 6 | margin = 10 7 | mini_itx_width = 500 8 | sheet_width = mini_itx_width + margin*2 9 | sheet_height = 200 + margin*2 10 | sheet_depth = 0.5 11 | 12 | mount_holes = [ 13 | [12,23], 14 | [45,66] 15 | ] 16 | 17 | #jump_to 10,10 18 | 19 | line 10.cm, 0, -0.5.cm 20 | 21 | #rect 10.cm, 10.cm, -0.8.cm, corner_radius:2.cm 22 | 23 | # mount_holes.each do |h| 24 | # drill(*h) 25 | # end 26 | end 27 | -------------------------------------------------------------------------------- /console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | #require File.dirname(__FILE__) + '/../config/boot' 3 | #require File.expand_path('../../config/boot', __FILE__) 4 | require 'irb' 5 | require 'irb/completion' 6 | #require 'map_by_method' 7 | #require 'what_methods' 8 | require 'pp' 9 | 10 | require_relative 'lib/general.rb' 11 | 12 | 13 | class InteractiveGcodeGenerator < GcodeGenerator 14 | include IRB::ExtendCommandBundle # so that Marshal.dump works 15 | 16 | end 17 | 18 | #ARGV.clear 19 | #IRB.start 20 | 21 | module IRB 22 | def IRB.parse_opts 23 | # Don't touch ARGV, which belongs to the app which called this module. 24 | end 25 | 26 | def IRB.start_session(*args) 27 | unless $irb 28 | IRB.setup nil 29 | ## maybe set some opts here, as in parse_opts in irb/init.rb? 30 | end 31 | 32 | workspace = WorkSpace.new(*args) 33 | 34 | if @CONF[:SCRIPT] ## normally, set by parse_opts 35 | $irb = Irb.new(workspace, @CONF[:SCRIPT]) 36 | else 37 | $irb = Irb.new(workspace) 38 | end 39 | 40 | @CONF[:IRB_RC].call($irb.context) if @CONF[:IRB_RC] 41 | @CONF[:MAIN_CONTEXT] = $irb.context 42 | 43 | trap 'INT' do 44 | $irb.signal_handle 45 | end 46 | 47 | custom_configuration if defined?(IRB.custom_configuration) 48 | 49 | catch :IRB_EXIT do 50 | $irb.eval_input 51 | end 52 | 53 | ## might want to reset your app's interrupt handler here 54 | end 55 | end 56 | 57 | if __FILE__ == $0 58 | x = InteractiveGcodeGenerator.new 59 | puts 'gcode generation subshell' 60 | IRB.start_session(x) 61 | #puts "\nStarted irb shell for x with current binding" 62 | #IRB.start_session(binding, x) 63 | #puts "\nRestarted irb shell for x with current binding" 64 | #$irb.eval_input 65 | #puts "\nExited irb shell" 66 | p x 67 | end 68 | -------------------------------------------------------------------------------- /lib/general.rb: -------------------------------------------------------------------------------- 1 | class Float 2 | def mm 3 | to_f 4 | end 5 | def cm 6 | mm*100.0 7 | end 8 | def inches 9 | mm*25.4 10 | end 11 | end 12 | 13 | class Fixnum 14 | def mm 15 | to_f 16 | end 17 | def cm 18 | mm*100.0 19 | end 20 | def inches 21 | mm*25.4 22 | end 23 | end 24 | 25 | class CNCGenerator 26 | end 27 | 28 | class GcodeGenerator < CNCGenerator 29 | attr_accessor :material 30 | attr_accessor :x, :y, :z 31 | attr_accessor :cut_depth_limit # Max depth the endmill can be embedded in the material per a cut 32 | attr_accessor :cut_speed_limit # Max cutting speed for the material in mm/sec 33 | 34 | RAPID = 'G0' 35 | LINE = 'G1' 36 | CLW_ARC = 'G2' 37 | CCW_ARC = 'G3' 38 | MODE_ABSOLUTE = 'G90' 39 | MOVEMENT_FUNCTIONS = [RAPID,LINE] 40 | 41 | def initialize(&job) 42 | @x = @y = @z = 0 43 | g MODE_ABSOLUTE # Intentionally normalizing everything to absolute 44 | g RAPID, X:x, Y:y, Z:z 45 | self.instance_eval(&job) if job 46 | g RAPID, X:0, Y:0, Z:0 47 | end 48 | 49 | def g(code, args = {}) 50 | 51 | args[:F] ||= material_feedrate if MOVEMENT_FUNCTIONS.include?(code) 52 | 53 | args.each do |k,v| 54 | next if v.nil? 55 | 56 | k = k.upcase 57 | code += ' %s%s' % [k, v] 58 | 59 | case k 60 | when :X then @x = v 61 | when :Y then @y = v 62 | when :Z then @z = v 63 | end 64 | end 65 | 66 | puts ' ' + code 67 | 68 | code 69 | end 70 | 71 | def retract 72 | g RAPID, Z:0 73 | end 74 | 75 | def insert(depth=material_depth, &block) 76 | g LINE, Z:depth 77 | 78 | if block 79 | yield block 80 | retract 81 | end 82 | end 83 | 84 | def jump_to(x=nil,y=nil) 85 | retract 86 | g RAPID, X: x, Y: y 87 | end 88 | 89 | def line(x=nil,y=nil,depth=nil) 90 | insert depth 91 | g LINE, X: x, Y: y 92 | retract 93 | end 94 | 95 | def rect(width, height, depth, options = {}) 96 | start_x = @x 97 | start_y = @y 98 | start_z = @z 99 | 100 | # Adjust for the bit diameter 101 | if options[:negative] 102 | start_x += bit_diameter 103 | start_y += bit_diameter 104 | else 105 | width += bit_diameter 106 | height += bit_diameter 107 | end 108 | 109 | corner_radius = options[:corner_radius].to_f || nil 110 | 111 | if corner_radius && corner_radius != 0 112 | # Round rect 113 | g RAPID, X:start_x+corner_radius 114 | g LINE, Z:start_z+depth # Insert 115 | 116 | g LINE, X:start_x+width-corner_radius 117 | g CCW_ARC, X:start_x+width, Y:start_y+corner_radius, I:0, J:corner_radius 118 | g LINE, Y:start_y+height-corner_radius 119 | g CCW_ARC, X:start_x+width-corner_radius, Y:start_y+height, I: -corner_radius, J: 0 120 | g LINE, X:start_x+corner_radius 121 | g CCW_ARC, X:start_x, Y:start_y+height-corner_radius, I: 0, J: -corner_radius 122 | g LINE, Y:start_x+corner_radius 123 | g CCW_ARC, X:start_x+corner_radius, Y:start_y, I: corner_radius, J: 0 124 | 125 | else 126 | # Simple rect 127 | g LINE, X:start_x+width 128 | g LINE, Y:start_y+height 129 | g LINE, X:start_x 130 | g LINE, Y:start_y 131 | end 132 | end 133 | 134 | def drill(x=nil,y=nil,depth=nil) 135 | jump_to x, y 136 | insert 137 | retract 138 | end 139 | 140 | def layers(layer_depth=material_layer_depth, total_depth=material_depth, &block) 141 | start_z = @z 142 | depth = 0 143 | while depth < total_depth 144 | depth += layer_depth 145 | yield depth 146 | end 147 | end 148 | 149 | def config(name) 150 | yml = YAML::load( File.open('config/'+name) ) 151 | 152 | material.merge!(yml.material) if yml.material 153 | machine.merge!(yml.machine) if yml.machine 154 | end 155 | 156 | def right(d) y -d end 157 | def left(d) x -d end 158 | def down(d) y d end 159 | def up(d) y -d end 160 | 161 | private 162 | def gxyz(x=nil,y=nil,z=nil) 163 | @x = x 164 | @y = y 165 | @y = z 166 | result = '' 167 | result += gx(x) if x 168 | result += gy(y) if y 169 | result += gz(z) if z 170 | end 171 | def gx(x) 172 | ' X%f' % @x = x 173 | end 174 | def gy(y) 175 | ' Y%f' % @y = y 176 | end 177 | def gz(z) 178 | ' Z%f' % @z = z 179 | end 180 | 181 | def material_feedrate 182 | 2000 183 | end 184 | 185 | def material_depth 186 | 1.cm 187 | end 188 | 189 | def material_layer_depth 190 | 10.mm 191 | end 192 | 193 | def material_feedrate 194 | 2200 195 | end 196 | 197 | def bit_diameter 198 | (1.0/8.0).inches 199 | end 200 | 201 | def bit_radius 202 | bit_diameter / 2 203 | end 204 | end 205 | --------------------------------------------------------------------------------