Esempio n. 1
0
def create_tower_gcode():
    # generate a purge tower alternative
    _x = v.wipe_tower_info['minx']
    _y = v.wipe_tower_info['miny']
    _w = v.wipe_tower_info['maxx'] - v.wipe_tower_info['minx']
    _h = v.wipe_tower_info['maxy'] - v.wipe_tower_info['miny']

    purgetower.purge_create_layers(_x, _y, _w, _h)
    # generate og items for the new purge tower
    gui.create_logitem(
        " Purge Tower :Loc X{:.2f} Y{:.2f}  W{:.2f} H{:.2f}".format(_x, _y, _w, _h))
    gui.create_logitem(
        " Layer Length Solid={:.2f}mm   Sparse={:.2f}mm".format(purgetower.sequence_length_solid,
                                                                purgetower.sequence_length_empty))
Esempio n. 2
0
def find_alternative_tower():
    v.wipe_tower_info_maxx = v.wipe_tower_posx
    v.wipe_tower_info_minx = v.wipe_tower_posx
    v.wipe_tower_info_maxy = v.wipe_tower_posy
    v.wipe_tower_info_miny = v.wipe_tower_posy

    if v.wipe_tower_posx and v.wipe_tower_posy:
        state = 0
        for i in range(len(v.input_gcode)):
            line = v.input_gcode[i]
            if line.startswith(";"):
                if line.startswith(";TYPE:Wipe tower"):
                    state = 1
                    continue
                if state == 1 and line.startswith(";TYPE"):
                    check_tower_update(False)
                    purgetower.purge_create_layers(v.wipe_tower_info_minx,
                                                   v.wipe_tower_info_miny,
                                                   v.wipe_tower_xsize,
                                                   v.wipe_tower_ysize)
                    gui.create_logitem(
                        "Tower detected from ({}, {}) to ({}, {})".format(
                            v.wipe_tower_info_minx, v.wipe_tower_info_miny,
                            v.wipe_tower_info_maxx, v.wipe_tower_info_maxy))
                    break
            if state == 1:
                gc = gcode.create_command(line)
                if gc[gcode.EXTRUDE]:
                    if gc[gcode.X] is not None:
                        v.wipe_tower_info_maxx = max(
                            v.wipe_tower_info_maxx,
                            gc[gcode.X] + 6 * v.extrusion_width)
                        v.wipe_tower_info_minx = min(
                            v.wipe_tower_info_minx,
                            gc[gcode.X] - 6 * v.extrusion_width)
                    if gc[gcode.Y] is not None:
                        v.wipe_tower_info_maxy = max(
                            v.wipe_tower_info_maxy,
                            gc[gcode.Y] + 6 * v.extrusion_width)
                        v.wipe_tower_info_miny = min(
                            v.wipe_tower_info_miny,
                            gc[gcode.Y] - 6 * v.extrusion_width)
Esempio n. 3
0
def gcode_parseline(index):
    g = v.parsedgcode[index]
    block_class = v.gcodeclass[index]
    previous_block_class = v.gcodeclass[max(0, index - 1)]
    classupdate = block_class != previous_block_class

    if g.Command == 'T':
        gcode_process_toolchange(int(g.Command_value),
                                 v.total_material_extruded, g.Layer)
        g.move_to_comment("Color Change")
        g.issue_command()
        return

    if g.fullcommand in [
            "M104", "M109", "M140", "M190", "M73", "M84", "M201", "M204"
    ]:
        g.issue_command()
        return

    # fan speed command

    if g.fullcommand == "M107":
        g.issue_command()
        v.saved_fanspeed = 0
        return

    if g.fullcommand == "M106":
        g.issue_command()
        v.saved_fanspeed = g.get_parameter("S", v.saved_fanspeed)
        return

    if block_class == CLS_TOOL_UNLOAD and g.fullcommand in [
            "M900"
    ] and g.get_parameter("K", 0) == 0:
        g.move_to_comment("tool unload")

    if g.fullcommand in ["M220"]:
        g.move_to_comment("Flow Rate Adjustments are removed")
        g.issue_command()
        return

    if g.fullcommand == "M221":
        v.extrusion_multiplier = float(
            g.get_parameter("S", v.extrusion_multiplier * 100)) / 100
        g.issue_command()
        return

    if g.is_movement_command():
        if g.has_X():
            v.previous_purge_keep_x = v.purge_keep_x
            v.purge_keep_x = g.X
        if g.has_Y():
            v.previous_purge_keep_y = v.purge_keep_y
            v.purge_keep_y = g.Y

    ## ALL SITUATIONS
    ##############################################
    if block_class in [CLS_TOOL_START, CLS_TOOL_UNLOAD]:

        if g.fullcommand == "G4":
            g.move_to_comment("tool unload")
        if g.is_movement_command():
            if g.has_Z():
                g.remove_parameter("X")
                g.remove_parameter("Y")
                g.remove_parameter("F")
                g.remove_parameter("E")
            else:
                g.move_to_comment("tool unload")

        g.issue_command()
        return

    if block_class == CLS_TOOL_PURGE and not (v.side_wipe
                                              or v.full_purge_reduction):
        if g.is_movement_command():
            _x = g.get_parameter("X", v.current_position_x)
            _y = g.get_parameter("Y", v.current_position_y)
            if not (coordinate_in_tower(_x, _y)
                    and coordinate_in_tower(v.purge_keep_x, v.purge_keep_y)):
                g.remove_parameter("E")

    if not v.side_wipe:
        if g.has_X():
            if v.wipe_tower_info['minx'] <= g.X <= v.wipe_tower_info['maxx']:
                v.keep_x = g.X
        if g.has_Y():
            if v.wipe_tower_info['miny'] <= g.Y <= v.wipe_tower_info['maxy']:
                v.keep_y = g.Y
    elif not x_on_bed(g.X):
        g.remove_parameter("X")

    ## SIDEWIPE / FULLPURGEREDUCTION / TOWER DELTA
    ###############################################
    if v.pathprocessing:

        if block_class == CLS_TONORMAL:

            if not g.is_comment():
                g.move_to_comment("post block processing")
            g.issue_command()
            return

        if flagset(v.parsecomment[index], SPEC_INTOWER):
            if coordinate_in_tower(g.X, g.Y):
                g.remove_parameter("X")
                g.remove_parameter("Y")

        # sepcific for FULL_PURGE_REDUCTION
        if v.full_purge_reduction:

            # get information about the purge tower dimensions
            if block_class == CLS_BRIM and not (g.has_X() and g.has_Y()):
                if g.has_X():
                    purgetower.purge_width = min(
                        purgetower.purge_width,
                        abs(g.X - v.previous_position_x))
                if g.has_Y():
                    purgetower.purge_height = min(
                        purgetower.purge_height,
                        abs(g.Y - v.previous_position_y))

            if block_class == CLS_BRIM_END:
                # generate a purge tower alternative

                _x = v.wipe_tower_info['minx'] + 4 * v.extrusion_width
                _y = v.wipe_tower_info['miny'] + 4 * v.extrusion_width
                _w = v.wipe_tower_info['maxx'] - v.wipe_tower_info[
                    'minx'] - 8 * v.extrusion_width
                _h = v.wipe_tower_info['maxy'] - v.wipe_tower_info[
                    'miny'] - 8 * v.extrusion_width

                purgetower.purge_create_layers(_x, _y, _w, _h)
                # generate og items for the new purge tower
                gui.create_logitem(
                    " Purge Tower :Loc X{:.2f} Y{:.2f}  W{:.2f} H{:.2f}".
                    format(_x, _y, _w, _h))
                gui.create_logitem(
                    " Layer Length Solid={:.2f}mm   Sparse={:.2f}mm".format(
                        purgetower.sequence_length_solid,
                        purgetower.sequence_length_empty))
                # issue the new purge tower
                for i in range(len(purgetower.brimlayer)):
                    purgetower.brimlayer[i].issue_command()
                    if i == 1 and v.retraction:
                        purgetower.unretract(v.current_tool)
                # set the flag to update the post-session retraction move section
                v.retract_move = True
                v.retract_x = purgetower.last_brim_x
                v.retract_y = purgetower.last_brim_y
                # correct the amount of extrusion for the brim

        # sepcific for SIDEWIPE
        if v.side_wipe:

            # side wipe does not need a brim
            if block_class == CLS_BRIM:
                if not g.is_comment():
                    g.move_to_comment("side wipe - removed")
                g.issue_command()
                return

        # entering the purge tower with a delta
        ########################################
        if v.tower_delta:

            if classupdate:

                if block_class == CLS_TOOL_PURGE:
                    g.issue_command()
                    gcode.issue_code("G1 X{} Y{} ;\n".format(
                        v.keep_x, v.keep_y))
                    v.current_position_x = v.keep_x
                    v.current_position_x = v.keep_y
                    entertower(g.Layer * v.layer_height)
                    return

        # going into an empty grid -- check if it should be consolidated
        ################################################################
        if classupdate and block_class in [CLS_FIRST_EMPTY, CLS_EMPTY]:
            if v.skippable_layer[v.layernumber[index]]:
                v.towerskipped = True
                # print("Skipped: {:.3f} now at delta {:.3f}".format(v.current_position_z- v.retract_lift[v.current_tool]+v.layer_height,v.cur_tower_z_delta+v.layer_height))
                remove_previous_move_in_tower()
                if v.tower_delta and "CP EMPTY GRID START" in g.Comment:
                    v.cur_tower_z_delta += v.layer_height
                    gcode.issue_code(
                        ";-------------------------------------\n")
                    gcode.issue_code(
                        ";  GRID SKIP --TOWER DELTA {:6.2f}mm\n".format(
                            v.cur_tower_z_delta))
                    gcode.issue_code(
                        ";-------------------------------------\n")

        # changing from EMPTY to NORMAL
        ###############################
        if (previous_block_class == CLS_ENDGRID) and (block_class
                                                      == CLS_NORMAL):
            v.towerskipped = False

        if v.towerskipped:
            if not g.is_comment():
                g.move_to_comment("tower skipped")
            g.issue_command()
            return
    else:
        if classupdate and block_class in [CLS_TOOL_PURGE, CLS_EMPTY]:
            if v.acc_ping_left <= 0:
                pings.check_accessorymode_first()
            v.enterpurge = True

        if v.enterpurge and g.is_movement_command():
            v.enterpurge = False
            if g.has_X():
                _x = v.previous_purge_keep_x
            else:
                _x = v.purge_keep_x
            if g.has_Y():
                _y = v.previous_purge_keep_y
            else:
                _y = v.purge_keep_y

            if not coordinate_in_tower(_x, _y):
                _x = v.purge_keep_x
                _y = v.purge_keep_y

            gcode.issue_code(
                "G1 X{:.3f} Y{:.3f}; P2PP Inserted to realign\n".format(
                    v.purge_keep_x, v.purge_keep_y))
            v.current_position_x = _x
            v.current_position_x = _y

            g.remove_parameter("E")
            if g.get_parameter("X") == _x:
                g.remove_parameter("X")
            if len(g.Parameters) == 0:
                g.move_to_comment("-useless command-")

    if v.tower_delta:
        if g.has_E() and block_class in [CLS_TOOL_UNLOAD, CLS_TOOL_PURGE]:
            if not inrange(g.X, v.wipe_tower_info['minx'],
                           v.wipe_tower_info['maxx']):
                g.remove_parameter("E")
            if not inrange(g.Y, v.wipe_tower_info['miny'],
                           v.wipe_tower_info['maxy']):
                g.remove_parameter("E")

    # process movement commands
    ###########################

    if not g.has_E():
        g.E = 0

    if v.full_purge_reduction and block_class == CLS_NORMAL and classupdate:
        purgetower.purge_generate_sequence()

    if g.is_movement_command():

        if v.expect_retract and g.has_X() or g.has_Y():
            if not v.retraction < 0:
                if not g.has_E and g.E < 0:
                    purgetower.retract(v.current_tool)
            v.expect_retract = False

        if v.retract_move and g.is_retract_command():
            # This is going to break stuff, G10 cannot take X and Y, what to do?
            if v.retract_x:
                g.update_parameter("X", v.retract_x)
            else:
                g.remove_parameter("X")
            if v.retract_y:
                g.update_parameter("Y", v.retract_y)
            else:
                g.remove_parameter("Y")
            v.retract_move = False

        v.current_position_x = g.get_parameter("X", v.current_position_x)
        v.current_position_y = g.get_parameter("Y", v.current_position_y)
        v.current_position_z = g.get_parameter("Z", v.current_position_z)

        if block_class == CLS_BRIM and v.full_purge_reduction:
            g.move_to_comment("replaced by P2PP brim code")
            g.remove_parameter("E")

    if v.side_wipe or v.full_purge_reduction:
        if block_class in [
                CLS_TOOL_PURGE, CLS_ENDPURGE, CLS_EMPTY, CLS_FIRST_EMPTY
        ]:
            if v.skippable_layer[g.Layer]:
                g.move_to_comment("skipped purge")
            else:
                v.side_wipe_length += g.E
                g.move_to_comment("side wipe/full purge")

    if v.side_wipe and block_class == CLS_NORMAL and classupdate:
        if v.bigbrain3d_purge_enabled:
            create_sidewipe_BigBrain3D()
        else:
            create_side_wipe()

    # check here issue with unretract
    #################################

    # g.Comment = " ; - {}".format(v.total_material_extruded)

    if g.is_retract_command():
        if g.has_E():
            v.retraction += g.E
        else:
            v.retraction -= 1

    if g.is_unretract_command():
        if g.has_E():
            v.retraction = min(0, v.retraction + g.E)
        else:
            v.retraction = 0

    if (g.has_X() or g.has_Y()) and (g.has_E()
                                     and g.E > 0) and v.retraction < 0 and abs(
                                         v.retraction) > 0.01:
        gcode.issue_code(";fixup retracts\n")
        purgetower.unretract(v.current_tool)
        # v.retracted = False

    g.issue_command()

    ### PING PROCESSING
    ###################

    if v.accessory_mode:
        pings.check_accessorymode_second(g.E)

    if (g.has_E() and g.E > 0) 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
Esempio n. 4
0
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)
Esempio n. 5
0
def process_gcode():
    gui.comment("Processing " + v.filename)
    line_count = len(v.rawfile)
    line_idx = 0
    for line in v.rawfile:
        line_idx += 1
        gui.setprogress(int(50 * line_idx / line_count))

        # skip fully empty lines
        if len(line) == 0:
            continue

        # parse comments
        if line.startswith(";"):
            line = parameters.parse_comment(line)

        tmp = gcode.GCodeCommand(line)

        # we calculate the purge for tower position
        # afterwards this code is removed
        #########################################################
        if v.mode == parameters.MODE_PURGE:
            if tmp.E:
                v.purge_minx = min(v.purge_minx, tmp.get_parameter("X", 9999))
                v.purge_maxx = max(v.purge_maxx, tmp.get_parameter("X", -9999))
                v.purge_miny = min(v.purge_miny, tmp.get_parameter("Y", 9999))
                v.purge_maxy = max(v.purge_maxy, tmp.get_parameter("Y", -9999))

            if tmp.is_comment() and tmp.comment.startswith(' process'):
                v.gcodes.append(tmp)
        else:
            v.gcodes.append(tmp)

        toolchange = tmp.is_toolchange()
        if toolchange in [0, 1, 2, 3]:
            # keep track of the tools used
            if not v.toolsused[toolchange]:
                if not v.filament_type[toolchange]:
                    error(
                        "TOOL_{} setting command missing - output file cannot be created"
                        .format(toolchange))
            v.toolsused[toolchange] = True

            # calculate the purge
            if not (v.parse_curtool == -1):
                v.layer_toolchange_count[-1] += 1
                if v.filament_type[toolchange] and v.filament_type[
                        v.parse_curtool] and not (v.parse_curtool
                                                  == toolchange):
                    v.layer_purge_volume[-1] += purgetower.calc_purge_length(
                        v.parse_curtool, toolchange)
                    v.parse_prevtool = v.parse_curtool
                    v.parse_curtool = toolchange
            else:
                v.parse_curtool = v.parse_prevtool = toolchange

    comment("filament Info: " + v.filament_type.__str__())
    comment("Tool unload info: " + v.unloadinfo.__str__())
    comment("Tool load info: " + v.loadinfo.__str__())
    comment("Algorithms:" + v.algorithm.__str__())
    comment("Maximum purge needed per layer: {}mm".format(
        max(v.layer_purge_volume)))
    comment("Autotower function active: {}".format(v.autotower))
    if v.autotower:
        autotower.init_autotower()
        _x = 0.0
        _y = 0.0
        for g in v.gcodes:

            if g.is_movement_command():
                _ux = g.get_parameter("X", _x)
                _uy = g.get_parameter("Y", _y)
                _ue = g.get_parameter("E", 0)

                if _ue > 0:
                    autotower.filament_mark(_x, _y, _ux, _uy)
                _x = _ux
                _y = _uy

        autotower.calculate_purgevolume()
        tower_fits = False
        while not tower_fits:
            purgetower.purge_create_layers(
                autotower.purge_minx - 1, autotower.purge_miny - 1,
                autotower.purge_maxx - autotower.purge_minx + 2,
                autotower.purge_maxy - autotower.purge_miny + 2)
            tower_fits = purgetower.simulate_tower(
                purgetower.sequence_length_solid,
                purgetower.sequence_length_empty,
                purgetower.sequence_length_fill, 5)
            if not tower_fits:
                if not autotower.tower_expand():
                    error("COULD NOT GENERATE SUITABLE TOWER")
                    tower_fits = True

        v.purge_minx = autotower.purge_minx
        v.purge_miny = autotower.purge_miny
        v.purge_maxx = autotower.purge_maxx
        v.purge_maxy = autotower.purge_maxy

    else:
        expand = 0
        tower_fits = False
        while not tower_fits:
            purgetower.purge_create_layers(v.purge_minx - 1, v.purge_miny - 1,
                                           v.purge_maxx - v.purge_minx + 2,
                                           v.purge_maxy - v.purge_miny + 2)
            tower_fits = purgetower.simulate_tower(
                purgetower.sequence_length_solid,
                purgetower.sequence_length_empty,
                purgetower.sequence_length_fill, 5)
            if not tower_fits:
                purgetower.tower_auto_expand(10)
                expand += 10

        if expand > 0:
            warning("Tower expanded by {}mm".format(expand))

    comment('Calculated purge volume : {:.3f},{:.3f} -> {:.3f},{:.3f}'.format(
        v.purge_minx, v.purge_miny, v.purge_maxx, v.purge_maxy))

    line_idx = 0
    line_count = len(v.gcodes)
    layer = -1
    for g in v.gcodes:
        if g.layer != layer:
            layer = g.layer
            purgetower.checkfill(g.layer, v.maxtowerdelta / v.layer_height)

        line_idx += 1
        gui.setprogress(50 + int(50 * line_idx / line_count))
        if g.command in ["M220"]:
            g.move_to_comment("IGNORED COMMAND")
            g.issue_command()
            continue  # no further mcf required

        if g.command == "M221":
            v.extrusion_multiplier = g.get_parameter(
                "S", v.extrusion_multiplier * 100) / 100
            g.issue_command()
            continue  # no further mcf required

        if g.command in ["T0", "T1", "T2", "T3"]:
            gcode.GCodeCommand(";---- {} TOOLCHANGE -----".format(
                g.command)).issue_command()
            process_tool_change(g)
            g.issue_command()
            continue  # no further mcf required

        if g.command in [
                "M104", "M106", "M109", "M140", "M190", "M73", "M900", "M84"
        ]:
            g.issue_command()
            continue  # no further mcf required

        if g.is_movement_command():
            v.current_position_x = g.get_parameter("X", v.current_position_x)
            v.current_position_y = g.get_parameter("Y", v.current_position_y)
            v.current_position_z = g.get_parameter("Z", v.current_position_z)
            if purgetower.moveintower():
                error("MODEL COLLIDES WITH TOWER.")
        g.issue_command()

    process_tool_change(None)

    if v.maxdelta > 1 or v.mindelta < -1:
        warning(
            "Tower hight deviates {:.2f}mm above and {:.2f}mm below print level"
            .format(-v.mindelta, v.maxdelta))
        warning(
            "Make sure to keep enough distance between tower and object to avoid collisions"
        )
        warning(
            "If the tower grows over the print height, consider increasing the prime pillar width in S3D"
        )

    gui.completed()