Пример #1
0
def header_generate_omega(job_name):
    if v.printer_profile_string == '':
        v.printer_profile_string = v.default_printerprofile
        if v.palette3:
            v.printer_profile_string = v.default_printerprofile + v.default_printerprofile
        else:
            v.printer_profile_string = v.default_printerprofile
        gui.log_warning(
            "The PRINTERPROFILE identifier is missing, Default will be used {} \n"
            .format(v.printer_profile_string))
        v.printer_profile_string = v.default_printerprofile

    if len(v.splice_extruder_position) == 0 and not v.palette3:
        gui.log_warning("This does not look like a multi-colour file.\n")

    if v.palette3:
        return {
            'header': [],
            'summary': generatesummary(),
            'warnings': generatewarnings()
        }

    algorithm_create_table()
    if not v.palette_plus:
        return header_generate_omega_palette2(job_name)
    else:
        return header_generate_omega_paletteplus()
Пример #2
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
Пример #3
0
def generatesummary():
    summary = [
        ";Splice Information:\n", ";-------------------\n",
        ";       Splice Offset = {:-8.2f}mm\n".format(v.splice_offset),
        ";       Autoloading Offset = {:-8.2f}mm\n\n".format(
            v.autoloadingoffset)
    ]

    for i in range(len(v.splice_extruder_position)):
        if i == 0:
            pos = 0
        else:
            pos = v.splice_extruder_position[i - 1]

        summary.append(
            ";{:04}   Input: {}  Location: {:-8.2f}mm   length {:-8.2f}mm \n".
            format(i + 1, v.splice_used_tool[i] + 1, pos, v.splice_length[i]))

    summary.append("\n")
    summary.append(";Ping Information:\n")
    summary.append(";-----------------\n")

    for i in range(len(v.ping_extruder_position)):
        pingtext = ";Ping {:04} at {:-8.2f}mm\n".format(
            i + 1, v.ping_extruder_position[i])
        summary.append(pingtext)

    if v.side_wipe and v.side_wipe_loc == "" and not v.bigbrain3d_purge_enabled and not v.blobster_purge_enabled:
        gui.log_warning("Using sidewipe with undefined SIDEWIPELOC!!!")

    return summary
Пример #4
0
def header_generate_omega(job_name):
    if v.printer_profile_string == '':
        gui.log_warning(
            "The PRINTERPROFILE identifier is missing, Please add:\n" +
            ";P2PP PRINTERPROFILE=<your printer profile ID>\n" +
            "to your Printers Start GCODE.\n")

    if len(v.splice_extruder_position) == 0:
        gui.log_warning("This does not look like a multi-colour file.\n")
        if v.gui:
            if gui.ask_yes_no(
                    'Not a Multi-Colour file?',
                    "This doesn't look like a multi-colour file. Skip processing?"
            ):
                exit(1)
        else:
            if yes_or_no(
                    "This does not look like a multi-colour file.. Skip P2PP Processing?\n"
            ):
                exit(1)

    algorithm_create_table()
    if not v.palette_plus:
        return header_generate_omega_palette2(job_name)
    else:
        return header_generate_omega_paletteplus()
Пример #5
0
def optimize_tower_skip(skipmax, layersize):

    skipped = 0.0
    skipped_num = 0
    if v.side_wipe or v.bigbrain3d_purge_enabled:
        base = -1
    else:
        base = 0

    for idx in range(len(v.skippable_layer) - 1, base, -1):
        if skipped + 0.005 >= skipmax:
            v.skippable_layer[idx] = False
        elif v.skippable_layer[idx]:
            skipped = skipped + layersize
            skipped_num += 1

    if v.tower_delta:
        if skipped > 0:
            gui.log_warning(
                "Warning: Purge Tower delta in effect: {} Layers or {:-6.2f}mm".format(skipped_num, skipped))
        else:
            gui.create_logitem("Tower Purge Delta could not be applied to this print")
            for idx in range(len(v.skippable_layer)):
                v.skippable_layer[idx] = False
            v.tower_delta = False

    if not v.side_wipe and not v.bigbrain3d_purge_enabled:
        v.skippable_layer[0] = False
Пример #6
0
def generate_blobster_advanced_blob(count):
    issue_code("\n;---- BLOBSTER ADVANCED BLOB {}".format(count + 1), True)

    setfanspeed(0)
    if count > 0:
        issue_code("G4 P2000  ; Interblob wait")
    issue_code("G1 X{:.3f} F1000   ; go to the actual wiping position".format(
        v.mechpurge_x_position))  # takes 2.5 seconds
    issue_code("G4 P{}  ; Wait for Blobster to engage before purging".format(
        v.blobster_engagetime))

    if v.retraction < 0:
        purgetower.largeunretract()

    try:
        for i in range(len(v.blobster_advanced_speed)):
            setfanspeed(v.blobster_advanced_fan[i])
            issue_code("G1 E{:6.3f} F{}     ; Purge Part {} ".format(
                v.blobster_advanced_length[i], v.blobster_advanced_speed[i],
                i + 1))
    except IndexError:
        if not v.blobsterwarning:
            gui.log_warning(
                "BLOBSTER ERROR: THIS FILE WILL NOT PRING AS EXPECTED!!!")
            v.blobsterwarning = True

    purgetower.largeretract(v.mechpurge_retract)

    setfanspeed(255)
    issue_code("G4 S{0:.0f}              ; blob {0}s cooling time".format(
        v.mechpurge_blob_cooling_time))
    issue_code(
        "G1 X{:.3f} F10800  ; activate flicker".format(v.mechpurge_x_position -
                                                       v.bigbrain3d_left * 30))
Пример #7
0
def algorithm_process_material_configuration(splice_info):

    # 22/02/2022 - Added check for correctness of the parameters
    error = True

    fields = splice_info.split("_")
    if fields[0] == "DEFAULT" and len(fields) == 4:
        try:
            check = float(fields[1]) + float(fields[2]) + float(fields[3])
            v.default_splice_algorithm = algorithm_create_process_string(
                fields[1], fields[2], fields[3])
            error = False
        except ValueError:
            pass

    if len(fields) == 5:
        key = "{}{}".format(fields[0], fields[1])
        try:
            check = float(fields[2]) + float(fields[3]) + float(fields[4])
            error = False
            v.splice_algorithm_dictionary[
                key] = algorithm_create_process_string(fields[2], fields[3],
                                                       fields[4])
        except ValueError:
            pass

    if error:
        gui.log_warning("Error splice info: {}".format(splice_info))
Пример #8
0
def generatesummary():
    summary = [
        ";---------------------\n", "; - SPLICE INFORMATION-\n",
        ";---------------------\n",
        ";       Splice Offset = {:-8.2f}mm\n\n".format(v.splice_offset)
    ]

    for i in range(len(v.splice_extruder_position)):
        if i == 0:
            pos = 0
        else:
            pos = v.splice_extruder_position[i - 1]

        summary.append(
            ";{:04}   Tool: {}  Location: {:-8.2f}mm   length {:-8.2f}mm  ({})\n"
            .format(i + 1, v.splice_used_tool[i], pos, v.splice_length[i],
                    hexify_float(pos)))

    summary.append("\n")
    summary.append(";-------------------\n")
    summary.append("; - PING INFORMATION-\n")
    summary.append(";-------------------\n")

    for i in range(len(v.ping_extruder_position)):
        pingtext = ";Ping {:04} at {:-8.2f}mm ({})\n".format(
            i + 1, v.ping_extruder_position[i],
            hexify_float(v.ping_extruder_position[i]))
        summary.append(pingtext)

    if v.side_wipe and v.side_wipe_loc == "":
        gui.log_warning("Using sidewipe with undefined SIDEWIPELOC!!!")

    return summary
Пример #9
0
def generatesummary():
    summary = []

    summary.append(";---------------------\n")
    summary.append("; - COLORS DEFINED   -\n")
    summary.append(";---------------------\n")
    summary.append(";Number of extruders defined in PrusaSlicer: {}\n".format(
        v.m4c_numberoffilaments))
    summary.append(";Number of color swaps in this print: {}\n".format(
        len(v.m4c_late_warning)))
    summary.append(";Filament defined for this print:\n")
    for i in range(v.m4c_numberoffilaments):
        try:
            id = v.filament_ids[i]
        except IndexError:
            id = ""
        summary.append(";.   Filament {} - Color Code {} - {:20}  {}\n".format(
            i + 1, v.filament_color_code[i],
            find_nearest_colour(v.filament_color_code[i].strip("\n")), id))
    summary.append("\n")

    summary.append(";---------------------\n")
    summary.append("; - SPLICE INFORMATION-\n")
    summary.append(";---------------------\n")
    summary.append(";       Splice Offset = {:-8.2f}mm\n".format(
        v.splice_offset))
    summary.append(";       Autoloading Offset = {:-8.2f}mm\n\n".format(
        v.autoloadingoffset))

    for i in range(len(v.splice_extruder_position)):
        if i == 0:
            pos = 0
        else:
            pos = v.splice_extruder_position[i - 1]

        summary.append(
            ";{:04}   Input: {}  Location: {:-8.2f}mm   length {:-8.2f}mm  ({})\n"
            .format(i + 1, v.splice_used_tool[i] + 1, pos, v.splice_length[i],
                    hexify_float(pos)))

    summary.append("\n")
    summary.append(";-------------------\n")
    summary.append("; - PING INFORMATION-\n")
    summary.append(";-------------------\n")

    for i in range(len(v.ping_extruder_position)):
        pingtext = ";Ping {:04} at {:-8.2f}mm ({})\n".format(
            i + 1, v.ping_extruder_position[i],
            hexify_float(v.ping_extruder_position[i]))
        summary.append(pingtext)

    if v.side_wipe and v.side_wipe_loc == "" and not v.bigbrain3d_purge_enabled:
        gui.log_warning("Using sidewipe with undefined SIDEWIPELOC!!!")

    return summary
Пример #10
0
def swap_pause(command):
    global warning
    if v.z_maxheight > 0:
        lift = min(v.current_position_z + 20, v.z_maxheight)
    else:
        lift = v.current_position_z + 20
        if warning:
            gui.log_warning("Manual swap lift of 20 without constraint!!")

    gc.issue_code(";MANUAL SWAP PAUSE SEQUENCE")
    gc.issue_code("G1 Z{:.2f} F10800".format(lift))
    gc.issue_code(command)
Пример #11
0
def gcode_process_toolchange(new_tool, location, current_layer):
    # some commands are generated at the end to unload filament,
    # they appear as a reload of current filament - messing up things
    if new_tool == v.current_tool:
        return

    location += v.splice_offset

    if new_tool == -1:
        location += v.extra_runout_filament
        v.material_extruded_per_color[v.current_tool] += v.extra_runout_filament
        v.total_material_extruded += v.extra_runout_filament
    else:
        v.palette_inputs_used[new_tool] = True

    length = location - v.previous_toolchange_location

    if v.current_tool != -1:

        v.splice_extruder_position.append(location)
        v.splice_length.append(length)
        v.splice_used_tool.append(v.current_tool)

        v.autoadded_purge = 0

        if len(v.splice_extruder_position) == 1:
            if v.splice_length[0] < v.min_start_splice_length:
                if v.autoaddsplice and (v.full_purge_reduction or v.side_wipe):
                    v.autoadded_purge = v.min_start_splice_length - length
                else:
                    gui.log_warning("Warning : Short first splice (<{}mm) Length:{:-3.2f}".format(length,
                                                                                              v.min_start_splice_length))

                    filamentshortage = v.min_start_splice_length - v.splice_length[0]
                    v.filament_short[new_tool] = max(v.filament_short[new_tool], filamentshortage)
        else:
            if v.splice_length[-1] < v.min_splice_length:
                if v.autoaddsplice and (v.full_purge_reduction or v.side_wipe):
                    v.autoadded_purge = v.min_splice_length - v.splice_length[-1]
                else:
                    gui.log_warning("Warning: Short splice (<{}mm) Length:{:-3.2f} Layer:{} Input:{}".
                                    format(v.min_splice_length, length, current_layer, v.current_tool + 1))
                    filamentshortage = v.min_splice_length - v.splice_length[-1]
                    v.filament_short[new_tool] = max(v.filament_short[new_tool], filamentshortage)

        v.side_wipe_length += v.autoadded_purge
        v.splice_extruder_position[-1] += v.autoadded_purge
        v.splice_length[-1] += v.autoadded_purge

        v.previous_toolchange_location = v.splice_extruder_position[-1]

    v.previous_tool = v.current_tool
    v.current_tool = new_tool
Пример #12
0
def optimize_tower_skip(skipmax, layersize):
    skipped = 0.0
    skipped_num = 0
    for idx in range(len(v.skippable_layer) - 1, 0, -1):
        if skipped >= skipmax:
            v.skippable_layer[idx] = False
        elif v.skippable_layer[idx]:
            skipped = skipped + layersize
            skipped_num += 1

    if v.tower_delta and skipped > 0:
        gui.log_warning(
            "Warning: Purge Tower delta in effect: {} Layers or {:-6.2f}mm".
            format(skipped_num, skipped))
    else:
        gui.create_logitem(
            "Tower Purge Delta could not be applied to this print")
Пример #13
0
def update_class(gcode_line):

    v.previous_block_classification = v.block_classification

    if gcode_line[0] == "T":
        v.block_classification = CLS_TOOL_PURGE

    if gcode_line.startswith("; CP"):
        if "PRIMING START" in gcode_line:
            gui.log_warning("Extruder Primimng will not work with P2PP")

        if "TOOLCHANGE START" in gcode_line:
            v.block_classification = CLS_TOOL_START

        if "TOOLCHANGE UNLOAD" in gcode_line:
            v.block_classification = CLS_TOOL_UNLOAD

        if "TOOLCHANGE WIPE" in gcode_line:
            v.block_classification = CLS_TOOL_PURGE

        if "TOOLCHANGE END" in gcode_line:
            if v.previous_block_classification == CLS_TOOL_UNLOAD:
                v.block_classification = CLS_NORMAL
            else:
                v.block_classification = CLS_TONORMAL

        if "WIPE TOWER FIRST LAYER BRIM START" in gcode_line:
            v.block_classification = CLS_BRIM
            v.tower_measure = True

        if "WIPE TOWER FIRST LAYER BRIM END" in gcode_line:
            v.tower_measure = False
            v.block_classification = CLS_BRIM_END


        if "EMPTY GRID START" in gcode_line:
            v.block_classification = CLS_EMPTY

        if "EMPTY GRID END" in gcode_line:
            v.block_classification = CLS_ENDGRID

        if v.block_classification == CLS_TONORMAL and v.previous_block_classification == CLS_TOOL_PURGE:
            v.block_classification = CLS_ENDPURGE

    return
Пример #14
0
def algorithm_create_table():
    splice_list = []
    for i in range(4):
        for j in range(4):

            if i == j:
                continue
            try:
                algo_key = "{}{}".format(
                    v.used_filament_types.index(v.filament_type[i]) + 1,
                    v.used_filament_types.index(v.filament_type[j]) + 1)
                if algo_key in splice_list:
                    continue
            except (IndexError, KeyError):
                continue

            if not algorithm_transition_used(i, j):
                continue

            splice_list.append(algo_key)

            try:
                algo = v.splice_algorithm_dictionary["{}{}".format(
                    v.filament_type[i], v.filament_type[j])]
            except (IndexError, KeyError):
                gui.log_warning(
                    "WARNING: No Algorithm defined for transitioning" +
                    " {} to {}. Using Default".format(v.filament_type[i],
                                                      v.filament_type[j]))
                if v.default_splice_algorithm is None:
                    if v.palette_plus:
                        algo = "0,0,0"
                    else:
                        algo = "D0000 D0000 D0000"
                else:
                    algo = v.default_splice_algorithm
            if v.palette_plus:
                v.splice_algorithm_table.append("({},{})".format(
                    algo_key, algo).replace("-", ""))
            else:
                v.splice_algorithm_table.append("D{} {}".format(
                    algo_key, algo))
Пример #15
0
    def __str__(self):
        p = ""

        # use the same formatting as prusa to ease file compares (X, Y, Z, E, F)

        sorted_keys = "XYZE"
        if self.is_movement_command():
            for key in sorted_keys:
                if key in self.Parameters:
                    form = ""
                    if key in "XYZ":
                        form = "{}{:0.3f} "
                    if key == "E":
                        form = "{}{:0.5f} "
                    value = self.Parameters[key]
                    if value == None:
                        gui.log_warning(
                            "GCode error detected, file might not print correctly"
                        )
                        value = ""

                    p = p + form.format(key, value)

        for key in self.Parameters:
            if not self.is_movement_command() or key not in sorted_keys:
                value = self.Parameters[key]
                if value == None:
                    value = ""

                p = p + "{}{} ".format(key, value)

        c = self.fullcommand
        if not c:
            c = ""

        if not self.Comment:
            co = ""
        else:
            co = ";" + self.Comment

        return ("{} {} {}".format(c, p, co)).strip() + "\n"
Пример #16
0
def check_config_parameters(keyword, value):
    keyword = keyword.upper()
    if value is None:
        value = ""

    if keyword == "TEMPERATURECONTROL":
        v.process_temp = True

    if keyword == "PRINTERPROFILE":

        if len(value) != 16:
            gui.log_warning("Invalid Printer profile!  - Has invalid length (expect 16) - [{}]"
                            .format(value))
            value = ""
        if not all(char in set("0123456789ABCDEFabcdef") for char in value):
            gui.log_warning("Invalid Printer profile!  - Invalid characters  (expect 0123456789abcdef) - [{}]"
                            .format(value))
            value = ""

        if len(value) == 16:
            v.printer_profile_string = value
            gui.set_printer_id(v.printer_profile_string)
        return

    if keyword == "ACCESSORYMODE_MAF":
        v.accessory_mode = True
        gui.create_logitem("Config: Palette2 Accessory Mode Selected")
        return

    if keyword == "ACCESSORYMODE_MSF":
        v.accessory_mode = True
        v.palette_plus = True
        gui.create_logitem("Config: Palette+ Accessory Mode Selected")
        return

    if keyword == "P+LOADINGOFFSET":
        v.palette_plus_loading_offset = int(value)
        return

    if keyword == "P+PPM":
        v.palette_plus_ppm = intparameter(value)
        return

    if keyword == "SPLICEOFFSET":
        v.splice_offset = floatparameter(value)
        gui.create_logitem("Splice Offset set tofiloverride {:-5.2f}mm".format(v.splice_offset))
        return

    if keyword == "PROFILETYPEOVERRIDE":
        v.filament_type[v.set_tool] = value
        v.used_filament_types.append(v.filament_type[v.set_tool])
        v.used_filament_types = list(dict.fromkeys(v.used_filament_types))
        return

    if keyword == "EXTRUSIONMULTIPLIERCORRECTION":
        v.filament_type[v.current_tool] = floatparameter(value)
        return

    if keyword == "EXTRAENDFILAMENT":
        v.extra_runout_filament = floatparameter(value)
        gui.create_logitem("Extra filament at end of print {:-8.2f}mm".format(v.extra_runout_filament))
        return

    if keyword == "BEFORESIDEWIPEGCODE":
        v.before_sidewipe_gcode.append(value)
        return

    if keyword == "AFTERSIDEWIPEGCODE":
        v.after_sidewipe_gcode.append(value)
        return

    if keyword == "AUTOLOADINGOFFSET":
        v.autoloadingoffset = floatparameter(value)
        return

    if keyword == "AUTOADDPURGE":
        v.autoaddsplice = True
        return

    if keyword == "MINSTARTSPLICE":
        v.min_start_splice_length = floatparameter(value)
        if v.min_start_splice_length < 100:
            v.min_start_splice_length = 100
            gui.log_warning("Minimal first slice length adjusted to 100mm")
        return

    if keyword == "BEDSIZEX":
        v.bed_size_x = floatparameter(value)
        return

    if keyword == "BEDSIZEY":
        v.bed_size_y = floatparameter(value)
        return

    if keyword == "BEDORIGINX":
        v.bed_origin_x = floatparameter(value)
        return

    if keyword == "BEDORIGINY":
        v.bed_origin_y = floatparameter(value)
        return

    if keyword == "BIGBRAIN3D_BLOBSIZE":
        v.bigbrain3d_blob_size = intparameter(value)
        return

    if keyword == "BIGBRAIN3D_BLOBSPEED":
        v.bigbrain3d_blob_speed = intparameter(value)
        return

    if keyword == "BIGBRAIN3D_COOLINGTIME":
        v.bigbrain3d_blob_cooling_time = intparameter(value)
        return

    if keyword == "BIGBRAIN3D_PURGEPOSITION":
        v.bigbrain3d_x_position = floatparameter(value)
        return

    if keyword == "BIGBRAIN3D_PURGEYPOSITION":
        v.bigbrain3d_y_position = floatparameter(value)
        return

    if keyword == "BIGBRAIN3D_MOTORPOWER_HIGH":
        v.bigbrain3d_motorpower_high = intparameter(value)
        return

    if keyword == "BIGBRAIN3D_MOTORPOWER_NORMAL":
        v.bigbrain3d_motorpower_normal = intparameter(value)
        return

    if keyword == "BIGBRAIN3D_NUMBER_OF_WHACKS":
        v.bigbrain3d_whacks = intparameter(value)
        return

    if keyword == "BIGBRAIN3D_PRIME_BLOBS":
        v.bigbrain3d_prime = intparameter(value)
        return

    if keyword == "BIGBRAIN3D_FAN_OFF_PAUSE":
        v.bigbrain3d_fanoffdelay = intparameter(value)
        return

    if keyword == "BIGBRAIN3D_LEFT_SIDE":
        v.bigbrain3d_left = -1
        return

    if keyword == "BIGBRAIN3D_ENABLE":
        if not v.wipe_remove_sparse_layers:
            v.bigbrain3d_purge_enabled = True
            gui.log_warning("BIGBRAIN3D Will only work with installed hardware on a Prusa Printer")
        else:
            gui.log_warning("BIGBRAIN3D mode not compatible with sparse wipe tower in PS")
        return

    if keyword == "BIGBRAIN3D_SMARTFAN":
        v.bigbrain3d_smartfan = True
        return

    if keyword == "MINSPLICE":
        v.min_splice_length = floatparameter(value)
        if v.min_splice_length < 70:
            v.min_splice_length = 70
            gui.log_warning("Minimal slice length adjusted to 70mm")
        return

    # LINEAR PING removed

    if keyword == "LINEARPINGLENGTH":
        v.ping_interval = floatparameter(value)
        v.ping_length_multiplier = 1.0
        if v.ping_interval < 300:
            v.ping_interval = 300
            gui.log_warning("Minimal Linear Ping distance is 300mm!  Your config stated: {}".format(line))
        gui.create_logitem("Linear Ping interval of  {:-6.2f}mm".format(v.ping_interval))
        return

    # SIDE TRANSITIONING
    if keyword == "SIDEWIPELOC":
        v.side_wipe_loc = value
        return

    if keyword == "PURGETOPSPEED":
        v.purgetopspeed = int(floatparameter(value))
        gui.create_logitem("Purge Max speed set to {:.0f}mm/min ({}mm/s)".format(v.purgetopspeed, v.purgetopspeed / 60))
        return

    if keyword == "WIPEFEEDRATE":
        v.wipe_feedrate = floatparameter(value)
        return

    if keyword == "SIDEWIPEMINY":
        v.sidewipe_miny = floatparameter(value)
        return

    if keyword == "SIDEWIPEMAXY":
        v.sidewipe_maxy = floatparameter(value)
        return

    if keyword == "SIDEWIPECORRECTION":
        v.sidewipe_correction = floatparameter(value)
        if v.sidewipe_correction < 0.9 or v.sidewipe_correction > 1.10:
            v.sidewipe_correction = 1.0
        return

    if keyword == "PURGETOWERDELTA":
        parm = abs(floatparameter(value))
        if parm > 0.001 and v.wipe_remove_sparse_layers:
            gui.log_warning("TOWER DELTA feature mode not compatible with sparse wipe tower in PS")
            v.max_tower_delta = 0.0
        else:
            if parm != float(0):
                v.max_tower_z_delta = abs(floatparameter(value))
                gui.create_logitem("Max Purge Tower Delta set to {:-2.2f}mm".format(v.max_tower_z_delta))


        return

    if keyword == "FULLPURGEREDUCTION":
        if not v.wipe_remove_sparse_layers:
            gui.create_logitem("Full purge reduction configured")
            v.full_purge_reduction = True
        else:
            gui.log_warning("FULL PURGE TOWER REDUCTION feature mode not compatible with sparse wipe tower in PS")
            v.full_purge_reduction = False
        return

    if keyword == "CHECKVERSION":
        import p2pp.checkversion as cv
        import version
        latest = cv.get_version(cv.MASTER)
        if latest > version.Version:
            gui.create_logitem("New development version of P2PP available ({})".format(latest), "red", False, "2.0")
        else:
            if (latest < version.Version):
                latest = cv.get_version(cv.DEV)
                if (latest > version.Version):
                    gui.create_logitem("New development version of P2PP available ({})".format(latest), "red", False,
                                       "2.0")

    # Program parameters
    if keyword == "NOGUI":
        v.gui = False
        return

    if keyword == "CONSOLEWAIT":
        v.consolewait = True
        return

    if keyword == "IGNOREWARNINGS":
        v.ignore_warnings = True
        return

    if keyword == "ABSOLUTEEXTRUDER":
        v.absolute_extruder = True
        gui.create_logitem("Convert to absolute extrusion parameters")
        return

    if keyword == "DEBUGTCOMMAND":
        v.debug_leaveToolCommands = True
        gui.log_warning("DEBUGTCOMMAND ACTIVE - File will not print correctly!!")
        return
Пример #17
0
def check_config_parameters(line):
    # BASIC SETUP  (material setup handled in mcf.py

    # -p takes precedence over printer defined in file
    if "PRINTERPROFILE" in line:
        tmp_string = stringparameter(line)
        if len(tmp_string) != 16:
            gui.log_warning(
                "Invalid Printer profile!  - Has invalid length (expect 16) - [{}]"
                .format(tmp_string))
            tmp_string = ""
        if not all(char in set("0123456789ABCDEFabcdef")
                   for char in tmp_string):
            gui.log_warning(
                "Invalid Printer profile!  - Invalid characters  (expect 0123456789abcdef) - [{}]"
                .format(tmp_string))
            tmp_string = ""

        if len(tmp_string) == 16:
            v.printer_profile_string = tmp_string
            gui.set_printer_id(v.printer_profile_string)
        return

    if "ACCESSORYMODE_MAF" in line:
        v.accessory_mode = True
        gui.create_logitem("Config: Palette2 Accessory Mode Selected")

    if "ACCESSORYMODE_MSF" in line:
        v.accessory_mode = True
        v.palette_plus = True
        gui.create_logitem("Config: Palette+ Accessory Mode Selected")

    if "P+LOADINGOFFSET" in line:
        v.palette_plus_loading_offset = int(floatparameter(line))

    if "P+PPM" in line:
        v.palette_plus_ppm = int(floatparameter(line))

    if "SPLICEOFFSET" in line:
        v.splice_offset = floatparameter(line)
        gui.create_logitem("Splice Offset set to {:-5.2f}mm".format(
            v.splice_offset))
        return

    if "PROFILETYPEOVERRIDE" in line:
        v.filament_type[v.current_tool] = stringparameter(line)
        v.used_filament_types.append(v.filament_type[v.current_tool])
        v.used_filament_types = list(dict.fromkeys(v.used_filament_types))
        return

    if "EXTRUSIONMULTIPLIERCORRECTION" in line:
        v.filament_type[v.current_tool] = floatparameter(line)
        return

    if "EXTRAENDFILAMENT" in line:
        v.extra_runout_filament = floatparameter(line)
        gui.create_logitem("Extra filament at end of print {:-8.2f}mm".format(
            v.extra_runout_filament))
        return

    if "BEFORESIDEWIPEGCODE" in line:
        v.before_sidewipe_gcode.append(stringparameter(line))
        return

    if "AFTERSIDEWIPEGCODE" in line:
        v.after_sidewipe_gcode.append(stringparameter(line))
        return

    if "MINSTARTSPLICE" in line:
        v.min_start_splice_length = floatparameter(line)
        if v.min_start_splice_length < 100:
            v.min_start_splice_length = 100
            gui.log_warning("Minimal first slice length adjusted to 100mm")
        return

    if "BEDSIZEX" in line:
        v.bed_size_x = floatparameter(line)
        return
    if "BEDSIZEY" in line:
        v.bed_size_y = floatparameter(line)
        return
    if "BEDORIGINX" in line:
        v.bed_origin_x = floatparameter(line)
        return
    if "BEDORIGINY" in line:
        v.bed_origin_y = floatparameter(line)
        return

    if "BIGBRAIN3D_BLOBSIZE" in line:
        v.bigbrain3d_blob_size = int(floatparameter(line))

    if "BIGBRAIN3D_COOLINGTIME" in line:
        v.bigbrain3d_blob_cooling_time = int(floatparameter(line))

    if "BIGBRAIN3D_PURGEPOSITION" in line:
        v.bigbrain3d_x_position = floatparameter(line)

    if "BIGBRAIN3D_MOTORPOWER_HIGH" in line:
        v.bigbrain3d_motorpower_high = int(floatparameter(line))

    if "BIGBRAIN3D_MOTORPOWER_NORMAL" in line:
        v.bigbrain3d_motorpower_normal = int(floatparameter(line))

    if "BIGBRAIN3D_ENABLE" in line:
        v.bigbrain3d_purge_enabled = True
        gui.log_warning(
            "BIGBRAIN3D Will only work with installed hardware on a Prusa Printer"
        )

    if "BIGBRAIN3D_SMARTFAN" in line:
        v.bigbrain3d_smartfan = True

    if "MINSPLICE" in line:
        v.min_splice_length = floatparameter(line)
        if v.min_splice_length < 70:
            v.min_splice_length = 70
            gui.log_warning("Minimal slice length adjusted to 70mm")
        return

    # LINEAR PING removed

    if "LINEARPINGLENGTH" in line:
        v.ping_interval = floatparameter(line)
        v.ping_length_multiplier = 1.0
        if v.ping_interval < 300:
            v.ping_interval = 300
            gui.log_warning(
                "Minimal Linear Ping distance is 300mm!  Your config stated: {}"
                .format(line))
        gui.create_logitem("Linear Ping interval of  {:-6.2f}mm".format(
            v.ping_interval))
        return

    if line.endswith("LINEARPING"):
        gui.log_warning(
            "LINEARPING deprecated, use LINEARPINGLENGTH  parameter instead")
        return

    # SIDE TRANSITIONING
    if "SIDEWIPELOC" in line:
        v.side_wipe_loc = stringparameter(line)
        return

    if "WIPEFEEDRATE" in line:
        v.wipe_feedrate = floatparameter(line)
        return

    if "SIDEWIPEMINY" in line:
        v.sidewipe_miny = floatparameter(line)
        return

    if "SIDEWIPEMAXY" in line:
        v.sidewipe_maxy = floatparameter(line)
        return

    if "SIDEWIPECORRECTION" in line:
        v.sidewipe_correction = floatparameter(line)
        if v.sidewipe_correction < 0.9 or v.sidewipe_correction > 1.10:
            v.sidewipe_correction = 1.0
        return

    if "PURGETOWERDELTA" in line:
        if abs(floatparameter(line)) != abs(float(0)):
            v.max_tower_z_delta = abs(floatparameter(line))
            gui.create_logitem(
                "Max Purge Tower Delta set to {:-2.2f}mm".format(
                    v.max_tower_z_delta))
        return
    if "FULLPURGEREDUCTION" in line:
        gui.create_logitem("Full purge reduction configured")
        v.full_purge_reduction = True

    if line.endswith("CHECKVERSION"):
        import p2pp.checkversion as cv
        import version
        latest = cv.get_version(cv.MASTER)
        if latest > version.Version:
            gui.create_logitem(
                "New development version of P2PP available ({})".format(
                    latest), "red", False, "2.0")
        else:
            if (latest < version.Version):
                latest = cv.get_version(cv.DEV)
                if (latest > version.Version):
                    gui.create_logitem(
                        "New development version of P2PP available ({})".
                        format(latest), "red", False, "2.0")

    # REPRAP COMPATIBILITY
    if "REPRAPCOMPATIBLE" in line:
        v.reprap_compatible = True
        return

    # Program parameters
    if "NOGUI" in line:
        v.gui = False
        return

    if "CONSOLEWAIT" in line:
        v.consolewait = True

    if "IGNOREWARNINGS" in line:
        v.ignore_warnings = True

    if "ABSOLUTEEXTRUDER" in line:
        v.absolute_extruder = True
        gui.create_logitem("Convert to absolute extrusion parameters")
Пример #18
0
def config_checks():
    # CHECK BED SIZE PARAMETERS
    if v.bed_size_x == -9999 or v.bed_size_y == -9999 or v.bed_origin_x == -9999 or v.bed_origin_y == -9999:
        gui.log_warning("Bedsize nor or incorrectly defined.")

    v.bed_max_x = v.bed_origin_x + v.bed_size_x
    v.bed_max_y = v.bed_origin_y + v.bed_size_y

    # CHECK EXTRUSION WIDTH
    if v.extrusion_width == 0:
        gui.create_logitem("Extrusionwidth set to 0, defaulted back to 0.45")
        v.extrusion_width = 0.45

    if v.process_temp and v.side_wipe:
        gui.log_warning(
            "TEMPERATURECONTROL and SIDEWIPE / BigBrain3D are incompatible (TEMPERATURECONTROL disabled"
        )
        v.process_temp = False

    if v.palette_plus:
        if v.palette_plus_ppm == -9:
            gui.log_warning(
                "P+ parameter P+PPM incorrectly set up in startup GCODE - Processing Halted"
            )
            return -1
        if v.palette_plus_loading_offset == -9:
            gui.log_warning(
                "P+ parameter P+LOADINGOFFSET incorrectly set up in startup GCODE - Processing Halted"
            )
            return -1

    v.side_wipe = not ((v.bed_origin_x <= v.wipe_tower_posx <= v.bed_max_x) and
                       (v.bed_origin_y <= v.wipe_tower_posy <= v.bed_max_y))
    v.tower_delta = v.max_tower_z_delta > 0

    if (v.tower_delta or v.full_purge_reduction) and v.variable_layer:
        gui.log_warning(
            "Variable layers may cause issues with FULLPURGE / TOWER DELTA")
        gui.log_warning(
            "This warning could be caused by support that will print on variable layer offsets"
        )

    # sidewipe option compatibility test
    if v.side_wipe:

        if v.full_purge_reduction:
            gui.log_warning(
                "FULLURGEREDUCTION is incompatible with SIDEWIPE, parameter ignored"
            )
            v.full_purge_reduction = False

        if v.skirts:
            if v.ps_version >= "2.2":
                gui.log_warning(
                    "SIDEWIPE and SKIRTS are NOT compatible in PS2.2 or later")

        if v.wipe_remove_sparse_layers:
            gui.log_warning(
                "SIDE WIPE mode not compatible with sparse wipe tower in PS - Processing Halted"
            )
            return -1

        gui.create_logitem("Side wipe activated", "blue")

    # fullpurge option compatibility test
    if v.full_purge_reduction:

        if v.skirts:
            gui.log_warning(
                "FULLPURGE and SKIRTS are NOT compatible.  Overlaps may occur")

        if v.tower_delta:
            gui.log_warning(
                "FULLPURGEREDUCTION is incompatible with TOWERDELTA")
            v.tower_delta = False
        gui.create_logitem("FULLPURGEREDUCTION activated", "blue")

    # auto add splice length only works with full purge reeduction / sidewipe
    if v.autoaddsplice:
        if not v.full_purge_reduction and not v.side_wipe:
            gui.log_warning(
                "AUTOADDPURGE only works with SIDEWIPE and FULLPURGEREDUCTION")
        else:
            gui.create_logitem("Automatic Splice length increase activated",
                               "blue")

    if len(v.skippable_layer) == 0:
        gui.log_warning("P2PP Layer Configuration is missing!!")
        return -1

    skippable = optimize_tower_skip(int(v.max_tower_z_delta / v.layer_height))
    if v.tower_delta:
        v.skippable_layer[0] = False
        if skippable > 0:
            gui.log_warning(
                "TOWERDELTA in effect for {} Layers or {:.2f}mm".format(
                    skippable, skippable * v.layer_height))
        else:
            gui.create_logitem("TOWERDELTA could not be applied to this print")
            v.tower_delta = False

    return 0
Пример #19
0
def check_config_parameters(keyword, value):
    keyword = keyword.upper().strip()

    if value is None:
        value = ""

    # allows for delaying the change of temperature until after the putge block
    # not sure if this should stay in future releases.   To be evaluated
    #  low complexity, but it adds a waiting position calculation which moves off the regular path.
    if keyword == "TEMPERATURECONTROL":
        v.process_temp = True

    # saves the unprocessed file, so it can be sent for processing simulation in case of errors
    if keyword == "SAVEUNPROCESSED":
        v.save_unprocessed = True

    # enable the preheat function on the Palette 3
    if keyword == "P3_PROCESSPREHEAT":
        v.p3_process_preheat = True

    # defines the printer profile for config storage on the Palette hardware
    if keyword == "PRINTERPROFILE":
        value = value.strip(" ")
        _idlen = 16
        if v.palette3:
            _idlen = 32

        if len(value) != _idlen:
            gui.log_warning(
                "Invalid Printer profile!  - Has invalid length (expect {}) - [{}]"
                .format(_idlen, value))
            value = ""

        if not all(char in set("0123456789ABCDEFabcdef") for char in value):
            gui.log_warning(
                "Invalid Printer profile!  - Invalid characters  (expect 0123456789abcdef) - [{}]"
                .format(value))
            value = ""

        if len(value) <= _idlen:
            v.printer_profile_string = value
            return

    # toggles hardware to Palette 3 - sets the number of inputs, output format.
    if keyword == "PALETTE3":
        if len(v.printer_profile_string) == 16:
            gui.log_warning(
                "Invalid Printer profile!  - P3 printer profile should be 32 characters ({})"
                .format(v.printer_profile_string))

        v.palette3 = True
        v.colors = 4
        # Min first splice length for P3 == 130
        v.min_start_splice_length = max(v.min_start_splice_length,
                                        v.min_first_splice_p3)
        v.min_splice_length = max(v.min_splice_length, v.min_splice_p3)
        check_splice_table()
        return

    # toggles hardware to Palette 3 Pro - sets the number of inputs, output format.
    if keyword == "PALETTE3_PRO":
        if len(v.printer_profile_string) == 16:
            gui.log_warning(
                "Invalid Printer profile!  - P3 printer profile should be 32 characters"
            )

        v.palette3 = True
        v.colors = 8
        # Min first splice length for P3 == 130
        v.min_start_splice_length = max(v.min_start_splice_length,
                                        v.min_first_splice_p3)
        v.min_splice_length = max(v.min_splice_length, v.min_splice_p3)
        check_splice_table()
        return

    if keyword == "P3_HOSTNAME":
        v.p3_hostname = value

    if keyword == "P3_PROFILENAME":
        v.p3_printername = value

    if keyword == "P3_UPLOADFILE":
        v.uploadfile = True

    if keyword == "P3_SHOWPRINTERPAGE":
        v.showwebbrowser = True

    # toggles Palette 3 accessory mode = added 22/02/2022
    if keyword == "ACCESSORYMODE_MAFX":
        v.accessory_mode = True
        gui.create_logitem("Config: Palette3 Accessory Mode Selected")
        return

    # toggles Palette 2 accessory mode
    if keyword == "ACCESSORYMODE_MAF":
        v.accessory_mode = True
        v.colors = 4
        gui.create_logitem("Config: Palette2 Accessory Mode Selected")
        check_splice_table()
        return

    # toggles Palette + Accessory Mode
    if keyword == "ACCESSORYMODE_MSF":
        v.accessory_mode = True
        v.palette_plus = True
        v.colors = 4
        gui.create_logitem("Config: Palette+ Accessory Mode Selected")
        check_splice_table()
        return

    # Loading Offset - Required for the P+ configuration, take from existing print after callibration with Chroma
    if keyword == "P+LOADINGOFFSET":
        v.palette_plus_loading_offset = int(float(value))
        return

    # PPM  - Required for the P+ configuration, take from existing print after callibration with Chroma
    if keyword == "P+PPM":
        v.palette_plus_ppm = floatparameter(value)
        return

    # Splice offset defines how much the start of the toolchange is located after the position of the toolchange.
    # in general, you want this value as small as possible BUT this value is the buffer you need when material is consumed
    # at a too high rate, so putting it very low may result in early transition
    if keyword == "SPLICEOFFSET":
        v.splice_offset = floatparameter(value)
        gui.create_logitem("SPLICE OFFSET: {:-5.2f}mm".format(v.splice_offset))
        return

    # This parameter sets the amount of extra filament that is generated at the end of the print, to allow for the filament to still
    # engage with the motor gears.   This should be at least the plength of the path from the nozzel to the gears of the extruder motor
    if keyword == "EXTRAENDFILAMENT":
        v.extra_runout_filament = floatparameter(value)
        gui.create_logitem("Extra filament at end of print {:-8.2f}mm".format(
            v.extra_runout_filament))
        return

    # This parameter specified the minimal amount of total filament  USE ???
    if keyword == "P3_MINIMALTOTALFILAMENT":
        v.minimaltotal_filament = floatparameter(value)
        gui.create_logitem("Minimal ilament length {:-8.2f}mm".format(
            v.minimaltotal_filament))
        return

    # Specially Added for Manmeet - Not  documented
    if keyword == "MANUAL_SWAP":
        v.manual_filament_swap = True
        gui.create_logitem("Manual filament swap in place.")
        return

    # May be removed ??
    if keyword == "BEFORESIDEWIPEGCODE":
        v.before_sidewipe_gcode.append(value)
        return

    # May be removed ??
    if keyword == "AFTERSIDEWIPEGCODE":
        v.after_sidewipe_gcode.append(value)
        return

    # unused ???
    if keyword == "AUTOLOADINGOFFSET":
        v.autoloadingoffset = floatparameter(value)
        return

    # autmoaticall adds purge in case of short splices when fullpruereduction is applied
    if keyword == "AUTOADDPURGE":
        v.autoaddsplice = True
        return

    # special reauest feature - not documents - allows for pings shorter than 300 mm
    if keyword == "POWERCHAOS":  # Special feature request to allow sub 300 mm pings
        v.powerchaos = True
        return

    # sets the minimal first splice length (100 / 130 for P2/P3 resp)
    if keyword == "MINSTARTSPLICE":
        v.min_start_splice_length = floatparameter(value)
        if v.palette3:
            if v.min_start_splice_length < v.min_first_splice_p3:
                gui.log_warning(
                    "Minimal first slice length adjusted to {}mm for palette 3"
                    .format(v.min_first_splice_p3))
                v.min_start_splice_length = v.min_first_splice_p3

        if v.min_start_splice_length < 100:
            v.min_start_splice_length = 100
            gui.log_warning("Minimal first slice length adjusted to 100mm")
        return

    # firmware purge support
    if keyword == "FIRMWARE_PURGE_LENGTH":
        v.firmwarepurge = intparameter(value)
        return

    # SECTION BLOBSTER and BB3D

    # BB3D/BLOBSTER config parm
    if keyword in ["BIGBRAIN3D_BLOBSIZE", "BLOBSTER_BLOBSIZE"]:
        v.mechpurge_blob_size = intparameter(value)
        return

    # BLOBSTER config parm
    if keyword in ["BLOBSTER_ENGAGETIME"]:
        v.blobster_engagetime = intparameter(value)
        return

    # BB3D config parm
    if keyword == "BIGBRAIN3D_SINGLEBLOB":
        v.single_blob = True
        return

    # BB3D/blobster config parm
    if keyword in ["BIGBRAIN3D_BLOBSPEED", "BLOBSTER_BLOBSPEED"]:
        v.mechpurge_blob_speed = intparameter(value)
        return

    # BB3D/blobster config parm
    if keyword in ["BIGBRAIN3D_COOLINGTIME", "BLOBSTER_COOLINGTIME"]:
        v.mechpurge_blob_cooling_time = intparameter(value)
        return

    # BB3D/blobster config parm
    if keyword in ["BIGBRAIN3D_PURGEPOSITION", "BLOBSTER_PURGEPOSITION"]:
        v.mechpurge_x_position = floatparameter(value)
        return

    # BB3D config parm
    if keyword == "BIGBRAIN3D_PURGEYPOSITION":
        v.bigbrain3d_y_position = floatparameter(value)
        return

    # BB3D config parm
    if keyword == "BIGBRAIN3D_MOTORPOWER_HIGH":
        v.bigbrain3d_motorpower_high = intparameter(value)
        return

    # BB3D config parm
    if keyword == "BIGBRAIN3D_MOTORPOWER_NORMAL":
        v.bigbrain3d_motorpower_normal = intparameter(value)
        return

    # BB3D config parm
    if keyword == "BIGBRAIN3D_NUMBER_OF_WHACKS":
        v.bigbrain3d_whacks = intparameter(value)
        return

    # BB3D config parm
    if keyword in ["BIGBRAIN3D_PRIME_BLOBS", "BLOBSTER_PRIME_BLOBS"]:
        v.mechpurge_prime_blobs = intparameter(value)
        return

    # BB3D config parm
    if keyword == "BIGBRAIN3D_FAN_OFF_PAUSE":
        v.bigbrain3d_fanoffdelay = intparameter(value)
        return

    # BB3D config parm
    if keyword == "BIGBRAIN3D_LEFT_SIDE":
        v.bigbrain3d_left = -1
        return

    # BB3D/BLOBSTER config parm
    if keyword in ["BIGBRAIN3D_CLEARANCE_MM", "BLOBSTER_CLEARANCE_MM"]:
        v.mechpurge_minimalclearenceheight = floatparameter(value)
        return

    # BB3D/BLBSTER config parm
    if keyword in ["BIGBRAIN3D_RETRACT", "BLOBSTER_RETRACT"]:
        v.mechpurge_retract = floatparameter(value)
        return

    # BB3D/BLOBSTER config parm
    if keyword == "BIGBRAIN3D_ENABLE":
        if not v.wipe_remove_sparse_layers:
            v.bigbrain3d_purge_enabled = True
            gui.create_logitem(
                "<b>BIGBRAIN3D Will only work with installed hardware on a Prusa Printer</b>"
            )
        else:
            gui.log_warning(
                "<b>BIGBRAIN3D mode not compatible with sparse wipe tower in PS</b>"
            )
        return

    if keyword == "BLOBSTER_ADVANCED":
        v.blobster_advanced = True
        gui.create_logitem("<b>BLOBSTER ADVANCED MODE ENABLED</b>")
        return

    if keyword == "BLOBSTER_ADVANCED_LENGTH":
        v.blobster_advanced_length = []
        fields = value.split(",")
        for i in fields:
            try:
                v.blobster_advanced_length.append(abs(int(i)))
            except ValueError:
                gui.log_warning(
                    "BLOBSTER_ADVANCED_LENGTH parameter accepts a list of interger values (length in mm)"
                )
        return

    if keyword == "BLOBSTER_ADVANCED_SPEED":
        v.blobster_advanced_speed = []
        fields = value.split(",")
        for i in fields:
            try:
                v.blobster_advanced_speed.append(abs(int(i)))
            except ValueError:
                gui.log_warning(
                    "BLOBSTER_ADVANCED_SPEEDH parameter accepts a list of interger values (length in mm)"
                )
        return

    if keyword == "BLOBSTER_ADVANCED_FAN":
        v.blobster_advanced_fan = []
        fields = value.split(",")
        for i in fields:
            try:
                v.blobster_advanced_fan.append(
                    int(min(abs(int(i)), 100) * 2.55))
            except ValueError:
                gui.log_warning(
                    "BLOBSTER_ADVANCED_FAN parameter accepts a list of interger values (percentage 0-100)"
                )
        return

    # BB3D/BLOBSTER config parm
    if keyword == "BLOBSTER_ENABLE":
        if not v.wipe_remove_sparse_layers:
            v.blobster_purge_enabled = True
            v.mechpurge_blob_size = 180
            v.mechpurge_minimalclearenceheight = 30
            v.mechpurge_blob_cooling_time = 60

            gui.create_logitem(
                "<b>BLOBSTER Will only work with installed hardware on a Prusa Printer</b>"
            )
        else:
            gui.log_warning(
                "<b>BLOBSTER mode not compatible with sparse wipe tower in PS</b>"
            )
        return

    # BB3D/BLOBSTER config parm
    if keyword in ["BIGBRAIN3D_SMARTFAN", "BLOBSTER_SMARTFAN"]:
        v.mechpurge_smartfan = True
        return

    # defines the minimal splice length ( this is the safe length to make sure a splice is only heated once (70/90 for P2/P3 resp)
    if keyword == "MINSPLICE":
        v.min_splice_length = floatparameter(value)
        if v.palette3:
            if v.min_splice_length < v.min_splice_p3:
                gui.log_warning(
                    "Minimal slice length adjusted to {}mm for palette 3".
                    format(v.min_splice_p3))
                v.min_splice_length = v.min_splice_p3

        if v.min_splice_length < 70:
            v.min_splice_length = 70
            gui.log_warning("Minimal slice length adjusted to 70mm")
        return

    # LINEAR PING removed

    # set the distance between pings (same length every time), instead of increasing ping lengths
    if keyword == "LINEARPINGLENGTH":
        v.ping_interval = floatparameter(value)
        v.ping_length_multiplier = 1.0
        if not v.powerchaos:
            if v.ping_interval < 100:
                v.ping_interval = 100
                gui.log_warning(
                    "Minimal Linear Ping distance is 300mm!  Your config stated: {}"
                    .format(value))
            gui.create_logitem("Linear Ping interval of  {:-6.2f}mm".format(
                v.ping_interval))
        return

    # Set the location for the side wipes
    if keyword == "SIDEWIPELOC":
        v.side_wipe_loc = value
        return

    # define a Z-Hop for jumps to the wipe location
    if keyword == "SIDEWIPEZHOP":
        v.addzop = floatparameter(value)
        gui.create_logitem("Side Wipe ZHOP of {:3.2f}mm".format(v.addzop))

    # maybe removed??
    if keyword == "SIDEWIPEZHOP_SKIPRETURN":
        v.sidewipe_delay_zreturn = True

    # set the highest top speed for purging
    if keyword == "PURGETOPSPEED":
        v.purgetopspeed = int(floatparameter(value))

        # if parameter specified is below 200 then the value is assumed mm/sec and is converted to mm/min
        if v.purgetopspeed < 200:
            v.purgetopspeed = v.purgetopspeed * 60

        gui.create_logitem(
            "Purge Max speed set to {:.0f}mm/min ({}mm/s)".format(
                v.purgetopspeed, v.purgetopspeed / 60))
        return

    # set the wipe feedrate
    if keyword == "WIPEFEEDRATE":
        v.wipe_feedrate = floatparameter(value)
        return

    # define the sidewipe minimal and macimal Y position
    if keyword == "SIDEWIPEMINY":
        v.sidewipe_miny = floatparameter(value)
        return

    # define the sidewipe minimal and macimal Y position
    if keyword == "SIDEWIPEMAXY":
        v.sidewipe_maxy = floatparameter(value)
        return

    # define a extrusion multiplier for sidewipe.  needed???
    if keyword == "SIDEWIPECORRECTION":
        v.sidewipe_correction = floatparameter(value)
        if v.sidewipe_correction < 0.9 or v.sidewipe_correction > 1.10:
            v.sidewipe_correction = 1.0
        return

    # apply delta (similar to sparse layer removal in PS2.4
    if keyword == "PURGETOWERDELTA":
        parm = abs(floatparameter(value))
        if parm > 0.001 and v.wipe_remove_sparse_layers:
            gui.log_warning(
                "TOWER DELTA feature mode not compatible with sparse wipe tower in PS"
            )
            v.max_tower_delta = 0.0
        else:
            if parm != float(0):
                v.max_tower_z_delta = abs(floatparameter(value))
                gui.create_logitem(
                    "Max Purge Tower Delta set to {:-2.2f}mm".format(
                        v.max_tower_z_delta))
        return

    # simlir to tower delta but rather reduces the base of the tower to make it growmore evenly with the print
    if keyword == "FULLPURGEREDUCTION":
        if not v.wipe_remove_sparse_layers:
            gui.create_logitem("Full purge reduction configured")
            v.full_purge_reduction = True
            v.needpurgetower = True
        else:
            gui.log_warning(
                "FULL PURGE TOWER REDUCTION feature mode not compatible with sparse wipe tower in PS"
            )
            v.full_purge_reduction = False
        return

    # chech the version of P2PP on startup (requires an internet connection)
    if keyword == "CHECKVERSION":
        import p2pp.checkversion as cv
        import version
        latest = cv.get_version(cv.MASTER)
        if latest:
            if latest > version.Version:
                gui.create_logitem(
                    "New version of P2PP available ({})".format(latest), "red",
                    False, "2.0")

    # co be removed ?
    if keyword == "DO_NOT_GENERATE_M0":
        v.generate_M0 = False
        return

    # wait for user feedback at the ned of processing
    if keyword == "CONSOLEWAIT":
        v.consolewait = True
        return

    if keyword == "FINISH_MOVES_M400":
        v.finish_moves = "M400"
        v.replace_G4S0 = True

    # process toolchanges the KLIPPER way
    if keyword == "KLIPPER_TOOLCHANGE":
        v.klipper = True
        return

    # close and continue even if there are warnings
    if keyword == "IGNOREWARNINGS":
        v.ignore_warnings = True
        return

    # p2pp_process_file a gcode file with absolute extrusios instead of relative ones
    if keyword == "ABSOLUTEEXTRUDER":
        v.absolute_extruder = True
        gui.create_logitem("Convert to absolute extrusion parameters")
        return

    # unused !!! to be removed.
    if keyword == "DEBUGTCOMMAND":
        v.debug_leaveToolCommands = True
        gui.log_warning(
            "DEBUGTCOMMAND ACTIVE - File will not print correctly!!")
        return
Пример #20
0
def check_splice_table():
    if len(v.splice_algorithm_table) > 0:
        gui.log_warning(
            "Algorithm definitions should appear AFTER Palette Model selection (PALETTE3/PALETTE3_PRO/ACCESSORYMODE_MAF/ACCESSORYMODE_MSF)"
        )
Пример #21
0
def generate(input_file, output_file, printer_profile, splice_offset, silent):
    starttime = time.time()
    v.printer_profile_string = printer_profile
    basename = os.path.basename(input_file)
    _taskName = os.path.splitext(basename)[0].replace(" ", "_")
    _taskName = _taskName.replace(".mcf", "")

    v.splice_offset = splice_offset

    try:
        # python 3.x
        opf = open(input_file, encoding='utf-8')
    except TypeError:
        try:
            # python 2.x
            opf = open(input_file)
        except IOError:
            if v.gui:
                gui.user_error("P2PP - Error Occurred", "Could not read input file\n'{}'".format(input_file))
            else:
                print ("Could not read input file\n'{}".format(input_file))
            return
    except IOError:
        if v.gui:
            gui.user_error("P2PP - Error Occurred", "Could not read input file\n'{}'".format(input_file))
        else:
            print ("Could not read input file\n'{}".format(input_file))
        return

    gui.setfilename(input_file)
    gui.set_printer_id(v.printer_profile_string)
    gui.create_logitem("Reading File " + input_file)
    gui.progress_string(1)

    v.input_gcode = opf.readlines()
    opf.close()

    v.input_gcode = [item.strip() for item in v.input_gcode]

    gui.create_logitem("Analyzing slicer parameters")
    gui.progress_string(2)
    parse_slic3r_config()

    gui.create_logitem("Pre-parsing GCode")
    gui.progress_string(4)
    parse_gcode()

    if v.tower_delta or v.full_purge_reduction:
        if v.variable_layer:
            gui.log_warning("Variable layers are not compatible with fullpruge/tower delta")

    if v.process_temp and v.side_wipe:
        gui.log_warning("TEMPERATURECONTROL and Side Wipe / BigBrain3D are not compatible")

    if v.palette_plus:
        if v.palette_plus_ppm == -9:
            gui.log_warning("P+ parameter P+PPM not set correctly in startup GCODE")
        if v.palette_plus_loading_offset == -9:
            gui.log_warning("P+ parameter P+LOADINGOFFSET not set correctly in startup GCODE")

    v.side_wipe = not coordinate_on_bed(v.wipetower_posx, v.wipetower_posy)
    v.tower_delta = v.max_tower_z_delta > 0

    gui.create_logitem("Creating tool usage information")
    m4c.calculate_loadscheme()


    if v.side_wipe:

        if v.skirts and v.ps_version > "2.2":
            gui.log_warning("SIDEWIPE and SKIRTS are NOT compatible in PS2.2 or later")
            gui.log_warning("THIS FILE WILL NOT PRINT CORRECTLY")

        if v.wipe_remove_sparse_layers:
            gui.log_warning("SIDE WIPE mode not compatible with sparse wipe tower in PS")
            gui.log_warning("THIS FILE WILL NOT PRINT CORRECTLY")

        gui.create_logitem("Side wipe activated", "blue")
        if v.full_purge_reduction:
            gui.log_warning("Full Purge Reduction is not compatible with Side Wipe, performing Side Wipe")
            v.full_purge_reduction = False



    if v.full_purge_reduction:
        v.side_wipe = False
        gui.create_logitem("Full Tower Reduction activated", "blue")
        if v.tower_delta:
            gui.log_warning("Full Purge Reduction is not compatible with Tower Delta, performing Full Purge Reduction")
            v.tower_delta = False

    v.pathprocessing = (v.tower_delta or v.full_purge_reduction or v.side_wipe)

    if v.autoaddsplice and not v.full_purge_reduction and not v.side_wipe:
        gui.log_warning("AUTOEDDPURGE only works with side wipe and fullpurgereduction at this moment")

    if (len(v.skippable_layer) == 0) and v.pathprocessing:
        gui.log_warning("LAYER configuration is missing. NO OUTPUT FILE GENERATED.")
        gui.log_warning("Check the P2PP documentation for furhter info.")
    else:

        if v.tower_delta:
            optimize_tower_skip(v.max_tower_z_delta, v.layer_height)

        if v.side_wipe:
            optimize_tower_skip(999, v.layer_height)

        gui.create_logitem("Generate processed GCode")

        total_line_count = len(v.input_gcode)
        v.retraction = 0
        for process_line_count in range(total_line_count):
            gcode_parseline(process_line_count)
            gui.progress_string(50 + 50 * process_line_count // total_line_count)

        v.processtime = time.time() - starttime

        gcode_process_toolchange(-1, v.total_material_extruded, 0)
        omega_result = header_generate_omega(_taskName)
        header = omega_result['header'] + omega_result['summary'] + omega_result['warnings']

        if v.absolute_extruder and v.gcode_has_relative_e:
            gui.create_logitem("Converting to absolute extrusion")
            convert_to_absolute()

        # write the output file
        ######################

        if not output_file:
            output_file = input_file
        gui.create_logitem("Generating GCODE file: " + output_file)
        opf = open(output_file, "w")
        if not v.accessory_mode:
            opf.writelines(header)
            opf.write("\n\n;--------- START PROCESSED GCODE ----------\n\n")
        if v.accessory_mode:
            opf.write("M0\n")
            opf.write("T0\n")

        if v.splice_offset == 0:
            gui.log_warning("SPLICE_OFFSET not defined")
        opf.writelines(v.processed_gcode)
        opf.close()

        if v.accessory_mode:

            pre, ext = os.path.splitext(output_file)
            if v.palette_plus:
                maffile = pre + ".msf"
            else:
                maffile = pre + ".maf"
            gui.create_logitem("Generating PALETTE MAF/MSF file: " + maffile)


            maf = open(maffile, 'w')

            for h in header:
                h = h.strip('\r\n')
                maf.write(unicode(h))
                maf.write('\r\n')
            maf.close()
            #
            # with io.open(maffile, 'w', newline='\r\n') as maf:
            #
            #     for i in range(len(header)):
            #         h = header[i].strip('\n\r') + "\n"
            #         if not h.startswith(";"):
            #             try:
            #                 maf.write(unicode(h))
            #             except:
            #                 maf.write(h)


        gui.print_summary(omega_result['summary'])

    gui.progress_string(100)
    if (len(v.process_warnings) > 0 and not v.ignore_warnings) or v.consolewait:
        gui.close_button_enable()
Пример #22
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)
Пример #23
0
def header_generate_omega_palette2(job_name):
    header = []
    summary = []
    warnings = []

    header.append('O21 ' + hexify_short(20) + "\n")  # MSF2.0

    if v.printer_profile_string == '':
        v.printer_profile_string = v.default_printerprofile
        gui.log_warning(
            "No or Invalid Printer profile ID specified\nusing default P2PP printer profile ID {}"
            .format(v.default_printerprofile))

    header.append('O22 D' + v.printer_profile_string.strip("\n") +
                  "\n")  # PRINTERPROFILE used in Palette2
    header.append('O23 D0001' + "\n")  # unused
    header.append('O24 D0000' + "\n")  # unused

    str = "O25"

    initools = v.m4c_loadedinputs[0]

    if len(initools) < 4:
        if v.m4c_numberoffilaments == 4:
            initools = [0, 1, 2, 3]
            for i in range(4):
                if not v.palette_inputs_used[i]:
                    initools[i] = -1
        else:
            while len(initools) < 4:
                initools.append(-1)

    for i in initools:
        if i != -1:

            str += " D{}{}{}{}".format(
                v.used_filament_types.index(v.filament_type[i]) + 1,
                v.filament_color_code[i].strip("\n"),
                find_nearest_colour(v.filament_color_code[i].strip("\n")),
                v.filament_type[i].strip("\n"))
        else:
            str += (" D0")

    header.append(str + "\n")

    header.append('O26 ' + hexify_short(len(v.splice_extruder_position)) +
                  "\n")
    header.append('O27 ' + hexify_short(len(v.ping_extruder_position)) + "\n")
    if len(v.splice_algorithm_table) > 9:
        header.append("O28 D{:0>4d}\n".format(len(v.splice_algorithm_table)))
    else:
        header.append('O28 ' + hexify_short(len(v.splice_algorithm_table)) +
                      "\n")
    header.append('O29 ' + hexify_short(v.hotswap_count) + "\n")

    for i in range(len(v.splice_extruder_position)):
        if v.accessory_mode:
            header.append("O30 D{:0>1d} {}\n".format(
                v.splice_used_tool[i],
                hexify_float(v.splice_extruder_position[i])))
        else:
            header.append("O30 D{:0>1d} {}\n".format(
                v.splice_used_tool[i],
                hexify_float(v.splice_extruder_position[i] +
                             v.autoloadingoffset)))

    if v.accessory_mode:
        for i in range(len(v.ping_extruder_position)):
            header.append("O31 {} {}\n".format(
                hexify_float(v.ping_extruder_position[i]),
                hexify_float(v.ping_extrusion_between_pause[i])))

    for i in range(len(v.splice_algorithm_table)):
        header.append("O32 {}\n".format(v.splice_algorithm_table[i]))

    if v.m4c_numberoffilaments > 4:
        v.m4c_headerinfo = m4c.generate_warninglist()
        for i in v.m4c_headerinfo:
            header.append(i + "\n")

    if v.autoloadingoffset > 0:
        header.append("O40 D{}".format(v.autoloadingoffset))
    else:
        v.autoloadingoffset = 0

    if not v.accessory_mode:
        if len(v.splice_extruder_position) > 0:
            header.append("O1 D{} {}\n".format(
                job_name,
                hexify_long(
                    int(v.splice_extruder_position[-1] + 0.5 +
                        v.autoloadingoffset))))
        else:
            header.append("O1 D{} {}\n".format(
                job_name,
                hexify_long(
                    int(v.total_material_extruded + 0.5 +
                        v.autoloadingoffset))))

        header.append("M0\n")
        header.append("T0\n")
        summary = generatesummary()
        warnings = generatewarnings()

    return {'header': header, 'summary': summary, 'warnings': warnings}
Пример #24
0
def parse_config_parameters():

    # TODO - get this information from the environment parameters
    # TODO - need to find out as from what version of PS this is working

    for idx in range(len(v.input_gcode) - 1, -1, -1):

        gcode_line = v.input_gcode[idx]

        if gcode_line.startswith("; estimated printing time"):
            try:
                fields = gcode_line.split("=")
                fields = fields[-1].split(" ")
                for i in range(len(fields)):
                    fields[i] = "0" + fields[i].strip('hms')

                if len(fields) > 2:
                    h = int(fields[-3])
                else:
                    h = 0

                if len(fields) > 1:
                    m = int(fields[-2])
                else:
                    m = 0

                if len(fields) > 0:
                    s = int(fields[-1])
                else:
                    s = 0

                v.printing_time = h * 3600 + m * 60 + s

            except (ValueError, IndexError):
                pass
            return

        if gcode_line.startswith("; filament_settings_id"):
            v.filament_ids = split_csv_strings(gcode_line)

        if "generated by PrusaSlicer" in gcode_line:
            try:
                s1 = gcode_line.split("+")
                s2 = s1[0].split(" ")
                v.ps_version = s2[-1]
                gui.create_logitem(
                    "File was created with PS version:{}".format(v.ps_version))
                if v.ps_version < "2.2":
                    gui.create_logitem(
                        "<b>This version of P2PP is optimized to work with PS2.2 and higher!<b>"
                    )
            except (ValueError, IndexError):
                pass
            continue

        if gcode_line.startswith("; single_extruder_multi_material_priming"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                try:
                    if int(gcode_line[parameter_start + 1:].strip()) == 1:
                        gui.log_warning(
                            "[Print Settings][Multiple Extruders][Wipe Tower]Prime all printing extruders MUST be turned off"
                        )
                        gui.log_warning("THIS FILE WILL NOT PRINT CORRECTLY")
                except (ValueError, IndexError):
                    pass
            continue

        if gcode_line.startswith("; wipe_tower_no_sparse_layers"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                try:
                    v.wipe_remove_sparse_layers = (int(
                        gcode_line[parameter_start + 1:].strip()) == 1)
                except (ValueError, IndexError):
                    pass
            continue

        if gcode_line.startswith("; variable_layer_height"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.variable_layer = int(gcode_line[parameter_start +
                                                  1:].strip()) == 1
            continue

        if gcode_line.startswith("; bed_shape") and not v.bed_shape_warning:
            get_bedshape(gcode_line)

        if gcode_line.startswith("; first_layer_temperature"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                try:
                    temps = gcode_line[parameter_start + 1:].strip().split(",")
                    v.p3_printtemp = []
                    for i in range(len(temps)):
                        v.p3_printtemp.append(int(temps[i]))
                except (IndexError, ValueError):
                    v.p3_printtemp = [0, 0, 0, 0, 0, 0, 0, 0]

        if gcode_line.startswith("; first_layer_bed_temperature"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                try:
                    temps = gcode_line[parameter_start + 1:].strip().split(",")
                    v.p3_bedtemp = []
                    for i in range(len(temps)):
                        v.p3_bedtemp.append(int(temps[i]))
                except (IndexError, ValueError):
                    v.p3_bedtemp = [0, 0, 0, 0, 0, 0, 0, 0]

        if gcode_line.startswith("; max_print_height"):

            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.z_maxheight = float(gcode_line[parameter_start + 1:].strip())
            continue

        if gcode_line.startswith("; wipe_tower_x"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.wipe_tower_posx = float(gcode_line[parameter_start +
                                                     1:].strip())
            continue

        if gcode_line.startswith("; min_skirt_length"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.skirtsize = float(gcode_line[parameter_start + 1:].strip())
            continue

        if gcode_line.startswith("; skirts"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.skirts = float(gcode_line[parameter_start + 1:].strip())
            continue

        if gcode_line.startswith("; wipe_tower_width"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.wipe_tower_width = float(gcode_line[parameter_start +
                                                      1:].strip())
            continue

        if gcode_line.startswith("; wipe_tower_y"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.wipe_tower_posy = float(gcode_line[parameter_start +
                                                     1:].strip())
            continue

        if gcode_line.startswith("; extrusion_width"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                parm = gcode_line[parameter_start + 1:].strip()

                if len(parm) == 0:
                    gui.log_warning(
                        "extrusion width parameter does not contain any values FULL PURGE REDUCTION will not work"
                    )
                    gui.log_warning(
                        "Please manually set the values for default extrusion (Print Settings/Advanced/Extrusion Width to resolve"
                    )
                    continue

                if parm[-1] == "%":
                    parm = parm.replace("%", "").strip()
                    tmpval = float(parm)
                    v.extrusion_width = v.nozzle_diameter * tmpval / 100.0
                else:
                    v.extrusion_width = float(gcode_line[parameter_start +
                                                         1:].strip())

                v.tx_offset = 2 + 4 * v.extrusion_width
                v.yy_offset = 2 + 8 * v.extrusion_width
            continue

        if gcode_line.startswith("; infill_speed"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.infill_speed = float(
                    gcode_line[parameter_start + 1:].strip()) * 60
            continue

        if gcode_line.startswith("; layer_height"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.layer_height = float(gcode_line[parameter_start +
                                                  1:].strip())
            continue

        # this next function assumes that the parameters are stored in alphabetical order
        # so layer_height is defined BEFORE first layer height when parsing back to front
        if gcode_line.startswith("; first_layer_height"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                value = gcode_line[parameter_start + 1:].strip()
                if value[-1] == "%":
                    v.first_layer_height = float(
                        value[:-1]) / 100.0 * v.layer_height
                else:
                    v.first_layer_height = float(value)
            continue

        if gcode_line.startswith("; support_material_synchronize_layers"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                tmp = float(gcode_line[parameter_start + 1:].strip())
                v.synced_support = tmp == 1
            continue

        if gcode_line.startswith("; support_material "):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                tmp = float(gcode_line[parameter_start + 1:].strip())
                v.support_material = tmp == 1
            continue

        if gcode_line.startswith("; nozzle_diameter "):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                tmp = gcode_line[parameter_start + 1:].strip().split(",")
                tmp = float(tmp[0])

                v.nozzle_diameter = tmp
            continue

        if gcode_line.startswith("; start_filament_gcode "):
            parameter_start = gcode_line.find("=")
            gcode_value = gcode_line[parameter_start + 2:].strip()
            fields = split_csv_strings(gcode_value)
            for i in range(len(fields)):
                lines = fields[0].split("\\n")
                for line in lines:
                    if line.startswith(";P2PP PROFILETYPEOVERRIDE="):
                        value = line[26:]
                        v.filament_type[i] = value
                        v.used_filament_types.append(v.filament_type[i])
                        v.used_filament_types = list(
                            dict.fromkeys(v.used_filament_types))
            continue

        if gcode_line.startswith("; start_gcode "):
            parameter_start = gcode_line.find("=")
            gcode_value = gcode_line[parameter_start + 2:].strip()
            lines = gcode_value.split("\\n")
            for line in lines:
                m = v.regex_p2pp.match(line)
                if m:
                    if m.group(1).startswith("MATERIAL"):
                        algorithm_process_material_configuration(
                            m.group(1)[9:])
                    else:
                        parameters.check_config_parameters(
                            m.group(1), m.group(2))

            if v.blobster_advanced:
                if len(v.blobster_advanced_speed) == 0:
                    gui.log_warning(
                        "BLOBSTER - Advanced mode required BLOBSTER_ADVANCED_SPEED parameter"
                    )
                if len(v.blobster_advanced_fan) == 0:
                    gui.log_warning(
                        "BLOBSTER - Advanced mode required BLOBSTER_ADVANCED_FAN parameter"
                    )
                if len(v.blobster_advanced_length) == 0:
                    gui.log_warning(
                        "BLOBSTER - Advanced mode required BLOBSTER_ADVANCED_LENGTH parameter"
                    )

                if len(v.blobster_advanced_speed) != len(
                        v.blobster_advanced_fan) or len(
                            v.blobster_advanced_speed) != len(
                                v.blobster_advanced_length):
                    gui.log_warning(
                        "BLOBSTER - Advanced mode - BLOBSTER_ADVANCED_LENGTH/FAN/SPEED parameter must have same number of parameters"
                    )

        if gcode_line.startswith("; extruder_colour") or gcode_line.startswith(
                "; filament_colour"):
            filament_colour = ''
            parameter_start = gcode_line.find("=")
            gcode_line = gcode_line[parameter_start + 1:].strip()
            parameter_start = gcode_line.find("#")
            if parameter_start != -1:
                filament_colour = gcode_line.split(";")
            v.filament_count = len(filament_colour)
            for i in range(v.filament_count):
                v.filament_color_code[i] = filament_colour[i][1:]

        if gcode_line.startswith("; filament_diameter"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                filament_diameters = gcode_line[parameter_start +
                                                1:].strip(" ").split(",")
                v.filament_diameter = [1.75] * max(len(filament_diameters), 4)
                for i in range(len(filament_diameters)):
                    v.filament_diameter[i] = float(filament_diameters[i])
            continue

        if gcode_line.startswith("; filament_type"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                filament_string = gcode_line[parameter_start +
                                             1:].strip(" ").split(";")
                for i in range(len(filament_string)):
                    if v.filament_type[i] != "":
                        filament_string[i] = v.filament_type[i]
                v.filament_type = filament_string
                v.used_filament_types = list(set(filament_string))
            continue

        if gcode_line.startswith("; retract_length = "):
            retract_error = False
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                retracts = gcode_line[parameter_start +
                                      1:].strip(" ").split(",")
                v.retract_length = [0.8] * max(len(retracts), v.colors)
                for i in range(len(retracts)):
                    v.retract_length[i] = float(retracts[i]) - 0.02
                    if v.retract_length[i] < 0.0:
                        retract_error = True
                        gui.log_warning(
                            "[Printer Settings]->[Extruders 1 -> {}]->[Retraction Length] should not be set to zero."
                            .format(i))
                    if retract_error:
                        gui.log_warning(
                            "Generated file might not print correctly")
            continue

        if gcode_line.startswith("; gcode_flavor"):
            if "reprap" in gcode_line:
                v.isReprap_Mode = True
            continue

        if "use_firmware_retraction" in gcode_line:
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                gcode_line = gcode_line[parameter_start + 1:].replace(";", "")
                if "1" in gcode_line:
                    gui.log_warning("Hardware retraction no longer supported")
            continue

        if "use_relative_e_distances" in gcode_line:
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                gcode_line = gcode_line[parameter_start + 1:].replace(";", "")
                if "1" not in gcode_line:
                    gui.log_warning(
                        "P2PP requires input file with RELATIVE extrusion")
            continue

        if gcode_line.startswith("; wiping_volumes_matrix"):
            wiping_info = []
            _warning = False
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                wiping_info = gcode_line[parameter_start +
                                         1:].strip(" ").split(",")
                _warning = True
                for i in range(len(wiping_info)):
                    if int(wiping_info[i]) != 140 and int(wiping_info[i]) != 0:
                        _warning = False
                    wiping_info[i] = float(wiping_info[i])

            v.max_wipe = max(wiping_info)
            v.bigbrain3d_matrix_blobs = v.max_wipe < 20
            if not v.bigbrain3d_matrix_blobs:
                map(filament_volume_to_length, wiping_info)
            else:
                gui.create_emptyline()
                gui.create_logitem("BigBrain3D BLOB transitions detected")
                color_table_size = int(math.sqrt(len(wiping_info)))
                header = "<table><tr><th>From\\To</th>"
                data = ""
                for i in range(color_table_size):
                    header = header + "<th>  Input {}  </th>".format(i)
                    data = data + "<tr><th>Input {}   </th>".format(i)
                    for j in range(color_table_size):
                        data = data + ("<td align=center>{}</td>".format(
                            int(wiping_info[j * color_table_size + i])))
                    data = data + "</tr>"

                header = header + "</tr>"
                data = data + "</table>"
                gui.create_logitem(header + data)

                gui.create_emptyline()

            v.wiping_info = wiping_info
            if _warning:
                gui.create_logitem(
                    "<b>All purge lenghths 70/70 OR 140.  Purge lengths may not have been set correctly.</b>"
                )
            continue
Пример #25
0
def gcode_process_toolchange(new_tool):
    if new_tool == v.current_tool:
        return

    location = v.total_material_extruded + v.splice_offset

    v.bigbrain3d_last_toolchange = v.current_tool * 10 + new_tool

    if new_tool == -1:  # LAST SLICE PROCESSING

        v.bigbrain3d_last_toolchange = -abs(v.bigbrain3d_last_toolchange)

        location += v.extra_runout_filament
        v.material_extruded_per_color[
            v.current_tool] += v.extra_runout_filament
        v.total_material_extruded += v.extra_runout_filament

        filldiff = v.minimaltotal_filament - v.total_material_extruded
        if filldiff > 0:
            gui.log_warning(
                "Minimum print size not met - adding {:-5.2f}.. of filament".
                format(filldiff))
            location += filldiff
            v.material_extruded_per_color[v.current_tool] += filldiff
            v.total_material_extruded += filldiff

    else:
        v.palette_inputs_used[new_tool] = True

    length = location - v.previous_toolchange_location

    if v.current_tool != -1:  # FIRST SLICE PROCESSING

        v.splice_extruder_position.append(location)
        v.splice_length.append(length)
        v.splice_used_tool.append(v.current_tool)

        if len(v.splice_extruder_position) == 1:
            min_length = v.min_start_splice_length
            gui_format = "SHORT FIRST SPLICE (min {}mm) Length:{:-3.2f} Input {}"
        else:
            min_length = v.min_splice_length
            gui_format = "SHORT SPLICE (min {}mm) Length:{:-3.2f} Layer:{} Input:{}"

        if v.splice_length[-1] < min_length:
            if v.autoaddsplice and (v.full_purge_reduction or v.side_wipe):
                v.autoadded_purge = v.min_start_splice_length - length
                v.side_wipe_length += v.autoadded_purge
                v.splice_extruder_position[
                    -1] += v.autoadded_purge * v.extrusion_multiplier
                v.splice_length[-1] += v.autoadded_purge
            else:
                gui.log_warning(
                    gui_format.format(min_length, length, v.last_parsed_layer,
                                      v.current_tool + 1))
                v.filament_short[new_tool] = max(
                    v.filament_short[new_tool],
                    v.min_start_splice_length - v.splice_length[-1])

        v.previous_toolchange_location = v.splice_extruder_position[-1]

    v.previous_tool = v.current_tool
    v.current_tool = new_tool
Пример #26
0
def parse_slic3r_config():
    for idx in range(len(v.input_gcode) - 1, -1, -1):

        gcode_line = v.input_gcode[idx]

        if gcode_line.startswith("G1"):
            break

        if gcode_line.startswith("; wipe_tower_x"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.wipetower_posx = float(gcode_line[parameter_start +
                                                    1:].strip())

        if gcode_line.startswith("; wipe_tower_width"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.wipetower_width = float(gcode_line[parameter_start +
                                                     1:].strip())

        if gcode_line.startswith("; wipe_tower_y"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.wipetower_posy = float(gcode_line[parameter_start +
                                                    1:].strip())

        if gcode_line.startswith("; extrusion_width"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.extrusion_width = float(gcode_line[parameter_start +
                                                     1:].strip())

        if gcode_line.startswith("; infill_speed"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.infill_speed = float(
                    gcode_line[parameter_start + 1:].strip()) * 60

        if gcode_line.startswith("; layer_height"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.layer_height = float(gcode_line[parameter_start +
                                                  1:].strip())

        if gcode_line.startswith("; extruder_colour") or gcode_line.startswith(
                "; filament_colour"):
            filament_colour = ''
            parameter_start = gcode_line.find("=")
            gcode_line = gcode_line[parameter_start + 1:].strip()
            parameter_start = gcode_line.find("#")
            if parameter_start != -1:
                filament_colour = gcode_line.split(";")
            if len(filament_colour) == 4:
                for i in range(4):
                    if filament_colour[i] == "":
                        filament_colour[i] = v.filament_color_code[i]
                    else:
                        v.filament_color_code[i] = filament_colour[i][1:]

        if gcode_line.startswith("; filament_diameter"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                filament_diameters = gcode_line[parameter_start +
                                                1:].strip(" ").split(",")
                if len(filament_diameters) == 4:
                    for i in range(4):
                        v.filament_diameter[i] = float(filament_diameters[i])

        if gcode_line.startswith("; filament_type"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                filament_string = gcode_line[parameter_start +
                                             1:].strip(" ").split(";")
                if len(filament_string) == 4:
                    v.filament_type = filament_string
                    v.used_filament_types = list(set(filament_string))
            continue

        if gcode_line.startswith("; retract_lift = "):
            if v.filament_list:
                continue
            lift_error = False
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                retracts = gcode_line[parameter_start +
                                      1:].strip(" ").split(",")
                if len(retracts) == 4:
                    for i in range(4):
                        v.retract_lift[i] = float(retracts[i])
                        if v.retract_lift[i] == 0:
                            lift_error = True
            continue

        if gcode_line.startswith("; retract_length = "):
            retract_error = False
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                retracts = gcode_line[parameter_start +
                                      1:].strip(" ").split(",")
                if len(retracts) == 4:
                    for i in range(4):
                        v.retract_length[i] = float(retracts[i])
                        if v.retract_length[i] == 0.0:
                            retract_error = True
            if retract_error:
                gui.log_warning(
                    "[Printer Settings]->[Extruders 1/2/3/4]->[Retraction Length] should not be set to zero."
                )
            continue

        if gcode_line.startswith("; gcode_flavor"):
            if "reprap" in gcode_line:
                v.isReprap_Mode = True

        if "use_firmware_retraction" in gcode_line:
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                gcode_line = gcode_line[parameter_start + 1:].replace(";", "")
                if "1" in gcode_line:
                    v.use_firmware_retraction = True
                else:
                    v.use_firmware_retraction = False

        if "use_relative_e_distances" in gcode_line:
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                gcode_line = gcode_line[parameter_start + 1:].replace(";", "")
                if "1" in gcode_line:
                    v.gcode_has_relative_e = True
                else:
                    v.gcode_has_relative_e = False

        if gcode_line.startswith("; wiping_volumes_matrix"):
            wiping_info = []
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                wiping_info = gcode_line[parameter_start +
                                         1:].strip(" ").split(",")
                if len(wiping_info) != 16:
                    continue
                for i in range(len(wiping_info)):
                    wiping_info[i] = filament_volume_to_length(
                        float(wiping_info[i]))
            v.max_wipe = max(wiping_info)
            if len(wiping_info) == 16:
                v.wiping_info = wiping_info
            continue
Пример #27
0
def uploadfile(localfile, p3file):
    global total_bytes
    _error = None

    v.retry_state = True

    # read file

    # check the size of the file to be sent:
    try:
        file_size = os.path.getsize(localfile)
        if file_size > 1 << 30:  #1GB
            gui.log_warning(
                "Filesize ({}) exceeds 1GB.  This file cannot be uploaded.".
                format(file_size))
            gui.log_warning(
                "Please use a memory stick to transfer files >1GB.")
            return
    except OSError:
        gui.log_warning(
            "Upload file does not seems to be ready for uploading (does not exists of is inaccessible)"
        )
        gui.log_warning("Please try uploading using a  memory stick.")
        return

    while v.p3_hostname == "":
        form.label_5.setText(
            "Please specify hostname or IP.\nP3_HOSTNAME config parameter missing."
        )
        form.RetryButton.setText("Upload")
        window.show()
        gui.app.exec()
        v.p3_hostname = form.hostname.text()
    else:
        form.hostname.setText(v.p3_hostname)

    form.RetryButton.setText("Retry")

    gui.create_logitem(
        "Sending file {}  to P3 ({})".format(p3file, v.p3_hostname), "blue",
        True)
    gui.app.sync()
    while v.retry_state:
        try:
            with open(localfile, "rb") as mcfx_file:
                gui.create_logitem("Uploading {}".format(p3file), "blue", True)
                encoder = MultipartEncoder({
                    'printFile':
                    (p3file, mcfx_file, "application/octet-stream"),
                })
                data = MultipartEncoderMonitor(encoder, callback)
                gui.create_logitem("|" + '.' * 50 + "|", "blue", True)
                total_bytes = encoder.len
                # data = {'printFile': (p3file, mcfx_file, "application/octet-stream")}
                url = "http://{}:5000/print-file".format(v.p3_hostname)

                response = requests.post(
                    url,
                    data=data,
                    headers={'Content-Type': data.content_type})
                if response.ok:
                    _error = None
                    v.retry_state = False
                    gui.create_logitem("Upload completed".format(p3file),
                                       "blue", True)
                else:
                    _error = "Error [{}] {} ".format(response.status_code,
                                                     response.reason)

        except Exception as e:
            print(e)
            gui.log_warning("Could not send file ({}) to P3 ({})".format(
                p3file, v.p3_hostname))
            gui.app.sync()
            _error = "Connection Error occurred!"

        if v.showwebbrowser and _error is None:
            try:
                tgtName = "http://{}:5000".format(v.p3_hostname)
                webform.webBrowser.load(QtCore.QUrl(tgtName))
                webwindow.show()
                gui.app.exec()

            except Exception as e:
                gui.logexception(e)

        if v.retry_state and _error is not None:
            form.label_5.setText(_error)
            window.show()
            gui.app.exec()
            v.p3_hostname = form.hostname.text()

    gui.close_button_enable()
Пример #28
0
def generate_palette():
    if v.accessory_mode:
        palette = {
            "version": "3.0",
            "drives": [],
            "splices": [],
            "pings": [],
            "pingCount": len(v.ping_extruder_position),
            "algorithms": []
        }
    else:
        palette = {
            "version": "3.0",
            "drives": [],
            "splices": [],
            "pingCount": len(v.ping_extruder_position),
            "algorithms": []
        }

    if len(v.splice_extruder_position) < 2:
        try:
            drive_used = v.splice_used_tool[0] + 1
        except IndexError:
            drive_used = 1

        palette["splices"] = [{
            "id":
            drive_used,
            "length":
            round(v.total_material_extruded + v.autoloadingoffset, 4)
        }]
        if v.colors == 4:
            palette["drives"] = [0, 0, 0, 0]
        else:
            palette["drives"] = [0, 0, 0, 0, 0, 0, 0, 0]
        palette["drives"][drive_used - 1] = drive_used
        palette["algorithms"].append({
            "ingoingId": drive_used,
            "outgoingId": drive_used,
            "heat": 0,
            "compression": 0,
            "cooling": 0
        })
    else:
        for i in range(len(v.splice_extruder_position)):
            palette["splices"].append({
                "id":
                v.splice_used_tool[i] + 1,
                "length":
                round(v.splice_extruder_position[i] + v.autoloadingoffset, 4)
            })

        splice_list = []
        palette["drives"] = []

        for i in range(v.colors):

            f_idx = 0
            if v.palette_inputs_used[i]:
                f_idx = i + 1

            palette["drives"].append(f_idx)

            for j in range(v.colors):
                if i == j:
                    continue
                try:
                    algo_key = "{}{}".format(
                        v.used_filament_types.index(v.filament_type[i]) + 1,
                        v.used_filament_types.index(v.filament_type[j]) + 1)
                    if algo_key in splice_list:
                        continue
                except (IndexError, KeyError):
                    continue

                if not algorithm_transition_used(i, j):
                    continue

                splice_list.append(algo_key)
                try:
                    algo = v.splice_algorithm_dictionary["{}{}".format(
                        v.filament_type[i], v.filament_type[j])]
                except (IndexError, KeyError):
                    algo = v.default_splice_algorithm
                    gui.log_warning(
                        "WARNING: No Algorithm defined for transitioning" +
                        " {} to {}. Using Default Splice Algorithm".format(
                            v.filament_type[i], v.filament_type[j]))
                try:
                    algin = int(algo_key[0])
                except ValueError:
                    algin = 0

                try:
                    algout = int(algo_key[1])
                except ValueError:
                    algout = 0

                palette["algorithms"].append({
                    "ingoingId": algin,
                    "outgoingId": algout,
                    "heat": algo[0],
                    "compression": algo[1],
                    "cooling": algo[2]
                })

    if v.accessory_mode:
        for i in range(len(v.ping_extruder_position)):
            palette["pings"].append({
                "length":
                v.ping_extruder_position[i],
                "extrusion":
                v.ping_extrusion_between_pause[i]
            })

    return json.dumps(palette, indent=2)
Пример #29
0
def generate(input_file, output_file, printer_profile, splice_offset, silent):
    starttime = time.time()
    v.printer_profile_string = printer_profile
    basename = os.path.basename(input_file)
    _taskName = os.path.splitext(basename)[0].replace(" ", "_")
    _taskName = _taskName.replace(".mcf", "")

    v.splice_offset = splice_offset

    try:
        # python 3.x
        opf = open(input_file, encoding='utf-8')
    except TypeError:
        try:
            # python 2.x
            opf = open(input_file)
        except IOError:
            if v.gui:
                gui.user_error(
                    "P2PP - Error Occurred",
                    "Could not read input file\n'{}'".format(input_file))
            else:
                print("Could not read input file\n'{}".format(input_file))
            return
    except IOError:
        if v.gui:
            gui.user_error(
                "P2PP - Error Occurred",
                "Could not read input file\n'{}'".format(input_file))
        else:
            print("Could not read input file\n'{}".format(input_file))
        return

    gui.setfilename(input_file)
    gui.set_printer_id(v.printer_profile_string)
    gui.create_logitem("Reading File " + input_file)
    gui.progress_string(1)

    v.input_gcode = opf.readlines()
    opf.close()

    v.input_gcode = [item.strip() for item in v.input_gcode]

    gui.create_logitem("Analyzing slicer parameters")
    gui.progress_string(2)
    parse_slic3r_config()

    gui.create_logitem("Pre-parsing GCode")
    gui.progress_string(4)
    parse_gcode()
    if v.palette_plus:
        if v.palette_plus_ppm == -9:
            gui.log_warning(
                "P+ parameter P+PPM not set correctly in startup GCODE")
        if v.palette_plus_loading_offset == -9:
            gui.log_warning(
                "P+ parameter P+LOADINGOFFSET not set correctly in startup GCODE"
            )

    v.side_wipe = not coordinate_on_bed(v.wipetower_posx, v.wipetower_posy)
    v.tower_delta = v.max_tower_z_delta > 0

    if v.side_wipe:
        gui.create_logitem("Side wipe activated", "blue")
        if v.full_purge_reduction:
            gui.log_warning(
                "Full Purge Reduction is not compatible with Side Wipe, performing Side Wipe"
            )
            v.full_purge_reduction = False

    if v.full_purge_reduction:
        v.side_wipe = False
        gui.create_logitem("Full Tower Reduction activated", "blue")
        if v.tower_delta:
            gui.log_warning(
                "Full Purge Reduction is not compatible with Tower Delta, performing Full Purge Reduction"
            )
            v.tower_delta = False

    v.pathprocessing = (v.tower_delta or v.full_purge_reduction or v.side_wipe)

    if v.tower_delta:
        optimize_tower_skip(v.max_tower_z_delta, v.layer_height)

    if v.side_wipe:
        optimize_tower_skip(999, v.layer_height)

    gui.create_logitem("Generate processed GCode")

    total_line_count = len(v.input_gcode)
    v.retraction = 0
    for process_line_count in range(total_line_count):
        gcode_parseline(process_line_count)
        gui.progress_string(50 + 50 * process_line_count // total_line_count)

    v.processtime = time.time() - starttime

    gcode_process_toolchange(-1, v.total_material_extruded, 0)
    omega_result = header_generate_omega(_taskName)
    header = omega_result['header'] + omega_result['summary'] + omega_result[
        'warnings']

    if v.absolute_extruder and v.gcode_has_relative_e:
        gui.create_logitem("Converting to absolute extrusion")
        convert_to_absolute()

    # write the output file
    ######################

    if not output_file:
        output_file = input_file
    gui.create_logitem("Generating GCODE file: " + output_file)
    opf = open(output_file, "w")
    if not v.accessory_mode:
        opf.writelines(header)
        opf.write("\n\n;--------- START PROCESSED GCODE ----------\n\n")
    if v.accessory_mode:
        opf.write("M0\n")
        opf.write("T0\n")

    if v.splice_offset == 0:
        gui.log_warning("SPLICE_OFFSET not defined")
    opf.writelines(v.processed_gcode)
    opf.close()

    if v.accessory_mode:

        pre, ext = os.path.splitext(output_file)
        if v.palette_plus:
            maffile = pre + ".msf"
        else:
            maffile = pre + ".maf"
        gui.create_logitem("Generating PALETTE MAF/MSF file: " + maffile)
        opf = open(maffile, "w")
        for i in range(len(header)):
            if not header[i].startswith(";"):
                opf.write(header[i])

    gui.print_summary(omega_result['summary'])

    gui.progress_string(100)
    if (len(v.process_warnings) > 0
            and not v.ignore_warnings) or v.consolewait:
        gui.close_button_enable()
Пример #30
0
def parse_slic3r_config():
    for idx in range(len(v.input_gcode) - 1, -1, -1):

        gcode_line = v.input_gcode[idx]

        if gcode_line.startswith("; filament_settings_id"):
            v.filament_ids = split_csv_strings(gcode_line)

        if ("generated by PrusaSlicer") in gcode_line:
            try:
                s1 = gcode_line.split("+")
                s2 = s1[0].split(" ")
                v.ps_version = s2[-1]
                gui.create_logitem(
                    "File was created with PS version:{}".format(v.ps_version))
                if v.ps_version < "2.2":
                    gui.log_warning(
                        "This version of P2PP is optimized to work with PS2.2!"
                    )
            except:
                pass
            continue

        if gcode_line.startswith("; wipe_tower_no_sparse_layers"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                try:
                    v.wipe_remove_sparse_layers = (int(
                        gcode_line[parameter_start + 1:].strip()) == 1)
                except:
                    pass
            continue

        if gcode_line.startswith("; wipe_tower_x"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.wipetower_posx = float(gcode_line[parameter_start +
                                                    1:].strip())
            continue

        if gcode_line.startswith("; min_skirt_length"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.skirtsize = float(gcode_line[parameter_start + 1:].strip())
            continue

        if gcode_line.startswith("; skirts"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.skirts = float(gcode_line[parameter_start + 1:].strip())
            continue

        if gcode_line.startswith("; wipe_tower_width"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.wipetower_width = float(gcode_line[parameter_start +
                                                     1:].strip())
            continue

        if gcode_line.startswith("; wipe_tower_y"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.wipetower_posy = float(gcode_line[parameter_start +
                                                    1:].strip())
            continue

        if gcode_line.startswith("; extrusion_width"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.extrusion_width = float(gcode_line[parameter_start +
                                                     1:].strip())
            continue

        if gcode_line.startswith("; infill_speed"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.infill_speed = float(
                    gcode_line[parameter_start + 1:].strip()) * 60
            continue

        if gcode_line.startswith("; layer_height"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.layer_height = float(gcode_line[parameter_start +
                                                  1:].strip())
            continue

        if gcode_line.startswith("; first_layer_height"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                v.first_layer_height = float(gcode_line[parameter_start +
                                                        1:].strip())
            continue

        if gcode_line.startswith("; support_material_synchronize_layers"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                tmp = float(gcode_line[parameter_start + 1:].strip())
                if tmp == 0:
                    v.synced_support = False
                else:
                    v.synced_support = True
            continue

        if gcode_line.startswith("; support_material "):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                tmp = float(gcode_line[parameter_start + 1:].strip())
                if tmp == 0:
                    v.support_material = False
                else:
                    v.support_material = True
            continue

        # TVDE: needs to be expanded to be able to support more than 4 colors
        if gcode_line.startswith("; extruder_colour") or gcode_line.startswith(
                "; filament_colour"):
            filament_colour = ''
            parameter_start = gcode_line.find("=")
            gcode_line = gcode_line[parameter_start + 1:].strip()
            parameter_start = gcode_line.find("#")
            if parameter_start != -1:
                filament_colour = gcode_line.split(";")
            if len(filament_colour) >= 4:
                for i in range(len(filament_colour)):
                    if filament_colour[i] == "":
                        filament_colour[i] = v.filament_color_code[i]
                    else:
                        v.filament_color_code[i] = filament_colour[i][1:]
            continue

        if gcode_line.startswith("; filament_diameter"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                filament_diameters = gcode_line[parameter_start +
                                                1:].strip(" ").split(",")
                if len(filament_diameters) >= 4:
                    for i in range(4):
                        v.filament_diameter[i] = float(filament_diameters[i])
            continue

        # TVDE: needs to be expanded to be able to support more than 4 colors
        # only check that is needed is that if nore than 4 colors exist, all must be of same type
        if gcode_line.startswith("; filament_type"):
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                filament_string = gcode_line[parameter_start +
                                             1:].strip(" ").split(";")
                v.m4c_numberoffilaments = len(filament_string)
                if v.m4c_numberoffilaments == 4:
                    v.filament_type = filament_string
                    v.used_filament_types = list(set(filament_string))
                elif v.m4c_numberoffilaments >= 4:
                    v.used_filament_types = list(set(filament_string))
                    if len(v.used_filament_types) > 1:
                        gui.log_warning(
                            "Prints with more than 4 colors should be of one filament type only!"
                        )
                        gui.log_warning("This file will not print correctly")
                    v.filament_type = filament_string[:4]

            if v.m4c_numberoffilaments > 4:
                gui.log_warning(
                    "Number of inputs defined in print: {}.  Swaps may be required!!!"
                    .format(v.m4c_numberoffilaments))

            continue

        # TVDE: needs to be expanded to be able to support more than 4 colors
        # if more than 4, just retain the first four (check is done at other level, but for not all settings should be the same)

        if gcode_line.startswith("; retract_lift = "):
            if v.filament_list:
                continue
            lift_error = False
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                retracts = gcode_line[parameter_start +
                                      1:].strip(" ").split(",")
                if len(retracts) >= 4:
                    for i in range(4):
                        v.retract_lift[i] = float(retracts[i])
                        if v.retract_lift[i] == 0:
                            lift_error = True
                if lift_error:
                    gui.log_warning(
                        "[Printer Settings]->[Extruders 1 -> {}]->[Retraction]->[Lift Z] should not be set to zero."
                        .format(len(retracts)))
                    gui.log_warning("Generated file might not print correctly")
            continue

        # TVDE: needs to be expanded to be able to support more than 4 colors
        # if more than 4, just retain the first four (check is done at other level, but for not all settings should be the same)
        if gcode_line.startswith("; retract_length = "):
            retract_error = False
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                retracts = gcode_line[parameter_start +
                                      1:].strip(" ").split(",")
                if len(retracts) >= 4:
                    for i in range(4):
                        v.retract_length[i] = float(retracts[i])
                        if v.retract_length[i] == 0.0:
                            retract_error = True
                if retract_error:
                    gui.log_warning(
                        "[Printer Settings]->[Extruders 1 -> {} 4]->[Retraction Length] should not be set to zero."
                        .format(len(retracts)))
            continue

        if gcode_line.startswith("; gcode_flavor"):
            if "reprap" in gcode_line:
                v.isReprap_Mode = True
            continue

        if "use_firmware_retraction" in gcode_line:
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                gcode_line = gcode_line[parameter_start + 1:].replace(";", "")
                if "1" in gcode_line:
                    v.use_firmware_retraction = True
                else:
                    v.use_firmware_retraction = False
            continue

        if "use_relative_e_distances" in gcode_line:
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                gcode_line = gcode_line[parameter_start + 1:].replace(";", "")
                if "1" in gcode_line:
                    v.gcode_has_relative_e = True
                else:
                    v.gcode_has_relative_e = False
            continue

        # TVDE: needs to be expanded to be able to support more than 4 colors
        # this should be expanded to nxn filaments where n = the number of filaments used.
        # needs to be a perfect square, calculate from there.
        if gcode_line.startswith("; wiping_volumes_matrix"):
            wiping_info = []
            parameter_start = gcode_line.find("=")
            if parameter_start != -1:
                wiping_info = gcode_line[parameter_start +
                                         1:].strip(" ").split(",")
                _warning = True
                for i in range(len(wiping_info)):
                    if int(wiping_info[i]) != 140 and int(wiping_info[i]) != 0:
                        _warning = False

                    wiping_info[i] = filament_volume_to_length(
                        float(wiping_info[i]))
            v.max_wipe = max(wiping_info)
            v.wiping_info = wiping_info
            if _warning:
                gui.log_warning(
                    "All purge lenghts 70/70 OR 140.  Purge lenghts may not have been set correctly."
                )
            continue