Exemplo n.º 1
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.GCodeCommand(pformat.format(start1, start2)))
    pformat = (pformat + " E{:.4f}")

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

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

        if start1 < end1:
            code.append(gcode.GCodeCommand(pformat.format(start1, end2, calculate_purge(step1))))
            code.append(gcode.GCodeCommand(pformat.format(start1, start2, calculate_purge(end2 - start2))))
        start1 += step1
Exemplo n.º 2
0
def generate_rectangle(result, x, y, w, h):
    x2 = x + w
    y2 = y + h
    result.append(gcode.GCodeCommand("G1 X{:.3f} Y{:.3f}".format(x, y)))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f}".format(
            x2, y, calculate_purge(w))))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f}".format(
            x2, y2, calculate_purge(h))))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f}".format(
            x, y2, calculate_purge(w))))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f}".format(
            x, y, calculate_purge(h))))

    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f}".format(x + ew, y + ew)))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f}".format(
            x2 - ew, y + ew, calculate_purge(w - 2 * ew))))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f}".format(
            x2 - ew, y2 - ew, calculate_purge(h - 2 * ew))))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f}".format(
            x + ew, y2 - ew, calculate_purge(w - 2 * ew))))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f}".format(
            x + ew, y + ew, calculate_purge(h - 2 * ew))))
Exemplo n.º 3
0
def purge_create_layers(x, y, w, h):
    global solidlayer, emptylayer, filllayer

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

    ew = v.extrusion_width

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

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

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

    filllayer.append(gcode.GCodeCommand(";---- 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
Exemplo n.º 4
0
def generate_rectangle(result, x, y, w, h):
    ew = v.extrusion_width
    x2 = x + w
    y2 = y + h
    result.append(gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} F8640".format(x, y)))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(
            x2, y, calculate_purge(w))))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(
            x2, y2, calculate_purge(h))))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(
            x, y2, calculate_purge(w))))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(
            x, y, calculate_purge(h))))

    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} F8640".format(x + ew, y + ew)))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f}".format(
            x2 - ew, y + ew, calculate_purge(w - 2 * ew))))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(
            x2 - ew, y2 - ew, calculate_purge(h - 2 * ew))))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(
            x + ew, y2 - ew, calculate_purge(w - 2 * ew))))
    result.append(
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f} F%SPEED%".format(
            x + ew, y + ew, calculate_purge(h - 2 * ew))))
Exemplo n.º 5
0
def purge_create_layers(x, y, w, h):
    global solidlayer, emptylayer, filllayer, ew

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

    ew = v.extrusion_width

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

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

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

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

    _purge_create_sequence(solidlayer, "X", x, y, w, h, ew)
    _purge_create_sequence(emptylayer, "Y", y, x, h, w, 2)
    _purge_generate_hatch(filllayer, 1, x + 1.85 * ew, y + 1.85 * ew,
                          x + w - 1.85 * ew, y + h - 1.85 * ew, 5)

    _purge_generate_tower_brim(x, y, w, h)

    _purge_calculate_sequences_length()
Exemplo n.º 6
0
def _purge_generate_hatch(code, slope, x1, y1, x2, y2, infill):
    assert infill > 0, "Infill must be >0"
    assert abs(slope) == 1, "Slope value must be -1 or 1"

    step = 100 / infill * ew

    if slope > 0:
        last_x = x1
        last_y = y1
        start_x = x1 - (y2 - y1) + step
        endx = x2
    else:
        last_x = x1
        last_y = y1
        start_x = x1 + step
        endx = x2 + (y2 - y1) - step

    index = 0

    code.append(gcode.GCodeCommand("G1 X{:3f} Y{:.3f}".format(last_x, last_y)))

    while start_x < endx:

        next_points = clipline(slope, x1, y1, x2, y2, start_x)

        start_x = start_x + step
        if next_points:
            if dist(last_x, last_y,
                    next_points[index][0], next_points[index][1]) > dist(
                        last_x, last_y, next_points[1 - index][0],
                        next_points[1 - index][1]):
                index = 1 - index

            strokelength = dist(last_x, last_y, next_points[index][0],
                                next_points[index][1])
            code.append(
                gcode.GCodeCommand("G1 X{:3f} Y{:.3f} E{:.4f}".format(
                    next_points[index][0], next_points[index][1],
                    calculate_purge(strokelength))))
            last_x = next_points[index][0]
            last_y = next_points[index][1]
            index = 1 - index

            strokelength = dist(last_x, last_y, next_points[index][0],
                                next_points[index][1])
            code.append(
                gcode.GCodeCommand("G1 X{:3f} Y{:.3f} E{:.4f}".format(
                    next_points[index][0], next_points[index][1],
                    calculate_purge(strokelength))))
            last_x = next_points[index][0]
            last_y = next_points[index][1]
Exemplo n.º 7
0
def convert_to_absolute():
    absolute = -9999

    for i in range(len(v.processed_gcode)):

        if absolute > 3000.0:
            v.processed_gcode.insert(i, "G92 E0.000    ;Extruder counter reset ")
            absolute = 0.00

        line = gcode.GCodeCommand(v.processed_gcode[i])

        if line.is_movement_command():
            if line.has_E():

                # if there is no filament reset code, make sure one is inserted before first extrusion
                # this should not be needed
                if absolute == -9999:
                    v.processed_gcode.insert(i, "G92 E0.00")
                    absolute = 0.0
                    i += 1

                absolute += line.E
                line.update_parameter("E", absolute)
                v.processed_gcode[i] = line.__str__()

        if line.fullcommand == "M83":
            v.processed_gcode[i] = "M82\n"

        if line.fullcommand == "G92":
            absolute = line.E
Exemplo n.º 8
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.GCodeCommand("; P2PP - BRIM CODE"))
    brimlayer.append(
        gcode.GCodeCommand("G0 X{:.3f} Y{:.3f} F8640".format(x, y)))
    brimlayer.append(gcode.GCodeCommand("G0 Z{:.3f}".format(v.layer_height)))

    for i in range(4):
        brimlayer.append(
            gcode.GCodeCommand("G1 X{:.3f} Y{:.3f}  E{:.4f} F{}".format(
                x + w, y, calculate_purge(w), 1200)))
        brimlayer.append(
            gcode.GCodeCommand("G1 X{:.3f} Y{:.3f}  E{:.4f}".format(
                x + w, y + h, calculate_purge(h))))
        x -= ew
        w += 2 * ew
        brimlayer.append(
            gcode.GCodeCommand("G1 X{:.3f} Y{:.3f}  E{:.4f}".format(
                x, y + h, calculate_purge(w))))
        y -= ew
        h += 2 * ew
        brimlayer.append(
            gcode.GCodeCommand("G1 X{:.3f} Y{:.3f}  E{:.4f}".format(
                x, y, calculate_purge(h))))
Exemplo n.º 9
0
def _purge_create_sequence(code, main_axis, x, y, w, h, step1):
    cw = w - 4 * ew
    ch = h - 4 * ew

    offset_x = x + 2 * ew
    offset_y = y + 2 * ew

    start1 = offset_x - ew * 0.15
    end1 = offset_x + cw + ew * 0.15

    start2 = offset_y - ew * 0.15
    end2 = offset_y + ch + ew * 0.15

    if main_axis == "Y":
        # start1, end1, start2, end2 = start2, end2, start1, end1
        short_axis = "X"
        code.append(
            gcode.GCodeCommand("G1 X{:.3f} Y{:.3f}".format(start2, start1)))
    else:
        short_axis = "Y"
        code.append(
            gcode.GCodeCommand("G1 X{:.3f} Y{:.3f}".format(start1, start2)))

    stroke_length = abs(end2 - start2)

    stroke_num = False

    while start1 < end1:
        stroke_num = not stroke_num
        stroke = min(end1 - start1, step1)
        start1 = start1 + stroke
        if stroke_num:
            code.append(
                gcode.GCodeCommand("G1 {}{:.3f} E{:.4f}".format(
                    short_axis, end2, calculate_purge(stroke_length))))
        else:
            code.append(
                gcode.GCodeCommand("G1 {}{:.3f} E{:.4f}".format(
                    short_axis, start2, calculate_purge(stroke_length))))

        code.append(
            gcode.GCodeCommand("G1 {}{:.3f} E{:.4f}".format(
                main_axis, start1, calculate_purge(stroke))))
Exemplo n.º 10
0
def _purge_generate_tower_brim(x, y, w, h):
    global brimlayer, last_brim_x, last_brim_y

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

    brimlayer.append(
        gcode.GCodeCommand("G0 X{:.3f} Y{:.3f} F4000".format(x, y)))
    brimlayer.append(gcode.GCodeCommand("G0 Z{:.3f}".format(v.layer_height)))

    for i in range(4):
        brimlayer.append(
            gcode.GCodeCommand("G1 X{:.3f} Y{:.3f}  E{:.4f} F{}".format(
                x + w, y, calculate_purge(w), v.wipe_feedrate1)))
        brimlayer.append(
            gcode.GCodeCommand("G1 X{:.3f} Y{:.3f}  E{:.4f}".format(
                x + w, y + h, calculate_purge(h))))
        x -= ew
        w += 2 * ew
        brimlayer.append(
            gcode.GCodeCommand("G1 X{:.3f} Y{:.3f}  E{:.4f}".format(
                x, y + h, calculate_purge(w))))
        y -= ew
        h += 2 * ew
        brimlayer.append(
            gcode.GCodeCommand("G1 X{:.3f} Y{:.3f}  E{:.4f}".format(
                x, y, calculate_purge(h))))

    last_brim_x = x
    last_brim_y = y
Exemplo n.º 11
0
def remove_previous_move_in_tower():
    idx = len(v.processed_gcode) - 10

    while idx < len(v.processed_gcode):
        line = v.processed_gcode[idx]
        tmp = gcode.GCodeCommand(line)
        if tmp.X and tmp.Y:
            if coordinate_in_tower(tmp.X, tmp.Y):
                if tmp.is_movement_command() and tmp.has_E():
                    v.total_material_extruded -= tmp.E
                    v.material_extruded_per_color[v.current_tool] -= tmp.E
                tmp.move_to_comment("tower skipped")
                v.processed_gcode[idx] = tmp.__str__()
        idx = idx + 1
Exemplo n.º 12
0
def patchup_toolchanges():
    # when we have only 4 extruders defined, keep the user defined input settings from PrusaSlicer
    if v.m4c_numberoffilaments == 4:
        return

    # otherwise replace the color with the right color offset.
    for idx in range(len(v.m4c_toolchange_source_positions)):
        try:
            old = v.parsed_gcode[v.m4c_toolchange_source_positions[idx]]
        except:
            old = v.parsed_gcode[v.m4c_toolchange_source_positions[-1]]

        _ip = calculate_input_index(idx, int(old.Command_value))
        v.parsed_gcode[v.m4c_toolchange_source_positions[idx]] = gcode.GCodeCommand(
            "T{} ; INPUT MAPPING MORE THAN 4 COLORS {} --> {}".format(_ip, _ip, int(old.Command_value)))
Exemplo n.º 13
0
def purge_complete_layer():
    global last_posx, last_posy, intermediate
    actual = 0

    if current_purge_index == 0:
        return 0

    purge_start_sequence(0)

    if intermediate:
        gcode.GCodeCommand("G1 X{:.3f} Y{:.3f} E{:.4f} ;inter resume ".format(
            tmp_pos_x, tmp_pos_y, tmpe)).issue_command()
    intermediate = False

    while current_purge_index:
        _purge_get_nextcommand_in_sequence().issue_command()
        _purge_update_sequence_index(0)

    purge_end_sequence()
Exemplo n.º 14
0
def gcode_parseline(index):
    g = v.parsed_gcode[index]

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

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

    if g.fullcommand in [ "M104" , "M109" ]:
        if not v.process_temp or not g.Class in [CLS_TOOL_PURGE, CLS_TOOL_START, CLS_TOOL_UNLOAD]:
            g.add_comment(" Unprocessed temp ")
            g.issue_command()
            v.new_temp = g.get_parameter("S", v.current_temp)
            v.current_temp = v.new_temp
        else:
            v.new_temp = g.get_parameter("S", v.current_temp)
            if v.new_temp >= v.current_temp:
                g.fullcommand = "M109"
                v.temp2_stored_command = g.__str__();
                g.move_to_comment("delayed temp rise until after purge {}-->{}".format(v.current_temp, v.new_temp))
                v.current_temp = v.new_temp
            else:
                v.temp1_stored_command = g.__str__();
                g.move_to_comment("delayed temp drop until after purge {}-->{}".format(v.current_temp,v.new_temp))
                g.issue_command()

        return



    if not g.Class in [CLS_TOOL_PURGE, CLS_TOOL_START, CLS_TOOL_UNLOAD] and v.current_temp != v.new_temp:
        print(v.temp1_stored_command)
        gcode.issue_code(v.temp1_stored_command)
        v.temp1_stored_command = ""

    # 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

    # flow rate changes have an effect on the filament consumption.  The effect is taken into account for ping generation
    if g.fullcommand == "M221":
        v.extrusion_multiplier = float(g.get_parameter("S", v.extrusion_multiplier * 100)) / 100
        g.issue_command()
        return

    # feed rate changes in the code are removed as they may interfere with the Palette P2 settings
    if g.fullcommand in ["M220"]:
        g.move_to_comment("Feed Rate Adjustments are removed")
        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

        v.keep_speed = g.get_parameter("F", v.keep_speed)


    previous_block_class = v.parsed_gcode[max(0, index - 1)].Class
    classupdate = g.Class != previous_block_class

    if classupdate and previous_block_class in [CLS_TOOL_PURGE, CLS_EMPTY]:
        if v.purge_count > 0:
            gcode.issue_code(
                ";>>> Total purge {:4.0f}mm3 - {:4.0f}mm <<<\n".format(purgetower.volfromlength(v.purge_count),
                                                                       v.purge_count))

    if classupdate and g.Class in [CLS_TOOL_PURGE, CLS_EMPTY]:
        v.purge_count = 0

    if classupdate and g.Class == CLS_BRIM and v.side_wipe and v.bigbrain3d_purge_enabled:
        v.side_wipe_length = v.bigbrain3d_prime * v.bigbrain3d_blob_size
        create_sidewipe_BigBrain3D()

    if not v.side_wipe:
        if x_coordinate_in_tower(g.X):
            v.keep_x = g.X
        if y_coordinate_in_tower(g.Y):
            v.keep_y = g.Y

    # remove M900 K0 commands during unload
    if g.Class == CLS_TOOL_UNLOAD:
        if (g.fullcommand == "G4" or (g.fullcommand in ["M900"] and g.get_parameter("K", 0) == 0)):
            g.move_to_comment("tool unload")


    ## ALL SITUATIONS
    ##############################################


    if g.Class in [CLS_TOOL_START, CLS_TOOL_UNLOAD]:

        if g.is_movement_command():
            if v.side_wipe or v.tower_delta or v.full_purge_reduction:
                g.move_to_comment("tool unload")
            else:
                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 g.Class == CLS_TOOL_PURGE and not (v.side_wipe or v.full_purge_reduction):



        if g.is_movement_command() and g.has_E():
            _x = g.get_parameter("X", v.current_position_x)
            _y = g.get_parameter("Y", v.current_position_y)
            # removepositive extrusions while moving into the tower
            if not (coordinate_in_tower(_x, _y) and coordinate_in_tower(v.purge_keep_x, v.purge_keep_y)) and g.E > 0:
                g.remove_parameter("E")

    if v.side_wipe:

        _x = g.get_parameter("X", v.current_position_x)
        _y = g.get_parameter("Y", v.current_position_y)
        if not coordinate_on_bed(_x, _y):
            g.remove_parameter("X")
            g.remove_parameter("Y")

    # top off the purge speed in the tower during tower delta or during no tower processing
    if not v.full_purge_reduction and not v.side_wipe and g.is_movement_command() and g.has_E() and g.has_parameter(
            "F"):
        f = int(g.get_parameter("F", 0))
        if f > v.purgetopspeed:
            g.update_parameter("F", v.purgetopspeed)
            g.add_comment(" prugespeed topped")

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

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

        # remove any commands that are part of the purge tower and still perofrm actions WITHIN the tower

        if g.is_movement_command() and g.Class in [CLS_ENDPURGE, CLS_ENDGRID] and g.has_X() and g.has_Y():
            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:

            if g.Class == CLS_BRIM_END:
                create_tower_gcode()
                purgetower.purge_generate_brim()

        ###################################
        # sepcific for SIDEWIPE
        ###################################

        if v.side_wipe:

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

        #######################################
        # specific for TOWER DELTA
        #######################################

        # changed for version 4.09.0 moves in tower were going all wrong.
        if not v.side_wipe and classupdate and g.Class == CLS_TOOL_PURGE:
            g.issue_command()
            gcode.issue_code("G1 X{} Y{} F8640;\n".format(v.keep_x, v.keep_y))
            v.current_position_x = v.keep_x
            v.current_position_x = v.keep_y

        if v.tower_delta:
            if classupdate and g.Class == CLS_TOOL_PURGE:
                entertower(g.Layer * v.layer_height + v.first_layer_height)
                return

            if classupdate and previous_block_class == CLS_TOOL_PURGE:
                leavetower()

        ################################################################
        # EMPTY GRID SKIPPING CHECK FOR SIDE WIPE/TOWER DELTA/FULLPURGE
        ################################################################
        if g.Class == CLS_EMPTY and "EMPTY GRID START" in g.get_comment():
            if g.Layer < len(v.skippable_layer) and v.skippable_layer[g.Layer]:
                v.towerskipped = True
                remove_previous_move_in_tower()
                if v.tower_delta:
                    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")
            else:
                if "EMPTY GRID START" in g.get_comment() and not v.side_wipe:
                    entertower(g.Layer * v.layer_height + v.first_layer_height)


        # changing from EMPTY to NORMAL
        ###############################
        if (previous_block_class == CLS_ENDGRID) and (g.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 g.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

            if v.retraction == 0:
                purgetower.retract(v.current_tool, 3000)

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

            if v.temp2_stored_command != "":
                gcode.issue_code(v.temp2_stored_command)
                v.temp2_stored_command = ""

            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 g.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 g.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 g.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 g.Class in [CLS_TOOL_PURGE, CLS_ENDPURGE, CLS_EMPTY]:
            if g.Layer < len(v.skippable_layer) and 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.toolchange_processed:
        if v.side_wipe and g.Class == CLS_NORMAL and classupdate:
            if v.bigbrain3d_purge_enabled:
                create_sidewipe_BigBrain3D()
            else:
                create_side_wipe()
            v.toolchange_processed = False

        if g.Class == CLS_NORMAL:
            gcode.GCodeCommand(";TOOLCHANGE PROCESSED").issue_command()
            v.toolchange_processed = False

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

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



    if g.is_retract_command():
        if v.retraction <= - (v.retract_length[v.current_tool] - 0.02):
            g.move_to_comment("Double Retract")
        else:
            if g.has_E():
                v.retraction += g.E
            else:
                v.retraction -= 1

    if g.is_unretract_command():
        if g.has_E():
            g.update_parameter("E", min(-v.retraction, g.E))
            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
Exemplo n.º 15
0
def parse_gcode():
    cur_tool = 0
    toolchange = 0
    emptygrid = 0

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

    index = 0
    for line in v.input_gcode:

        gui.progress_string(4 + 46 * index // total_line_count)


        if line.startswith(';'):

            m = v.regex_p2pp.match(line)
            if m:
                parameters.check_config_parameters(m.group(1), m.group(2))


            if line.startswith(";P2PP MATERIAL_"):
                algorithm_process_material_configuration(line[15:])

            layer = -1
            # if not supports are printed or layers are synced, there is no need to look at the layerheight,
            # otherwise look at the layerheight to determine the layer progress

            lm = layer_regex.match(line)
            if lm is not None:
                llm = len(lm.group(1))
                lmv = float(lm.group(2))
                if v.synced_support or not v.prints_support:
                    if llm == 5:  # LAYER
                        layer = int(lmv)
                else:
                    if llm == 11:  # LAYERHEIGHT
                        layer = int((lmv - v.first_layer_height + 0.005) / v.layer_height)

            if layer == v.parsedlayer:
                layer = -1

            if layer >= 0:
                v.parsedlayer = layer

            if layer > 0:
                v.skippable_layer.append((emptygrid > 0) and (toolchange == 0))
                toolchange = 0
                emptygrid = 0

            update_class(line)

        code = gcode.GCodeCommand(line)

        if code.Command == 'T':
            cur_tool = int(code.Command_value)
            v.set_tool = cur_tool
            v.m4c_toolchanges.append(cur_tool)
            v.m4c_toolchange_source_positions.append(len(v.parsed_gcode))


        code.Tool = cur_tool
        code.Class = v.block_classification


        # code.add_comment("[{}]".format(v.classes[v.block_classification]))
        v.parsed_gcode.append(code)

        if v.block_classification != v.previous_block_classification:

            if v.block_classification == CLS_TOOL_START:
                toolchange += 1

            if v.block_classification == CLS_EMPTY:
                emptygrid += 1

            if v.block_classification == CLS_BRIM or v.block_classification == CLS_TOOL_START or v.block_classification == CLS_TOOL_UNLOAD or v.block_classification == CLS_EMPTY:
                backpass(v.block_classification)

        if v.tower_measure:
            calculate_tower(code.X, code.Y)

        if v.block_classification == CLS_ENDGRID or v.block_classification == CLS_ENDPURGE:
            if code.has_X() and code.has_Y():
                if not coordinate_in_tower(code.X, code.Y):
                    v.parsed_gcode[-1].Class = CLS_NORMAL
                    v.block_classification = CLS_NORMAL

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

        index += 1
Exemplo n.º 16
0
def purge_generate_sequence(purgelength):
    global last_posx, last_posy, tmp_pos_x, tmp_pos_y, intermediate, tmpe

    if not purgelength > 0:
        return 0

    actual = 0

    purge_start_sequence(purgelength)

    # generate wipe code
    while purgelength > 1:

        if not intermediate:

            next_command = _purge_get_nextcommand_in_sequence()

            while not next_command.E or not next_command.E > 0:
                next_command.issue_command()
                _purge_update_sequence_index(purgelength)
                next_command = _purge_get_nextcommand_in_sequence()
        else:
            next_command = gcode.GCodeCommand(
                "G1 X{:.3f} Y{:.3f} E{:.4f} ;inter resume ".format(
                    tmp_pos_x, tmp_pos_y, tmpe))

        intermediate = False

        if float(next_command.E) > (purgelength + 1):

            tmp_pos_x = float(if_defined(next_command.X, last_posx))
            tmp_pos_y = float(if_defined(next_command.Y, last_posy))

            last_posx = last_posx + (tmp_pos_x - last_posx) * (
                purgelength / float(next_command.E))
            last_posy = last_posy + (tmp_pos_y - last_posy) * (
                purgelength / float(next_command.E))
            tmpe = float(next_command.E) - purgelength
            intermediate = True
            actual += purgelength

            gcode.GCodeCommand(
                "G1 X{:.3f} Y{:.3f} E{:.4f}   ;inter {:.3f} {:.3f}".format(
                    last_posx, last_posy, purgelength, tmp_pos_x,
                    tmp_pos_y)).issue_command()
            purgelength = 0

        else:
            last_posx = if_defined(next_command.X, last_posx)
            last_posy = if_defined(next_command.Y, last_posy)
            purgelength -= if_defined(next_command.E, 0)
            actual += if_defined(next_command.E, 0)
            next_command.issue_command()

        if not intermediate:
            _purge_update_sequence_index(purgelength)

    purge_end_sequence()

    # if we extruded more we need to account for that in the total count

    return actual
Exemplo n.º 17
0
def parse_gcode():
    cur_z = -999
    cur_tool = 0
    retract = 0.6
    layer = -1
    toolchange = 0
    emptygrid = 0

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

    index = 0
    for line in v.input_gcode:

        gui.progress_string(4 + 46 * index // total_line_count)

        specifier = 0
        code = gcode.GCodeCommand(line)
        v.parsedgcode.append(code)

        classupdate = False

        if line.startswith(';'):

            ## P2PP SPECIFIC SETP COMMANDS
            ########################################################
            if line.startswith(";P2PP"):
                parameters.check_config_parameters(line)

            if line.startswith(";P2PP MATERIAL_"):
                algorithm_process_material_configuration(line[15:])

            ## LAYER DISCRIMINATION COMMANDS
            ########################################################

            if line.startswith(";LAYER"):
                layer = 0
                try:
                    layer = int(line[7:])
                except ValueError:
                    fields = line[7:].split(" ")
                    for field in fields:
                        try:
                            layer = int(field)
                            break
                        except ValueError:
                            pass

                v.parsedlayer = layer
                if layer > 0:
                    v.skippable_layer.append((emptygrid > 0)
                                             and (toolchange == 0))
                toolchange = 0
                emptygrid = 0

            ## Update block class from comments information
            #########################################################
            classupdate = update_class(line)
        #
        # if line.startswith('T'):
        #     classupdate = update_class(line)

        if classupdate:

            if v.block_classification == CLS_TOOL_START:
                toolchange += 1

            if v.block_classification == CLS_EMPTY:
                emptygrid += 1

        ## Z-HOPS detection
        ###################
        if code.has_E() and code.is_movement_command():

            to_z = code.get_parameter("Z", 0)
            delta = (to_z - cur_z)

            if abs(delta - retract) < 0.0001:
                specifier |= SPEC_HOPUP

                if v.block_classification == CLS_TONORMAL:
                    v.previous_block_classification = v.block_classification = CLS_NORMAL

            if abs(-delta - retract) < 0.0001:
                specifier |= SPEC_HOPDOWN

            cur_z = to_z

        ## retract detections
        #####################
        if code.is_retract_command():
            specifier |= SPEC_RETRACTS

        ## tool change detection
        ########################
        if code.Command == 'T':
            cur_tool = int(code.Command_value)
            retract = v.retract_lift[cur_tool]
            specifier |= SPEC_TOOLCHANGE

        if v.tower_measure:
            if code.is_movement_command():
                if code.X is not None:
                    v.wipe_tower_info['minx'] = min(v.wipe_tower_info['minx'],
                                                    code.X)
                    v.wipe_tower_info['maxx'] = max(v.wipe_tower_info['maxx'],
                                                    code.X)
                if code.Y is not None:
                    v.wipe_tower_info['miny'] = min(v.wipe_tower_info['miny'],
                                                    code.Y)
                    v.wipe_tower_info['maxy'] = max(v.wipe_tower_info['maxy'],
                                                    code.Y)

        ## Extend block backwards towards last hop up
        #############################################

        if v.block_classification in [
                CLS_TOOL_START, CLS_TOOL_UNLOAD, CLS_EMPTY, CLS_BRIM
        ]:  # and not v.full_purge_reduction:
            backpass(v.block_classification)

        if v.block_classification in [CLS_ENDGRID, CLS_ENDPURGE]:
            if code.fullcommand == "G1":
                if code.has_X() and code.has_Y():
                    specifier |= SPEC_INTOWER

        if CLS_ENDGRID:
            code = v.parsedgcode[-1]
            if code.has_X and code.has_Y():
                if not coordinate_in_tower(code.X, code.Y):
                    v.block_classification = CLS_NORMAL
            # if v.parsedgcode[-1].fullcommand == "G1" and v.parsedgcode[-1].Z:
            #     v.block_classification = CLS_NORMAL
        else:
            if flagset(specifier, SPEC_RETRACTS):
                v.block_classification = CLS_NORMAL

        ## Put obtained values in global variables
        ##########################################
        v.gcodeclass.append(v.block_classification)
        v.layernumber.append(layer)
        v.linetool.append(cur_tool)
        v.parsecomment.append(specifier)
        v.classupdates.append(
            v.block_classification != v.previous_block_classification)
        v.previous_block_classification = v.block_classification
        index = index + 1

        if v.block_classification == CLS_BRIM_END:
            v.block_classification = CLS_NORMAL
Exemplo n.º 18
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()