Exemple #1
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()
Exemple #2
0
    comment("Use:  p2pp_s3d [filename]")


if __name__ == "__main__":

    number_of_args = len(sys.argv)

    if number_of_args == 1:

        platformD = platform.system()
        if platformD == 'Darwin':
            comment('{}/p2pp_s3d.command "[output_filepath]"'.format(
                os.path.dirname(sys.argv[0])))
        elif platformD == 'Windows':
            if " " in os.path.dirname(sys.argv[0]):
                warning("Your path contains spaces!!!")
                comment('"{}\\p2pp_s3d.bat" "[output_filepath]"'.format(
                    os.path.dirname(sys.argv[0])))
            else:
                comment('{}\\p2pp_s3d.bat "[output_filepath]"'.format(
                    os.path.dirname(sys.argv[0])))

    elif number_of_args == 2:
        main(filename=sys.argv[1])

    else:
        error("[err {}] - Invalid usage:".format(number_of_args))
        usage()

    gui.close_button_enable()
Exemple #3
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()
Exemple #4
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()
Exemple #5
0
def on_clickclose():
    webwindow.hide()
    gui.close_button_enable()
Exemple #6
0
def p2pp_process_file(input_file, output_file):
    starttime = time.time()

    if output_file is None:
        output_file = input_file

    # get the base name from the environment variable if available....
    # check for P3 that output is written to file at this point.
    # check for P3 that the output file is named mcfx

    try:
        basename = os.environ["SLIC3R_PP_OUTPUT_NAME"]
        pathname = os.path.dirname(os.environ["SLIC3R_PP_OUTPUT_NAME"])
        maffile = basename
        mybasename = os.path.basename(basename)

        if v.palette3 and not os.environ["SLIC3R_PP_HOST"].startswith("File"):
            gui.log_warning("Palette 3 File uploading currently not supported")

        if v.palette3 and not os.environ["SLIC3R_PP_HOST"].endswith(".mcfx"):
            gui.log_warning("Palette 3 files should have a .mcfx extension")

    # if any the retrieval of this information fails, the good old way is used

    except KeyError:
        maffile = output_file
        basename = os.path.basename(input_file)
        mybasename = basename
        pathname = os.path.dirname(input_file)

    gui.setfilename(basename)

    # Determine the task name for this print form the filename without any extensions.
    _task_name = os.path.splitext(mybasename)[0].replace(" ", "_")
    _task_name = _task_name.replace(".mcfx", "")
    _task_name = _task_name.replace(".mcf", "")
    _task_name = _task_name.replace(".gcode", "")

    gui.app.sync()

    # Read the input file
    try:
        opf = open(input_file, encoding='utf-8')
        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]

    except (IOError, MemoryError):
        gui.log_warning("Error Reading: '{}'".format(input_file))
        return

    gui.create_logitem("Analyzing Prusa Slicer Configuration")
    gui.progress_string(2)

    parse_config_parameters(
    )  # Parse the Prusa Slicer  and P2PP Config Parameters

    # Write the unprocessed file
    if v.save_unprocessed:
        pre, ext = os.path.splitext(input_file)
        of = pre + "_unprocessed" + ext
        gui.create_logitem("Saving unpocessed code to: " + of)
        opf = open(of, "wb")
        for line in v.input_gcode:
            opf.write(line.encode('utf8'))
            opf.write("\n" "".encode('utf8'))
        opf.close()

    gui.progress_string(4)
    gui.create_logitem("GCode Analysis ... Pass 1")
    parse_gcode_first_pass()

    if config_checks() == -1:
        return

    gui.create_logitem("Gcode Analysis ... Pass 2")
    parse_gcode_second_pass()

    v.processtime = time.time() - starttime

    omega_result = header_generate_omega(_task_name)
    header = omega_result['header'] + omega_result['summary'] + omega_result[
        'warnings']

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

    path, _ = os.path.split(output_file)

    if v.palette3 and not v.accessory_mode:
        opf = open(os.path.join(path, "print.gcode"), "wb")
        gui.create_logitem("Generating MCFX file: " + output_file)
    else:
        opf = open(output_file, "wb")
        gui.create_logitem(
            "Generating GCODE file: (temp location, PS will move) " +
            output_file)

    if not v.accessory_mode and not v.palette3:
        for line in header:
            opf.write(line.encode('utf8'))
        opf.write(
            ("\n\n;--------- THIS CODE HAS BEEN PROCESSED BY P2PP v{} --- \n\n"
             .format(version.Version)).encode('utf8'))
        if v.generate_M0:
            header.append("M0\n")
        opf.write("T0\n".encode('utf8'))
    else:
        opf.write(
            ("\n\n;--------- THIS CODE HAS BEEN PROCESSED BY P2PP v{} --- \n\n"
             .format(version.Version)).encode('utf8'))

    if v.splice_offset == 0:
        gui.log_warning("SPLICE_OFFSET not defined")
    for line in v.processed_gcode:
        try:
            opf.write(line.encode('utf8'))
        except IOError:
            gui.log_warning(
                "Line : {} could not be written to output".format(line))
        opf.write("\n".encode('utf8'))
    opf.close()

    if v.palette3:
        meta, palette = header_generate_omega_palette3(None)

        meta_file = os.path.join(path, "meta.json")
        palette_file = os.path.join(path, "palette.json")
        im_file = os.path.join(path, "thumbnail.png")

        # 22/02/2022 added accessory mode for palette 3
        if v.accessory_mode:
            gcode_file = os.path.join(path, output_file)
        else:
            gcode_file = os.path.join(path, "print.gcode")

        gui.create_logitem("Generating Palette 3 output files")
        mf = open(meta_file, 'wb')
        mf.write(meta.__str__().encode('ascii'))
        mf.close()

        pa = open(palette_file, 'wb')
        pa.write(palette.__str__().encode('ascii'))
        pa.close()

        im = open(im_file, "wb")
        if len(v.p3_thumbnail_data) == 0:
            gui.log_warning(
                "Thumbnail Info missing (Printer Settings/General/Firmware/G-Code Thumbnail"
            )

        im.write(base64.b64decode(v.p3_thumbnail_data))
        im.close()

        # 22/02/2022 added accessory mode for palette 3
        if v.accessory_mode:
            maffile = maffile + ".mafx"
            maffile = maffile.replace(".gcode", "")
            gui.create_logitem("Generating PALETTE MAFX file: " + maffile)
            zipf = zipfile.ZipFile(maffile, 'w', zipfile.ZIP_DEFLATED)
            zipf.write(meta_file, "meta.json")
            zipf.write(palette_file, "palette.json")
            zipf.write(im_file, "thumbnail.png")
            zipf.close()
        else:
            zipf = zipfile.ZipFile(output_file, 'w', zipfile.ZIP_DEFLATED)
            zipf.write(meta_file, "meta.json")
            zipf.write(palette_file, "palette.json")
            zipf.write(gcode_file, "print.gcode")
            zipf.write(im_file, "thumbnail.png")
            zipf.close()
            os.remove(os.path.join(path, "print.gcode"))

        os.remove(meta_file)
        os.remove(palette_file)
        os.remove(im_file)

    # 22/02/2022 added accessory mode for palette 3
    if v.accessory_mode and not v.palette3:

        pre, ext = os.path.splitext(maffile)
        if v.palette_plus:
            maffile = pre + ".msf"
        else:
            maffile = pre + ".maf"

        maffile = os.path.basename(maffile)
        maffile = os.path.join(pathname, maffile)

        gui.create_logitem("Generating PALETTE MAF/MSF file: " + maffile)

        maf = open(maffile, 'wb')

        for h in header:
            h = str(h).strip("\r\n")
            maf.write(h.encode('ascii'))
            maf.write("\r\n".encode('ascii'))

        maf.close()

    gui.print_summary(omega_result['summary'])

    gui.progress_string(101)

    if v.palette3:
        gui.create_logitem(
            "===========================================================================================",
            "green")
        gui.create_logitem(
            "Go to https://github.com/tomvandeneede/p2pp/wiki for more information on P2PP Configuration",
            "green")
        gui.create_logitem(
            "===========================================================================================",
            "green")

    if v.uploadfile:

        try:  # get the correct output filename from the PS environment variable
            filename = os.path.basename(os.environ["SLIC3R_PP_OUTPUT_NAME"])
            if filename.endswith(".gcode"):
                filename = filename.replace(".gcode", ".mcfx")

            filename = filename.replace(" ", "_")
        except (TypeError,
                KeyError):  # regardsless of the error, use this filename
            filename = "output.mcfx"

        upload.uploadfile(output_file, filename)

    if (len(v.process_warnings) > 0
            and not v.ignore_warnings) or v.consolewait:

        gui.close_button_enable()