diff --git a/README.md b/README.md index a827a79..d483e57 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,15 @@ +## Basement Ooza Basics + +The hacked together pipeline is as follows given an svg `$SVG`. You may use the `Woodbine.svg` file as an example for testing. + +1. Ensure that your SVG has a size set that fits in Ooza + 1. One way to ensure is by setting width & height on the root `` element +2. Covert the SVG to gcode via `cargo run --release -- $SVG -o $OUTFILE` +3. Rewrite the gcode to center where the print happens via `python rewritegcode.py $OUTFILE $UPDATEFILE` +4. (Optional) Verify the maximum x & y values fit on the board via `python parsegcode.py $UPDATEFILE` +5. Generate the final file by concatenating the header to the updated file via `cat ooza/config.g $UPDATEFILE > $FINALEFILE` +6. Upload `$FINALFILE` to Jobs in Duet and run it + # svg2gcode [![Build, test, and publish coverage for svg2gcode](https://github.com/sameer/svg2gcode/actions/workflows/lib.yml/badge.svg)](https://github.com/sameer/svg2gcode/actions/workflows/lib.yml) diff --git a/Woodbine.svg b/Woodbine.svg new file mode 100644 index 0000000..bd5a94b --- /dev/null +++ b/Woodbine.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ooza/config.g b/ooza/config.g new file mode 100644 index 0000000..ffaa1c2 --- /dev/null +++ b/ooza/config.g @@ -0,0 +1,61 @@ +; Configuration file for Duet 3 (firmware version 3.3) +; executed by the firmware on start-up +; +; generated by RepRapFirmware Configuration Tool v3.3.10 on Mon Mar 14 2022 19:57:00 GMT+0100 (heure normale d’Europe centrale) + +; General preferences +G90 ; send absolute coordinates... +M83 ; ...but relative extruder moves +M453 ; Put the machine into CNC Modes +M550 P"ooza" ; set printer name + +; Drives +M569 P0.1 S1 ; physical drive 0.0 goes BACKWARDS X +M569 P0.2 S1 ; physical drive 0.1 goes FORWARDS Y1 +M569 P0.4 S1 ; physical drive 0.2 goes FORWARDS Y2 +M569 P0.3 S1 ; physical drive 0.3 goes BACKWARDS Z +M584 X0.1 Y0.2:0.4 Z0.3 ; set drive mapping +M350 X16 Y16 Z16 I1 ; configure microstepping with interpolation +M92 X400.00 Y400.00 Z400.00 ; set steps per mm +M566 X500.00 Y500.00 Z500.00 ; set maximum instantaneous speed changes (mm/min) +M203 X2500.00 Y2500.00 Z2500.00 ; set maximum speeds (mm/min) +M201 X150.00 Y150.00 Z150.00 ; set accelerations (mm/s^2) +M906 X2400 Y2400 Z2400 I100 ; set motor currents (mA) and motor idle factor in per cent + + +; Axis Limits +M208 X0 Y0 Z0 S1 ; set axis minima +M208 X798 Y1300 Z103 S0 ; set axis maxima + +; Endstops +M574 X1 S1 P"!io6.in" ; configure switch-type (e.g. microswitch) endstop for low end on X via pin io0.in +M574 Y2 S1 P"!io8.in" ; configure switch-type (e.g. microswitch) endstop for HIGH end on Y via pin io1.in +M574 Z2 S1 P"!io7.in" ; configure switch-type (e.g. microswitch) endstop for HIGH end on Z via pin io2.in + +; Spindle +;M950 R0 C"vfd" L0:25000 Q1000 ; Create spindle index 0 +;M563 P1 S"Spindle 1" R0 ; Create tool 1 with spindle 0 and call it "Spindle 1" +;M453 +;T1 ; select tool 1 +;M3 S0 +;M5 ;stop spindle + +; Fans +;M950 F0 C"!out6" Q500 ; create fan 0 on pin out7 and set its frequency +;M106 P0 S0.5 H-1 ; set fan 0 value. Thermostatic control is turned off + +; Z-Probe +;M558 K0 P8 C"!io7.in" H10 F120 T3000 ; Z probe 0 via pin io6.in +;G31 Z10.0 ; set current probe status + +; Tools +M950 P0 C"!out1" Q65535 ; power to omega pressure regulator. sets out1 pin to be always on, basically just voltage supply +;M950 P1 C"io3.out" Q10000 ;OMEGA pressure regulator control on 3.3v pwm (io3.out) + +M950 P2 C"out7" Q65535 ; solenoid control, on out7 +M950 F0 C"out9" Q2000 ;OMEGA pressure regulator control on 5v pwm +M106 P0 C"regulator" X0.45 H-1 + + +; Custom settings are not defined + diff --git a/ooza/config.ini b/ooza/config.ini new file mode 100644 index 0000000..966b992 --- /dev/null +++ b/ooza/config.ini @@ -0,0 +1,474 @@ +# generated by SuperSlicer 2.4 on 2023-05-07 at 18:21:05 UTC +allow_empty_layers = 0 +avoid_crossing_not_first_layer = 1 +avoid_crossing_perimeters = 0 +avoid_crossing_perimeters_max_detour = 0 +bed_custom_model = G:\\My Drive\\Sync\\SuperSlicer\\Beds\\voron2_350bed.stl +bed_custom_texture = G:\\My Drive\\Sync\\SuperSlicer\\Beds\\V2_bed_smooth_pei.png +bed_shape = 0x0,798x0,798x1300,0x1300 +bed_temperature = 110 +before_layer_gcode = +between_objects_gcode = +bottom_fill_pattern = monotonicgapfill +bottom_solid_layers = 3 +bottom_solid_min_thickness = 1 +bridge_acceleration = 5000 +bridge_angle = 0 +bridge_fan_speed = -1 +bridge_flow_ratio = 85% +bridge_internal_acceleration = 5000 +bridge_internal_fan_speed = -1 +bridge_overlap = 50% +bridge_overlap_min = 50% +bridge_speed = 140 +bridge_speed_internal = 100% +bridge_type = nozzle +bridged_infill_margin = 200% +brim_acceleration = 5000 +brim_ears = 0 +brim_ears_detection_length = 1 +brim_ears_max_angle = 120 +brim_ears_pattern = concentric +brim_inside_holes = 0 +brim_separation = 0 +brim_speed = 50% +brim_width = 0 +brim_width_interior = 0 +chamber_temperature = 50 +clip_multipart_objects = 1 +color_change_gcode = M600 +colorprint_heights = +compatible_printers_condition_cummulative = "printer_notes=~/.*Onyx 0\\.4.*/";printer_notes=~/.*Onyx.*/ +compatible_prints_condition_cummulative = notes=~/.*Onyx.*/ +complete_objects = 0 +complete_objects_one_brim = 0 +complete_objects_one_skirt = 0 +complete_objects_sort = object +cooling_tube_length = 5 +cooling_tube_retraction = 91.5 +curve_smoothing_angle_concave = 0 +curve_smoothing_angle_convex = 0 +curve_smoothing_cutoff_dist = 2 +curve_smoothing_precision = 0 +default_acceleration = 0 +default_filament_profile = "" +default_print_profile = +default_speed = 100 +deretract_speed = 0 +disable_fan_first_layers = 1 +dont_support_bridges = 1 +draft_shield = disabled +duplicate_distance = 6 +end_filament_gcode = "; Filament-specific end gcode \n;END gcode for filament\n" +end_gcode = PRINT_END +enforce_full_fill_volume = 1 +enforce_retract_first_layer = 1 +ensure_vertical_shell_thickness = 1 +exact_last_layer_height = 0 +external_infill_margin = 4 +external_perimeter_acceleration = 1000 +external_perimeter_cut_corners = 0% +external_perimeter_extrusion_spacing = +external_perimeter_extrusion_width = 100% +external_perimeter_fan_speed = -1 +external_perimeter_overlap = 100% +external_perimeter_speed = 80 +external_perimeters_first = 0 +external_perimeters_hole = 1 +external_perimeters_nothole = 1 +external_perimeters_vase = 0 +extra_loading_move = -2 +extra_perimeters = 0 +extra_perimeters_odd_layers = 0 +extra_perimeters_overhangs = 1 +extruder_clearance_height = 20 +extruder_clearance_radius = 20 +extruder_colour = "" +extruder_fan_offset = 0% +extruder_offset = 0x0 +extruder_temperature_offset = 0 +extrusion_axis = E +extrusion_multiplier = 0.9 +extrusion_spacing = +extrusion_width = 115% +fan_always_on = 1 +fan_below_layer_time = 0 +fan_kickstart = 0 +fan_percentage = 0 +fan_speedup_overhangs = 1 +fan_speedup_time = 1 +feature_gcode = +filament_colour = #80FF08 +filament_cooling_final_speed = 3.4 +filament_cooling_initial_speed = 2.2 +filament_cooling_moves = 4 +filament_cooling_zone_pause = 0 +filament_cost = 22 +filament_custom_variables = "" +filament_density = 1.03 +filament_deretract_speed = nil +filament_diameter = 1.75 +filament_dip_extraction_speed = 70 +filament_dip_insertion_speed = 33 +filament_enable_toolchange_part_fan = 0 +filament_enable_toolchange_temp = 0 +filament_load_time = 0 +filament_loading_speed = 28 +filament_loading_speed_start = 3 +filament_max_overlap = 100% +filament_max_speed = 0 +filament_max_volumetric_speed = 0 +filament_max_wipe_tower_speed = 0 +filament_melt_zone_pause = 0 +filament_minimal_purge_on_wipe_tower = 15 +filament_notes = Onyx +filament_ramming_parameters = "120 100 6.6 6.8 7.2 7.6 7.9 8.2 8.7 9.4 9.9 10.0| 0.05 6.6 0.45 6.8 0.95 7.8 1.45 8.3 1.95 9.7 2.45 10 2.95 7.6 3.45 7.6 3.95 7.6 4.45 7.6 4.95 7.6" +filament_retract_before_travel = nil +filament_retract_before_wipe = nil +filament_retract_layer_change = nil +filament_retract_length = nil +filament_retract_lift = nil +filament_retract_lift_above = nil +filament_retract_lift_below = nil +filament_retract_restart_extra = nil +filament_retract_speed = nil +filament_seam_gap = nil +filament_settings_id = "Onyx ABS" +filament_shrink = 100% +filament_skinnydip_distance = 31 +filament_soluble = 0 +filament_spool_weight = 0 +filament_toolchange_delay = 0 +filament_toolchange_part_fan_speed = 50 +filament_toolchange_temp = 200 +filament_type = ABS +filament_unload_time = 0 +filament_unloading_speed = 90 +filament_unloading_speed_start = 100 +filament_use_fast_skinnydip = 0 +filament_use_skinnydip = 0 +filament_vendor = (Unknown) +filament_wipe = nil +filament_wipe_advanced_pigment = 0.5 +filament_wipe_extra_perimeter = nil +filament_wipe_inside_depth = nil +filament_wipe_inside_end = nil +filament_wipe_inside_start = nil +filament_wipe_only_crossing = nil +filament_wipe_speed = nil +fill_angle = 45 +fill_angle_increment = 0 +fill_density = 41% +fill_pattern = cubic +fill_smooth_distribution = 10% +fill_smooth_width = 50% +fill_top_flow_ratio = 100% +first_layer_acceleration = 2000 +first_layer_acceleration_over_raft = 0 +first_layer_bed_temperature = 110 +first_layer_extrusion_spacing = +first_layer_extrusion_width = 125% +first_layer_flow_ratio = 100% +first_layer_height = 0.25 +first_layer_infill_speed = 60 +first_layer_min_speed = 0 +first_layer_size_compensation = -0.1 +first_layer_size_compensation_layers = 3 +first_layer_speed = 30 +first_layer_speed_over_raft = 30 +first_layer_temperature = 245 +full_fan_speed_layer = 0 +fuzzy_skin = none +fuzzy_skin_point_dist = 200% +fuzzy_skin_thickness = 150% +gap_fill_acceleration = 2000 +gap_fill_enabled = 0 +gap_fill_flow_match_perimeter = 0% +gap_fill_last = 1 +gap_fill_min_area = 50% +gap_fill_overlap = 100% +gap_fill_speed = 60 +gcode_comments = 0 +gcode_filename_illegal_char = [<>:"/\\\\|?*] +gcode_flavor = reprapfirmware +gcode_label_objects = 1 +gcode_precision_e = 5 +gcode_precision_xyz = 3 +gcode_resolution = 0 +gcode_substitutions = +high_current_on_filament_swap = 0 +hole_size_compensation = 0 +hole_size_threshold = 100 +hole_to_polyhole = 0 +hole_to_polyhole_threshold = 0.01 +hole_to_polyhole_twisted = 1 +host_type = octoprint +infill_acceleration = 7000 +infill_anchor = 600% +infill_anchor_max = 0 +infill_connection = connected +infill_connection_bottom = connected +infill_connection_solid = connected +infill_connection_top = connected +infill_dense = 0 +infill_dense_algo = autoenlarged +infill_every_layers = 1 +infill_extruder = 1 +infill_extrusion_spacing = +infill_extrusion_width = 160% +infill_first = 0 +infill_only_where_needed = 0 +infill_overlap = 25% +infill_speed = 200 +init_z_rotate = 0 +interface_shells = 0 +ironing = 0 +ironing_acceleration = 2000 +ironing_angle = -1 +ironing_flowrate = 15% +ironing_spacing = 0.1 +ironing_speed = 15 +ironing_type = top +layer_gcode = +layer_height = 0.2 +lift_min = 0 +machine_limits_usage = time_estimate_only +machine_max_acceleration_e = 10000,5000 +machine_max_acceleration_extruding = 10000,1250 +machine_max_acceleration_retracting = 1500,1250 +machine_max_acceleration_travel = 10000,1250 +machine_max_acceleration_x = 10000,1000 +machine_max_acceleration_y = 10000,1000 +machine_max_acceleration_z = 300,200 +machine_max_feedrate_e = 120,120 +machine_max_feedrate_x = 450,200 +machine_max_feedrate_y = 450,200 +machine_max_feedrate_z = 30,12 +machine_max_jerk_e = 2.5,2.5 +machine_max_jerk_x = 10,10 +machine_max_jerk_y = 10,10 +machine_max_jerk_z = 0.2,0.4 +machine_min_extruding_rate = 0,0 +machine_min_travel_rate = 0,0 +max_fan_speed = 100 +max_gcode_per_second = 1500 +max_layer_height = 75% +max_print_height = 103 +max_print_speed = 300 +max_speed_reduction = 90% +max_volumetric_speed = 11 +milling_after_z = 200% +milling_diameter = +milling_extra_size = 150% +milling_post_process = 0 +milling_speed = 30 +milling_toolchange_end_gcode = +milling_toolchange_start_gcode = +milling_z_lift = +min_fan_speed = 75 +min_layer_height = 0.08 +min_length = 0 +min_print_speed = 10 +min_skirt_length = 20 +min_width_top_surface = 200% +mmu_segmented_region_max_width = 0 +model_precision = 0.0001 +no_perimeter_unsupported_algo = none +notes = Onyx +nozzle_diameter = 0.4 +only_one_perimeter_first_layer = 0 +only_one_perimeter_top = 1 +only_one_perimeter_top_other_algo = 0 +only_retract_when_crossing_perimeters = 1 +ooze_prevention = 0 +output_filename_format = [input_filename_base]-[printer_settings_id]-[filament_settings_id].gcode +over_bridge_flow_ratio = 100% +overhangs_acceleration = 2000 +overhangs_reverse = 0 +overhangs_reverse_threshold = 250% +overhangs_speed = 100% +overhangs_width = 75% +overhangs_width_speed = 0 +parking_pos_retraction = 92 +pause_print_gcode = PAUSE +perimeter_acceleration = 2000 +perimeter_bonding = 0% +perimeter_extruder = 1 +perimeter_extrusion_spacing = +perimeter_extrusion_width = 0 +perimeter_loop = 0 +perimeter_loop_seam = rear +perimeter_overlap = 100% +perimeter_round_corners = 0 +perimeter_speed = 150 +perimeters = 3 +physical_printer_settings_id = Ooza +post_process = +print_custom_variables = +print_extrusion_multiplier = 100% +print_host = +print_retract_length = -1 +print_retract_lift = -1 +print_settings_id = Onyx 11mm3 0.4 +print_temperature = 0 +printer_custom_variables = +printer_model = +printer_notes = Onyx 0.4 +printer_settings_id = Ooza 0.4 nozzle +printer_technology = FFF +printer_variant = +printer_vendor = +printhost_apikey = +printhost_cafile = +printhost_port = +raft_contact_distance = 0.1 +raft_expansion = 1.5 +raft_first_layer_density = 90% +raft_first_layer_expansion = 3 +raft_layers = 0 +remaining_times = 1 +remaining_times_type = m73 +resolution = 0.0125 +resolution_internal = 0.2 +retract_before_travel = 2 +retract_before_wipe = 0% +retract_layer_change = 0 +retract_length = 2 +retract_length_toolchange = 10 +retract_lift = 0.5 +retract_lift_above = 0.25 +retract_lift_below = 0 +retract_lift_first_layer = 0 +retract_lift_top = "All surfaces" +retract_restart_extra = 0 +retract_restart_extra_toolchange = 0 +retract_speed = 40 +seam_angle_cost = 100% +seam_gap = 0 +seam_position = cost +seam_travel_cost = 0% +silent_mode = 0 +single_extruder_multi_material = 0 +single_extruder_multi_material_priming = 1 +skirt_brim = 0 +skirt_distance = 3 +skirt_distance_from_brim = 1 +skirt_extrusion_width = 0 +skirt_height = 1 +skirts = 1 +slice_closing_radius = 0.049 +slicing_mode = regular +slowdown_below_layer_time = 15 +small_perimeter_max_length = 20 +small_perimeter_min_length = 6 +small_perimeter_speed = 60 +solid_fill_pattern = monotonic +solid_infill_acceleration = 5000 +solid_infill_below_area = 0 +solid_infill_every_layers = 0 +solid_infill_extruder = 1 +solid_infill_extrusion_spacing = +solid_infill_extrusion_width = 140% +solid_infill_overlap = 100% +solid_infill_speed = 200 +solid_over_perimeters = 1 +spiral_vase = 0 +standby_temperature_delta = -5 +start_filament_gcode = "; Filament gcode\n\n; Macro syntax: https://help.prusa3d.com/article/macros_1775\n; The \"=~\" operator uses regex enlosed by forward slashes (=~/regex/).\n; The \"==\" operator can be used for an exact match instead if you wish (==\"string\").\n\n; The below logic says:\n; - IF printer settings profile name contains \"Voron\" (using regex)\n; - AND nozzle size equals \n; - THEN insert the gcode (SET_ PRESSURE ADVANCE ADVANCE=).\n; Uncomment all lines below (and modify appropriately) if you wish to use this.\n\n;{if printer_settings_id =~/.*Voron.*/ and nozzle_diameter[0]==0.4}SET_PRESSURE_ADVANCE ADVANCE=0.0495\n;{elsif printer_settings_id =~/.*Voron.*/ and nozzle_diameter[0]==0.6}SET_PRESSURE_ADVANCE ADVANCE=0.04\n;{endif}\n\n" +start_gcode = ; For use with stock macro, without passing variables\nprint_start EXTRUDER=[first_layer_temperature] BED=[first_layer_bed_temperature]\n\n;; If you are passing variables to PRINT_START, comment out above and use below start g-code instead.\n;; Guide: https://github.com/AndrewEllis93/Print-Tuning-Guide/blob/main/articles/passing_slicer_variables.md\n;; Make sure the variable names match (e.g. if you use "EXTRUDER" instead of "HOTEND")\n;M104 S0 ; Stops PS/SS from sending temp waits separately\n;M140 S0\n;PRINT_START BED=[first_layer_bed_temperature] HOTEND={first_layer_temperature[initial_extruder]+extruder_temperature_offset[initial_extruder]} CHAMBER=[chamber_temperature] +start_gcode_manual = 1 +support_material = 0 +support_material_acceleration = 5000 +support_material_angle = 0 +support_material_auto = 1 +support_material_bottom_contact_distance = 0 +support_material_bottom_interface_layers = -1 +support_material_buildplate_only = 0 +support_material_closing_radius = 2 +support_material_contact_distance = 0.1 +support_material_contact_distance_type = filament +support_material_enforce_layers = 0 +support_material_extruder = 1 +support_material_extrusion_width = 0 +support_material_interface_acceleration = 5000 +support_material_interface_contact_loops = 0 +support_material_interface_extruder = 1 +support_material_interface_fan_speed = -1 +support_material_interface_layers = 3 +support_material_interface_pattern = rectilinear +support_material_interface_spacing = 0.2 +support_material_interface_speed = 100 +support_material_pattern = rectilinear +support_material_spacing = 3 +support_material_speed = 120 +support_material_style = grid +support_material_synchronize_layers = 0 +support_material_threshold = 30 +support_material_with_sheath = 0 +support_material_xy_spacing = 75% +temperature = 245 +template_custom_gcode = +thin_perimeters = 80% +thin_perimeters_all = 20% +thin_walls = 1 +thin_walls_acceleration = 2000 +thin_walls_merge = 1 +thin_walls_min_width = 33% +thin_walls_overlap = 50% +thin_walls_speed = 80 +threads = 8 +thumbnails = 32x32,400x300 +thumbnails_color = #00FF00 +thumbnails_custom_color = 1 +thumbnails_end_file = 0 +thumbnails_format = PNG +thumbnails_with_bed = 1 +time_cost = 0 +time_estimation_compensation = 100% +time_start_gcode = 20 +time_toolchange = 30 +tool_name = "" +toolchange_gcode = +top_fan_speed = -1 +top_fill_pattern = monotonicgapfill +top_infill_extrusion_spacing = +top_infill_extrusion_width = 100% +top_solid_infill_acceleration = 2000 +top_solid_infill_speed = 60 +top_solid_layers = 3 +top_solid_min_thickness = 1 +travel_acceleration = 10000 +travel_deceleration_use_target = 1 +travel_speed = 450 +travel_speed_z = 0 +use_firmware_retraction = 0 +use_relative_e_distances = 1 +use_volumetric_e = 0 +variable_layer_height = 1 +wipe = 0 +wipe_advanced = 0 +wipe_advanced_algo = linear +wipe_advanced_multiplier = 60 +wipe_advanced_nozzle_melted_volume = 120 +wipe_extra_perimeter = 0 +wipe_inside_depth = 50% +wipe_inside_end = 1 +wipe_inside_start = 0 +wipe_into_infill = 0 +wipe_into_objects = 0 +wipe_only_crossing = 1 +wipe_speed = 0 +wipe_tower = 0 +wipe_tower_bridging = 10 +wipe_tower_brim_width = 2 +wipe_tower_no_sparse_layers = 0 +wipe_tower_rotation_angle = 0 +wipe_tower_width = 60 +wipe_tower_x = 180 +wipe_tower_y = 140 +wiping_volumes_extruders = 70,70 +wiping_volumes_matrix = 0 +xy_inner_size_compensation = 0 +xy_size_compensation = 0 +z_offset = 0 +z_step = 0.01 diff --git a/parsegcode.py b/parsegcode.py new file mode 100644 index 0000000..a81b903 --- /dev/null +++ b/parsegcode.py @@ -0,0 +1,40 @@ +import re +import sys + + +def get_xy(line): + xmatch = re.search(r"X(\d*)", line) + ymatch = re.search(r"Y(\d*)", line) + + if xmatch is None or ymatch is None: + return None, None + + xval = int(xmatch.group().strip("X")) + yval = int(ymatch.group().strip("Y")) + return xval, yval + + +def parse_file(fname): + with open(fname) as fp: + lines = fp.read().splitlines() + + minx = float('inf') + miny = float('inf') + maxx = float('-inf') + maxy = float('-inf') + + for line in lines: + x, y = get_xy(line) + + if x is None or y is None: + continue + + minx = min(x, minx) + maxx = max(x, maxx) + miny = min(y, miny) + maxy = max(y, maxy) + + print(f"MinX={minx}, MinY={miny}, MaxX={maxx}, MaxY={maxy}") + +if __name__ == '__main__': + parse_file(sys.argv[1]) diff --git a/rewritegcode.py b/rewritegcode.py new file mode 100644 index 0000000..3b8e911 --- /dev/null +++ b/rewritegcode.py @@ -0,0 +1,43 @@ +import re +import sys + +XADD = 150 +YADD = 300 + +def get_xy(line): + xmatch = re.search(r"X(\d*\.\d*)", line) + ymatch = re.search(r"Y(\d*\.\d*)", line) + + if xmatch is None or ymatch is None: + return None, None + + xval = float(xmatch.group().strip("X")) + yval = float(ymatch.group().strip("Y")) + return xval, yval + + +def rewrite_gcode(infile, outfile): + with open(infile) as fp: + lines = fp.read().splitlines() + + fp = open(outfile, 'w') + + # Home the board after bed is setup + fp.write("G28\n") + + for line in lines: + x, y = get_xy(line) + prefix = line[:2] + + if x is None or y is None: + if prefix != "M2": + fp.write(f"{line}\n") + continue + + postfix = "" if prefix == "G0" else " F1500" + fp.write(f"{prefix} X{x+XADD} Y{y+YADD}{postfix}\n") + + fp.close() + +if __name__ == '__main__': + rewrite_gcode(sys.argv[1], sys.argv[2])