Example #1
0
def purge_create_layers(x, y, w, h):
    global solidlayer, emptylayer, filllayer

    solidlayer = []
    emptylayer = []
    filllayer = []

    ew = v.extrusion_width

    if ew == 0:
        ew = 0.45
        gui.log_warning("Extrusion Width of 0 detected, using default 0.45mm")

    w = int(w / ew) * ew
    h = int(h / ew) * ew

    solidlayer.append(gcode.create_command(";---- SOLID WIPE -------"))
    generate_rectangle(solidlayer, x, y, w, h)

    emptylayer.append(gcode.create_command(";---- EMPTY WIPE -------"))
    generate_rectangle(emptylayer, x, y, w, h)

    filllayer.append(gcode.create_command(";---- FILL LAYER -------"))
    generate_rectangle(filllayer, x, y, w, h)

    _purge_create_sequence(solidlayer, "G1 X{:.3f} Y{:.3f} F%SPEED%", x, y, w, h, ew)
    _purge_create_sequence(emptylayer, "G1 Y{:.3f} X{:.3f} F%SPEED%", y, x, h, w, 2)
    _purge_create_sequence(filllayer, "G1 Y{:.3f} X{:.3f} F%SPEED%", y, x, h, w, 15)

    _purge_generate_tower_brim(x, y, w, h)

    _purge_calculate_sequences_length()

    v.purge_sequence_x = x
    v.purge_sequence_y = y
Example #2
0
def _purge_create_sequence(code, pformat, x, y, w, h, step1):
    generate_front = False

    ew = v.extrusion_width

    cw = w - 4 * ew

    start1 = x + 2 * ew + (cw % step1) / 2
    end1 = x + 2 * ew + cw - (cw % step1) / 2

    start2 = y + 2 * ew - ew * 0.15
    end2 = y + h - 2 * ew + ew * 0.15

    code.append(gcode.create_command(pformat.format(start1, start2)))
    pformat = (pformat + " E{:.4f}")

    while start1 < end1:
        if generate_front:
            code.append(gcode.create_command(pformat.format(start1, start2, calculate_purge(step1))))
        else:
            generate_front = True

        code.append(gcode.create_command(pformat.format(start1, end2, calculate_purge(end2 - start2))))
        start1 += step1

        if start1 < end1:
            code.append(gcode.create_command(pformat.format(start1, end2, calculate_purge(step1))))
            code.append(gcode.create_command(pformat.format(start1, start2, calculate_purge(end2 - start2))))
        start1 += step1
Example #3
0
def generate_rectangle(result, x, y, w, h):
    ew = v.extrusion_width
    x2 = x + w
    y2 = y + h
    result.append(gcode.create_command("G1 X{:.3f} Y{:.3f} F8640".format(x, y)))
    result.append(gcode.create_command("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(x2, y, calculate_purge(w))))
    result.append(gcode.create_command("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(x2, y2, calculate_purge(h))))
    result.append(gcode.create_command("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(x, y2, calculate_purge(w))))
    result.append(gcode.create_command("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(x, y, calculate_purge(h))))

    result.append(gcode.create_command("G1 X{:.3f} Y{:.3f} F8640".format(x + ew, y + ew)))
    result.append(gcode.create_command("G1 X{:.3f} Y{:.3f} E{:.4f}".format(x2 - ew, y + ew, calculate_purge(w - 2 * ew))))
    result.append(
        gcode.create_command("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(x2 - ew, y2 - ew, calculate_purge(h - 2 * ew))))
    result.append(
        gcode.create_command("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(x + ew, y2 - ew, calculate_purge(w - 2 * ew))))
    result.append(
        gcode.create_command("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(x + ew, y + ew, calculate_purge(h - 2 * ew))))
Example #4
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)
Example #5
0
def _purge_generate_tower_brim(x, y, w, h):
    global brimlayer, last_brim_x, last_brim_y

    ew = v.extrusion_width
    brimlayer = []
    y -= ew
    w += ew
    h += 2 * ew

    brimlayer.append(gcode.create_command("; P2PP - BRIM CODE"))
    brimlayer.append(gcode.create_command("G1 X{:.3f} Y{:.3f} F8640".format(x, y)))
    brimlayer.append(gcode.create_command("G1 Z{:.3f}".format(v.layer_height)))

    for i in range(4):
        brimlayer.append(
            gcode.create_command("G1 X{:.3f} Y{:.3f}  E{:.4f} F{}".format(x + w, y, calculate_purge(w), 1200)))
        brimlayer.append(gcode.create_command("G1 X{:.3f} Y{:.3f}  E{:.4f}".format(x + w, y + h, calculate_purge(h))))
        x -= ew
        w += 2 * ew
        brimlayer.append(gcode.create_command("G1 X{:.3f} Y{:.3f}  E{:.4f}".format(x, y + h, calculate_purge(w))))
        y -= ew
        h += 2 * ew
        brimlayer.append(gcode.create_command("G1 X{:.3f} Y{:.3f}  E{:.4f}".format(x, y, calculate_purge(h))))
Example #6
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)
Example #7
0
def parse_gcode_first_pass():
    v.layer_toolchange_counter = 0
    v.layer_emptygrid_counter = 0

    v.block_classification = CLS_NORMAL
    v.previous_block_classification = CLS_NORMAL
    total_line_count = len(v.input_gcode)

    flh = int(v.first_layer_height * 100)
    olh = int(v.layer_height * 100)

    backpass_line = -1
    jndex = 0

    find_alternative_tower()

    for index in range(total_line_count):

        v.previous_block_classification = v.block_classification

        # memory management, reduce size of data structures when data is processed
        line = v.input_gcode[jndex]
        jndex += 1
        if jndex == 100000:
            gui.progress_string(4 + 46 * index // total_line_count)
            v.input_gcode = v.input_gcode[jndex:]
            jndex = 0

        # actual line processing, starting with comments processing
        if line.startswith(';'):

            is_comment = True

            # extract thumbnail from gcode file
            if not v.p3_processing_thumbnail_end:
                if line.startswith("; thumbnail"):
                    v.p3_thumbnail = not v.p3_thumbnail
                    if not v.p3_thumbnail:
                        v.p3_processing_thumbnail_end = True
                        v.p3_thumbnail_data = v.p3_thumbnail_data.replace(
                            "; ", "")
                elif v.p3_thumbnail:
                    v.p3_thumbnail_data += line

            # extract the main gcode building blocks
            if line.startswith(
                    '; CP'
            ):  # code block assignment, based on Prusa Slicer injected CP comments
                update_class(hash(line[5:]))

            # determine the layerheight at which we're printing
            elif line.startswith(
                    ';LAYERHEIGHT'
            ):  # Layer instructions, used to calculate the layer number
                fields = line.split(' ')
                try:
                    lv = float(fields[1])
                    lv = int((lv + 0.001) * 100) - flh
                    if lv % olh == 0:
                        process_layer(int(lv / olh), index)
                except (ValueError, IndexError):
                    pass

        else:

            is_comment = False

            try:
                if line[0] == 'T':
                    if v.set_tool == -1:  # ignore the first tool setting for purging
                        v.block_classification = CLS_NORMAL
                    else:
                        v.block_classification = CLS_TOOL_PURGE
                    cur_tool = int(line[1])
                    v.set_tool = cur_tool
            except (TypeError, ValueError):
                gui.log_warning("Unknown T-command: {}".format(line))
            except IndexError:  # in case there is an empty line there will be no line[0]
                pass

        code = gcode.create_command(line, is_comment, v.block_classification)
        v.parsed_gcode.append(code)

        if v.block_classification != v.previous_block_classification:

            if v.block_classification in [
                    CLS_TOOL_START, CLS_TOOL_UNLOAD, CLS_EMPTY, CLS_BRIM
            ]:
                for idx in range(backpass_line, len(v.parsed_gcode)):
                    v.parsed_gcode[idx][gcode.CLASS] = v.block_classification

        # determine tower size - old method
        if v.tower_measure:
            code[gcode.MOVEMENT] += gcode.INTOWER
            if code[gcode.X]:
                v.wipe_tower_info_minx = min(
                    v.wipe_tower_info_minx,
                    code[gcode.X] - 2 * v.extrusion_width)
                v.wipe_tower_info_maxx = max(
                    v.wipe_tower_info_maxx,
                    code[gcode.X] + 2 * v.extrusion_width)
            if code[gcode.Y]:
                v.wipe_tower_info_miny = min(
                    v.wipe_tower_info_miny,
                    code[gcode.Y] - 4 * 2 * v.extrusion_width)
                v.wipe_tower_info_maxy = max(
                    v.wipe_tower_info_maxy,
                    code[gcode.Y] + 4 * 2 * v.extrusion_width)

        if v.bedtrace:
            if (code[gcode.MOVEMENT] &
                (gcode.X + gcode.Y)) and v.bed is not None:
                if code[gcode.EXTRUDE]:
                    v.bed.line(code[gcode.X], code[gcode.Y])
                else:
                    v.bed.position(code[gcode.X], code[gcode.Y])

        # determine block separators by looking at the last full XY positioning move
        if (code[gcode.MOVEMENT] & 3) == 3:
            if (code[gcode.MOVEMENT] & 12) == 0:
                backpass_line = len(v.parsed_gcode) - 1

            # add
            if v.side_wipe_towerdefined:
                if ((v.wipe_tower_info_minx <= code[gcode.X] <=
                     v.wipe_tower_info_maxx)
                        and (v.wipe_tower_info_miny <= code[gcode.Y] <=
                             v.wipe_tower_info_maxy)):
                    code[gcode.MOVEMENT] += gcode.INTOWER

            if v.block_classification in [CLS_ENDGRID, CLS_ENDPURGE]:
                if not (code[gcode.MOVEMENT] & gcode.INTOWER):
                    v.parsed_gcode[-1][gcode.CLASS] = CLS_NORMAL
                    v.block_classification = CLS_NORMAL

        if v.block_classification == CLS_BRIM_END:
            v.block_classification = CLS_NORMAL

    v.input_gcode = None