def entertower(layer_hght): purgeheight = layer_hght - v.cur_tower_z_delta if v.current_position_z != purgeheight: v.max_tower_delta = max(v.cur_tower_z_delta, v.max_tower_delta) gcode.issue_code(";------------------------------", True) gcode.issue_code("; P2PP DELTA ENTER", True) gcode.issue_code( "; Current printing Z = {:.2f}".format(v.current_position_z), True) gcode.issue_code("; Tower Z = {:.2f}".format(purgeheight), True) gcode.issue_code( "; Delta = {:.2f} ".format(v.current_position_z - purgeheight), True) gcode.issue_code(";------------------------------", True) if v.retraction >= 0: purgetower.retract(v.current_tool) if v.manual_filament_swap: swap.swap_pause("M25") # unpause z-move is not required gcode.issue_code("G1 X{} Y{} F8640".format(v.current_position_x, v.current_position_y)) gcode.issue_code("G1 Z{:.2f} F10810".format(purgeheight)) if purgeheight <= (v.first_layer_height + 0.02): # FIRST LAYER PURGES SLOWER gcode.issue_code("G1 F{}".format(min(1200, v.wipe_feedrate))) else: gcode.issue_code("G1 F{}".format(v.wipe_feedrate)) v.disable_z = True
def create_sidewipe_bb3d(length): # purge blobs should all be same size if v.bigbrain3d_matrix_blobs and v.bigbrain3d_last_toolchange >= 0: filin = int(v.bigbrain3d_last_toolchange / 10) filout = v.bigbrain3d_last_toolchange % 10 matidx = filin * v.colors + filout purgeblobs = int(v.wiping_info[matidx]) correction = 0 length = purgeblobs * v.mechpurge_blob_size else: purgeleft = length % v.mechpurge_blob_size purgeblobs = int(length / v.mechpurge_blob_size) if purgeleft > 1: purgeblobs += 1 correction = v.mechpurge_blob_size * purgeblobs - length if v.single_blob: purgeblobs = 1 correction = 0 issue_code(";-------------------------------", True) issue_code("; P2PP BB3DBLOBS: {:.0f} BLOB(S)".format(purgeblobs), True) issue_code(";-------------------------------", True) issue_code("; Req={:.2f}mm Act={:.2f}mm".format(length, length + correction)) issue_code("; Purge difference {:.2f}mm".format(correction)) issue_code(";-------------------------------") if v.retraction == 0: purgetower.largeretract(v.mechpurge_retract) keep_xpos = v.current_position_x keep_ypos = v.current_position_y if v.retraction > -v.mechpurge_retract: diff = -v.mechpurge_retract - v.retraction issue_code("\nG1 E{:.3f} ; retract to -{}mm".format( diff, v.mechpurge_retract)) if v.bigbrain3d_y_position is not None: issue_code( "\nG1 Y{:.3f} F8640 ; change Y position to purge equipment". format(v.bigbrain3d_y_position)) if v.current_position_z < v.mechpurge_minimalclearenceheight: issue_code( "\nG1 Z{:.3f} F8640 ; Increase Z to prevent collission with bed" .format(v.mechpurge_minimalclearenceheight)) issue_code("G1 X{:.3f} F10800 ; go near edge of bed".format( v.mechpurge_x_position - 30)) if v.manual_filament_swap: swap.swap_pause("M25") swap.swap_unpause() issue_code("{} ; wait for the print buffer to clear".format( v.finish_moves)) v.processed_gcode.append( "M907 X{} ; increase motor power".format( v.bigbrain3d_motorpower_high)) issue_code( "; -- P2PP -- Generating {} blobs for {}mm of purge".format( purgeblobs, length), True) if v.single_blob: generate_bb3d_blob(length, 0) else: for i in range(purgeblobs): generate_bb3d_blob(v.mechpurge_blob_size, i) if not v.retraction < 0: purgetower.retract(v.current_tool) if v.current_position_z < v.mechpurge_minimalclearenceheight: if keep_xpos > v.bed_max_x or keep_xpos < v.bed_origin_x: keep_xpos = (v.bed_max_x - v.bed_origin_x) / 2 if keep_ypos > v.bed_max_y or keep_ypos < v.bed_origin_y: keep_ypos = (v.bed_max_y - v.bed_origin_y) / 2 issue_code("\nG1 X{:.3f} Y{:.3f} F8640".format(keep_xpos, keep_ypos)) if not v.sidewipe_delay_zreturn: issue_code( "\nG1 Z{:.4f} F8640 ; P2PP - ZHOP - return to oroginal height" .format(v.current_position_z)) else: issue_code( "\n; G1 Z{:.4f} F8640 ; P2PP - Deferred return to Z_height". format(v.current_position_z)) resetfanspeed() v.processed_gcode.append("\nM907 X{} ; reset motor power".format( v.bigbrain3d_motorpower_normal)) issue_code("\n;-------------------------------\n", True)
def create_side_wipe(length=0): if length != 0: v.side_wipe_length = length if not v.side_wipe or v.side_wipe_length == 0: return if v.bigbrain3d_purge_enabled: create_sidewipe_bb3d(v.side_wipe_length) v.side_wipe_length = 0 elif v.blobster_purge_enabled: create_sidewipe_blobster(v.side_wipe_length) v.side_wipe_length = 0 else: issue_code(";---------------------------", True) issue_code("; P2PP SIDE WIPE: {:7.3f}mm".format(v.side_wipe_length), True) # check if the sidewipe has an additional z-hop defined, if so increase z-height with that amount if v.addzop > 0.0: issue_code( "G1 Z{} ;P2PP ZHOP SIDEWIPE".format(v.current_position_z + 1.0)) for line in v.before_sidewipe_gcode: issue_code(line) if v.retraction == 0: purgetower.retract(v.current_tool) issue_code("G1 F8640") issue_code("G1 {} Y{}".format(v.side_wipe_loc, v.sidewipe_miny)) if v.manual_filament_swap: swap.swap_pause("M25") swap.swap_unpause() delta_y = abs(v.sidewipe_maxy - v.sidewipe_miny) if v.sidewipe_maxy == v.sidewipe_miny: # no Y movement, just purge purgetower.unretract(v.current_tool) while v.side_wipe_length > 0: sweep = min(v.side_wipe_length, 50) issue_code("G1 E{:.5f} F{}".format(sweep, v.wipe_feedrate)) issue_code("G1 E-3.0000 F200") issue_code("G1 E3.0000 F200") v.side_wipe_length -= sweep else: sweep_base_speed = v.wipe_feedrate * 20 * delta_y / 150 sweep_length = 20 yrange = [v.sidewipe_maxy, v.sidewipe_miny] rangeidx = 0 movefrom = v.sidewipe_miny moveto = yrange[rangeidx] numdiffs = 20 purgetower.unretract(v.current_tool) while v.side_wipe_length > 0: sweep = min(v.side_wipe_length, sweep_length) v.side_wipe_length -= sweep_length wipe_speed = min(5000, int(sweep_base_speed / sweep)) # split this move in very short moves to allow for faster planning buffer depletion diff = (moveto - movefrom) / numdiffs for i in range(numdiffs): issue_code("G1 {} Y{:.3f} E{:.5f} F{}".format( v.side_wipe_loc, movefrom + (i + 1) * diff, sweep / numdiffs * v.sidewipe_correction, wipe_speed)) # issue_code( # "G1 {} Y{} E{:.5f} F{}\n".format(v.side_wipe_loc, moveto, sweep * v.sidewipe_correction, wipe_speed)) rangeidx += 1 movefrom = moveto moveto = yrange[rangeidx % 2] for line in v.after_sidewipe_gcode: issue_code(line) purgetower.retract(v.current_tool) issue_code("G1 F8640") issue_code(";---------------------------", True) v.side_wipe_length = 0
def purge_generate_sequence(): global last_posx, last_posy if last_posx is None: last_posx = v.purge_sequence_x if last_posy is None: last_posy = v.purge_sequence_y if not v.side_wipe_length > 0: return actual = 0 gcode.issue_code("; --------------------------------------------------", True) gcode.issue_code("; --- P2PP WIPE SEQUENCE START FOR {:5.2f}mm".format(v.side_wipe_length), True) gcode.issue_code( "; --- DELTA = {:.2f}".format(v.current_position_z - (v.purgelayer + 1) * v.layer_height), True) # # if v.previous_tool != -1: # index = v.previous_tool * 4 + v.current_tool # if v.side_wipe_length > v.wiping_info[index]: # v.side_wipe_length = v.wiping_info[index] # gcode.issue_code( # "; --- CORRECTED PURGE TO TRANSITION LENGTH {:.2f}mm\n".format(v.wiping_info[index])) # gcode.issue_code("; --------------------------------------------------\n") v.max_tower_delta = max(v.max_tower_delta, v.current_position_z - (v.purgelayer + 1) * v.layer_height) v.min_tower_delta = min(v.min_tower_delta, v.current_position_z - (v.purgelayer + 1) * v.layer_height) if last_posx and last_posy: # gcode.issue_code(";retraction {}".format(v.retraction)) if v.retraction == 0: retract(v.current_tool) gcode.issue_code("G1 X{} Y{} F8640".format(last_posx, last_posy)) if v.manual_filament_swap: swap.swap_pause("M25") # no need to unpause as the reauired Z-move is part of the remaining sequence gcode.issue_code("G1 Z{:.2f} F10800".format((v.purgelayer + 1) * v.layer_height)) unretract(v.current_tool) # p2pp_process_file wipe code while v.side_wipe_length > 0: next_command = _purge_get_nextcommand_in_sequence() last_posx = if_defined(next_command[gcode.X], last_posx) last_posy = if_defined(next_command[gcode.Y], last_posy) v.side_wipe_length -= if_defined(next_command[gcode.E], 0) actual += if_defined(next_command[gcode.E], 0) gcode.issue_command(next_command, getwipespeed()) _purge_update_sequence_index() # return to print height retract(v.current_tool) if v.retraction == 0: v.expect_retract = True gcode.issue_code( "G1 Z{:.2f} F10800\n".format(max(v.current_position_z + 0.6, (v.purgelayer + 1) * v.layer_height) + 0.6)) gcode.issue_code("; -------------------------------------", True) gcode.issue_code("; --- P2PP WIPE SEQUENCE END DONE", True) gcode.issue_code("; -------------------------------------", True) # if we extruded more we need to account for that in the total count v.side_wipe_length = 0 v.retract_x = last_posx v.retract_y = last_posy v.expect_retract = True
def parse_gcode_second_pass(): idx = 0 intower = False purge = False total_line_count = len(v.parsed_gcode) v.retraction = 0 v.last_parsed_layer = -1 v.previous_block_classification = v.parsed_gcode[0][gcode.CLASS] # include firmware purge length accounting v.total_material_extruded = v.firmwarepurge v.material_extruded_per_color[v.current_tool] = v.firmwarepurge for process_line_count in range(total_line_count): try: if process_line_count >= v.layer_end[0]: v.last_parsed_layer += 1 v.layer_end.pop(0) v.current_layer_is_skippable = v.skippable_layer[ v.last_parsed_layer] and not v.last_parsed_layer == 0 if v.current_layer_is_skippable: if v.last_parsed_layer == 0: v.cur_tower_z_delta += v.first_layer_height else: v.cur_tower_z_delta += v.layer_height except IndexError: pass g = v.parsed_gcode[idx] idx = idx + 1 # ----- MEMORY MANAGEMENT - when 100K lines are processed, remove the top of the list if idx > 100000: v.parsed_gcode = v.parsed_gcode[idx:] idx = 0 if process_line_count % 10000 == 0: gui.progress_string(50 + 50 * process_line_count // total_line_count) current_block_class = g[gcode.CLASS] # ---- FIRST SECTION HANDLES DELAYED TEMPERATURE COMMANDS ---- if current_block_class not in [ CLS_TOOL_PURGE, CLS_TOOL_START, CLS_TOOL_UNLOAD ] and v.current_temp != v.new_temp: gcode.issue_code(v.temp1_stored_command) v.temp1_stored_command = "" # BLOCK Added 27/11/2021 - PS2.4 - P3 - showinf lines between print and tower if current_block_class != v.previous_block_classification and not v.side_wipe and not v.full_purge_reduction: if v.previous_block_classification == CLS_TOOL_UNLOAD: if v.restore_move_point: v.restore_move_point = False gcode.issue_code( "G1 X{:0.3f} Y{:0.3f} F8640 ; P2PP positional alignment" .format(v.current_position_x, v.current_position_y)) # BLOCK END # ---- SECOND SECTION HANDLES COMMENTS AND NONE-MOVEMENT COMMANDS ---- if g[gcode.COMMAND] is None: if v.disable_z and g[gcode.COMMENT].endswith("END"): v.disable_z = False if v.needpurgetower and g[gcode.COMMENT].endswith("BRIM END"): v.needpurgetower = False purgetower.purge_create_layers(v.wipe_tower_info_minx, v.wipe_tower_info_miny, v.wipe_tower_xsize, v.wipe_tower_ysize) purgetower.purge_generate_brim() v.toolchange_processed = False gcode.issue_command(g) continue elif g[gcode.MOVEMENT] == 0: if g[gcode.COMMAND].startswith('T'): if v.manual_filament_swap and not ( v.side_wipe or v.full_purge_reduction or v.tower_delta) and (v.current_tool != -1): swap.swap_pause("M25") swap.swap_unpause() gcode_process_toolchange(int(g[gcode.COMMAND][1:])) if not v.debug_leaveToolCommands: gcode.move_to_comment(g, "--P2PP-- Color Change") v.toolchange_processed = (current_block_class != CLS_NORMAL) elif v.klipper and g[gcode.COMMAND] == "ACTIVATE_EXTRUDER": extruder = g[gcode.OTHER].strip() if extruder.startswith("EXTRUDER=extruder"): if len(extruder) == 17: extruder_num = 0 else: try: extruder_num = int(extruder[17:]) except (ValueError, IndexError): extruder_num = None gui.log_warning( "KLIPPER - Named extruders are not supported ({})" .format(extruder)) if extruder_num is not None: gcode_process_toolchange(extruder_num) if not v.debug_leaveToolCommands: gcode.move_to_comment(g, "--P2PP-- Color Change") v.toolchange_processed = True else: gui.log_warning( "KLIPPER - Named extruders are not supported ({})". format(extruder)) else: if current_block_class == CLS_TOOL_UNLOAD: if g[gcode.COMMAND] in ["G4", "M900", "M400"]: gcode.move_to_comment(g, "--P2PP-- tool unload") if g[gcode.COMMAND] is not None and g[ gcode.COMMAND].startswith('M'): try: command_num = int(g[gcode.COMMAND][1:]) except (ValueError, KeyError): command_num = 0 if command_num in [104, 109]: if v.process_temp: if current_block_class not in [ CLS_TOOL_PURGE, CLS_TOOL_START, CLS_TOOL_UNLOAD ]: g[gcode.COMMENT] += " Unprocessed temp " v.new_temp = gcode.get_parameter( g, gcode.S, v.current_temp) v.current_temp = v.new_temp else: v.new_temp = gcode.get_parameter( g, gcode.S, v.current_temp) if v.new_temp >= v.current_temp: g[gcode.COMMAND] = "M109" v.temp2_stored_command = gcode.create_commandstring( g) gcode.move_to_comment( g, "--P2PP-- delayed temp rise until after purge {}-->{}" .format(v.current_temp, v.new_temp)) v.current_temp = v.new_temp else: v.temp1_stored_command = gcode.create_commandstring( g) gcode.move_to_comment( g, "--P2PP-- delayed temp drop until after purge {}-->{}" .format(v.current_temp, v.new_temp)) elif command_num == 107: v.saved_fanspeed = 0 elif command_num == 106: v.saved_fanspeed = gcode.get_parameter( g, gcode.S, v.saved_fanspeed) elif command_num == 221: v.extrusion_multiplier = float( gcode.get_parameter( g, gcode.S, v.extrusion_multiplier * 100.0)) / 100.0 elif command_num == 220: gcode.move_to_comment( g, "--P2PP-- Feed Rate Adjustments are removed") elif command_num == 572: for i in range(1, v.filament_count): g[gcode.OTHER] = g[gcode.OTHER].replace( "D{}".format(i), "D0") elif not v.generate_M0 and g[gcode.COMMAND] == "M0": gcode.move_to_comment(g, "--P2PP-- remove M0 command") gcode.issue_command(g) continue classupdate = not current_block_class == v.previous_block_classification v.previous_block_classification = current_block_class # ---- AS OF HERE ONLY MOVEMENT COMMANDS ---- if g[gcode.MOVEMENT] & 1: v.previous_purge_keep_x = v.purge_keep_x v.purge_keep_x = g[gcode.X] v.current_position_x = g[gcode.X] if g[gcode.MOVEMENT] & 2: v.previous_purge_keep_y = v.purge_keep_y v.purge_keep_y = g[gcode.Y] v.current_position_y = g[gcode.Y] if g[gcode.MOVEMENT] & 4: if v.disable_z: gcode.move_to_comment(g, "-- P2PP - invalid move in delta tower") gcode.issue_command(g) continue else: v.current_position_z = g[gcode.Z] if g[gcode.MOVEMENT] & 16: v.keep_speed = g[gcode.F] # this goes for all situations: START and UNLOAD are not needed if current_block_class in [CLS_TOOL_START, CLS_TOOL_UNLOAD]: # BLOCK Added 27/11/2021 - PS2.4 - P3 - showinf lines between print and tower if not (v.side_wipe or v.full_purge_reduction): v.restore_move_point = True # BLOCK END gcode.move_to_comment(g, "--P2PP-- tool unload") gcode.issue_command(g) continue # --------------------- TOWER DELTA PROCESSING if v.tower_delta: if classupdate: if current_block_class == CLS_TOOL_PURGE: gcode.issue_command(g) entertower(v.last_parsed_layer * v.layer_height + v.first_layer_height) continue if current_block_class == CLS_EMPTY and not v.towerskipped: v.towerskipped = ( g[gcode.MOVEMENT] & gcode.INTOWER ) == gcode.INTOWER and v.current_layer_is_skippable if not v.towerskipped: gcode.issue_command(g) entertower(v.last_parsed_layer * v.layer_height + v.first_layer_height) continue if current_block_class == CLS_NORMAL: if v.towerskipped: gcode.issue_code("G1 Z{:.2f} F10810".format( v.current_position_z)) v.towerskipped = False if current_block_class == CLS_TOOL_PURGE: speed_limiter(g) if current_block_class == CLS_TOOL_PURGE: if g[gcode.F] is not None and g[ gcode.F] > v.purgetopspeed and g[gcode.E]: g[gcode.F] = v.purgetopspeed g[gcode.COMMENT] += " prugespeed topped" if v.towerskipped: gcode.move_to_comment(g, "--P2PP-- tower skipped") gcode.issue_command(g) continue # --------------------- SIDE WIPE PROCESSING elif v.side_wipe: if classupdate: if current_block_class == CLS_BRIM: v.towerskipped = True v.side_wipe_state = 0 if not v.towerskipped and (g[gcode.MOVEMENT] & 3) != 0: if (g[gcode.MOVEMENT] & gcode.INTOWER) == gcode.INTOWER: v.towerskipped = True v.side_wipe_state = 1 if (current_block_class == CLS_TOOL_PURGE) else 0 if v.towerskipped and current_block_class == CLS_NORMAL and ( g[gcode.MOVEMENT] & 3) == 3: if (v.bed_origin_x <= g[gcode.X] <= v.bed_max_x) and ( v.bed_origin_y <= g[gcode.Y] <= v.bed_max_y): v.towerskipped = False v.side_wipe_state = 0 if v.toolchange_processed and v.side_wipe_length: create_side_wipe() v.toolchange_processed = False if v.towerskipped: inc = "NO_E" if current_block_class in [ CLS_TOOL_PURGE, CLS_ENDPURGE ] or (current_block_class == CLS_EMPTY and v.side_wipe_state == 1): if g[gcode.EXTRUDE]: v.side_wipe_length += g[gcode.E] inc = "INC_E" gcode.move_to_comment( g, "--P2PP-- side wipe skipped ({})".format(inc)) gcode.issue_command(g) continue # for PS2.4 # before first extrusion prime the nozzle if not v.mechpurge_hasprimed and g[gcode.EXTRUDE]: if v.bigbrain3d_purge_enabled or v.blobster_purge_enabled: create_side_wipe(v.mechpurge_prime_blobs * v.mechpurge_blob_size) v.mechpurge_hasprimed = True # --------------------- FULL PURGE PROCESSING elif v.full_purge_reduction: if (g[gcode.MOVEMENT] & 3) > 0: # if there is a movement intower = (g[gcode.MOVEMENT] & gcode.INTOWER) == gcode.INTOWER if classupdate: if current_block_class == CLS_NORMAL: v.towerskipped = False purge = False if current_block_class == CLS_TOOL_PURGE: purge = True if not v.towerskipped and current_block_class == CLS_EMPTY and v.current_layer_is_skippable: v.towerskipped = (g[gcode.MOVEMENT] & gcode.INTOWER) == gcode.INTOWER if v.towerskipped or current_block_class in [ CLS_BRIM, CLS_ENDGRID ]: gcode.move_to_comment( g, "--P2PP-- full purge skipped [Excluded]") gcode.issue_command(g) continue if current_block_class in [ CLS_TOOL_PURGE, CLS_ENDPURGE, CLS_EMPTY ]: if purge and g[gcode.EXTRUDE]: v.side_wipe_length += g[gcode.E] gcode.move_to_comment( g, "--P2PP-- full purge skipped [Included]") else: gcode.move_to_comment( g, "--P2PP-- full purge skipped [Excluded]") gcode.issue_command(g) continue if v.toolchange_processed and current_block_class == CLS_NORMAL: if v.side_wipe_length and ( g[gcode.MOVEMENT] & 3) == 3 and not (g[gcode.MOVEMENT] & gcode.INTOWER) == gcode.INTOWER: purgetower.purge_generate_sequence() v.toolchange_processed = False # do not issue code here as the next code might require further processing such as retractioncorrection else: gcode.move_to_comment(g, "--P2PP-- full purge skipped") gcode.issue_command(g) continue if v.expect_retract and (g[gcode.MOVEMENT] & 3): v.expect_retract = False if v.retraction >= 0 and g[gcode.RETRACT]: purgetower.retract(v.current_tool) if v.retract_move and g[gcode.RETRACT]: g[gcode.X] = v.retract_x g[gcode.Y] = v.retract_y g[gcode.MOVEMENT] |= 3 v.retract_move = False if v.retraction <= -v.retract_length[v.current_tool]: gcode.move_to_comment(g, "--P2PP-- Double Retract") else: v.retraction += g[gcode.E] if intower: gcode.move_to_comment( g, "--P2PP-- full purge skipped [Excluded]") gcode.issue_command(g) continue # --------------------- NO TOWER PROCESSING else: if current_block_class in [CLS_TOOL_PURGE, CLS_EMPTY ] and g[gcode.E]: if v.acc_ping_left <= 0: pings.check_accessorymode_first() v.enterpurge = True # TOEE - Added to limit the speed of the extrusions during purge to defined WIPEFEEDRATE if current_block_class == CLS_TOOL_PURGE: speed_limiter(g) if v.toolchange_processed: if v.temp2_stored_command != "": wait_location = calculate_temp_wait_position() gcode.issue_code( "G1 X{:.3f} Y{:.3f} F8640; temp wait position\n". format(wait_location[0], wait_location[0])) gcode.issue_code(v.temp2_stored_command) v.temp2_stored_command = "" gcode.issue_code("G1 F8640 ; correct speed") gcode.issue_command(g) if v.wipe_remove_sparse_layers: gcode.issue_code( "G1 X{} Y{} F8640 ;P2PP Position XY to avoid tower crash" .format(v.current_position_x, v.current_position_y)) v.z_correction = "G1 Z{} F10800 ;P2PP correct z-moves".format( v.current_position_z) v.toolchange_processed = False continue if current_block_class == CLS_TOOL_PURGE: if g[gcode.F] is not None and g[ gcode.F] > v.purgetopspeed and g[gcode.E]: g[gcode.F] = v.purgetopspeed g[gcode.COMMENT] += " prugespeed topped" # --------------------- GLOBAL PROCEDDING if g[gcode.UNRETRACT]: g[gcode.E] = min(-v.retraction, g[gcode.E]) v.retraction += g[gcode.E] elif g[gcode.RETRACT]: v.retraction += g[gcode.E] elif (g[gcode.MOVEMENT] & 3) and g[gcode.EXTRUDE]: if v.z_correction is not None or v.retraction < -0.01: if current_block_class != CLS_TOOL_START: gcode.issue_code(";P2PP START Z/E alignment processing") if v.z_correction is not None: gcode.issue_code(v.z_correction) v.z_correction = None if v.retraction < -0.01: purgetower.unretract(v.retraction, -1, ";--- P2PP --- fixup retracts") gcode.issue_code(";P2PP END Z/E alignment processing") else: gcode.issue_command(g) gcode.issue_code(";P2PP START Z/E alignment processing") if v.z_correction is not None: gcode.issue_code(v.z_correction) v.z_correction = None if v.retraction < -0.01: purgetower.unretract(v.retraction, -1, ";--- P2PP --- fixup retracts") g = gcode.create_command( ";P2PP END Z/E alignment processing") # --------------------- PING PROCESSING if v.accessory_mode and g[gcode.EXTRUDE]: if not pings.check_accessorymode_second(g[gcode.E]): gcode.issue_command(g) else: gcode.issue_command(g) if g[gcode.EXTRUDE] and v.side_wipe_length == 0: pings.check_connected_ping() v.previous_position_x = v.current_position_x v.previous_position_y = v.current_position_y # LAST STEP IS ADDING AN EXTRA TOOL UNLOAD TO DETERMINE THE LENGTH OF THE LAST SPLICE gcode_process_toolchange(-1)