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()
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()
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()
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()
def on_clickclose(): webwindow.hide() gui.close_button_enable()
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()