@@ -963,7 +963,9 @@ def __init__(self, extrusion_global_multiplier: float = 1.05, start_at_layer: in
963963 self .last_internalperimeter_state = None # Experiment...
964964 self .last_internalperimeter_xy_line = None # Experiment...
965965 self .last_noninternalperimeter_state = None # Experiment...
966- self .last_noninternalperimeter_xy_line = None # Experiment...
966+ self .last_noninternalperimeter_xy_line = None # Used to re-conciliate the moved lines to their new surroundings
967+ self .header_info = {} # Any text to be included at the beginning of the exported file
968+ self .enable_header = False # If turned false, won't output the Bricklayers header information to the file
967969
968970 def set_progress_callback (self , callback : Callable [[dict ], None ]):
969971 """Sets the progress callback function."""
@@ -1001,7 +1003,37 @@ def new_line_from_multiplier(myline, extrusion_multiplier):
10011003 myline .gcode = command + "\n "
10021004 return myline # keeps the states, just change the actual gcode string
10031005
1006+ def set_header_info (self , dict ):
1007+ self .header_info = dict
10041008
1009+ def gen_header_lines (self , gcodeline_wrap = True ) -> list :
1010+ """
1011+ Args:
1012+ gcodeline_wrap (bool):
1013+ - True returns a list of GCodeLine objects.
1014+ - False returns a list of plain string lines.
1015+ """
1016+ t = []
1017+ pf = ";=="
1018+ bar = "=============================="
1019+
1020+ t .append (bar )
1021+ t .append (" BrickLayers Post-Processed" )
1022+ # Loop through key/values to build header
1023+ for key , value in self .header_info .items ():
1024+ t .append (f" { key } : { value } " )
1025+ t .append (bar )
1026+ t .append ("" )
1027+
1028+ # Prefix each line with pf and add line breaks
1029+ output = []
1030+ for line in t :
1031+ txt = f"{ pf } { line } \n " if line else f"\n "
1032+ if gcodeline_wrap :
1033+ output .append (GCodeLine .from_gcode (txt ))
1034+ else :
1035+ output .append (txt )
1036+ return output
10051037
10061038 def travel_to (self , target_state , simulator , feature , loop = None , start_state = None , z = None ):
10071039 from_gcode = GCodeLine .from_gcode # faster lookup
@@ -1656,6 +1688,10 @@ def process_gcode(self, gcode_stream):
16561688 knife_activated = False
16571689 layer_changed_during_internal_perimeter = False
16581690
1691+ # includes the BrickLayer Header Information to the GCode
1692+ if self .enable_header :
1693+ buffer_lines .extend (self .gen_header_lines ())
1694+
16591695 # Process the G-code
16601696 #READING ONE LINE AT A TIME FROM A GENERATOR (the input)
16611697 for line_number , line in enumerate (gcode_stream , start = 1 ):
@@ -2201,6 +2237,10 @@ def expand_ranges(ranges):
22012237 "1: Just Filenames\n "
22022238 "2: Progress (default)\n "
22032239 "3: Progress all lines, a bit slower\n \n " )
2240+ parser .add_argument ("-noHeader" , action = "store_true" ,
2241+ help = "\n Skip adding BrickLayers header to your G-code\n "
2242+ "Recommended only for automation\n "
2243+ "(header is helpful for debugging)\n \n " )
22042244
22052245 args = parser .parse_args ()
22062246
@@ -2298,6 +2338,50 @@ def gcode_opener(path, flags):
22982338 if verbosity == 1 :
22992339 print (input_file )
23002340
2341+
2342+ # Setting up the BrickProcessor:
2343+ processor = BrickLayersProcessor (
2344+ extrusion_global_multiplier = args_dict ["extrusionmultiplier" ],
2345+ start_at_layer = args_dict ["startatlayer" ],
2346+ layers_to_ignore = final_ignored_layers ,
2347+ verbosity = verbosity
2348+ )
2349+ processor .experimental_arcflick = False
2350+ processor .set_progress_callback (update_progress ) # Full-fledged terminal progress indicator
2351+ #processor.set_progress_callback(update_progress_print) # Super simple progress-indicator example
2352+
2353+
2354+ # Detect interpreter
2355+ python_imp = platform .python_implementation ()
2356+ python_ver = platform .python_version ()
2357+ os_info = f"{ platform .system ()} { platform .release ()} "
2358+ IS_CPYTHON = python_imp == "CPython"
2359+ IS_PYPY = python_imp == "PyPy"
2360+
2361+ # !! HEADER PRIVACY CONCERNS !!
2362+ #
2363+ # Certain information is very useful for debugging
2364+ # but could accidentally expose sensitive user data:
2365+ #
2366+ # - Interpreter Path: Can reveal usernames or computer-specific info
2367+ # - Script Arguments: Might contain file paths or other sensitive details
2368+ # - Input/Output Filenames: May identify personal projects or users
2369+ #
2370+ # DO NOT add sensitive information to the header.
2371+ # Keep the following list minimal, generic, and privacy-safe:
2372+ header_info = {
2373+ "Script Version" : __version__ ,
2374+ "Python Interpreter" : python_imp ,
2375+ "Python Version" : python_ver ,
2376+ "OS" : os_info ,
2377+ "Input Source" : "Slicer" if is_uploading else "Command Line" ,
2378+ "Starting at Layer" : args_dict ["startatlayer" ],
2379+ "Ignored Layers" : final_ignored_layers ,
2380+ "Extrusion Multiplier" : args_dict ["extrusionmultiplier" ]
2381+ }
2382+ processor .set_header_info (header_info )
2383+ processor .enable_header = not args_dict ["noheader" ]
2384+
23012385 if verbosity > 1 :
23022386 import io
23032387 if os .name == "nt" :
@@ -2318,28 +2402,16 @@ def gcode_opener(path, flags):
23182402 print (" Layers to Ignore: " , final_ignored_layers )
23192403 print (" Enabled: " , args_dict ["enabled" ])
23202404 print (" Verbosity: " , args_dict ["verbosity" ])
2405+ print (" Include Header: " , "No" if args_dict ["noheader" ] else "Yes" )
2406+ print (" Python Interpreter: " , python_imp )
2407+ print (" Python Version: " , python_ver )
2408+ print (" OS: " , os_info )
23212409 print ("\n " )
23222410
23232411 logger .debug (input_file )
23242412 logger .debug (final_output_file )
23252413 input_file_size = os .path .getsize (input_file )
23262414
2327- # Setting up the BrickProcessor:
2328- processor = BrickLayersProcessor (
2329- extrusion_global_multiplier = args_dict ["extrusionmultiplier" ],
2330- start_at_layer = args_dict ["startatlayer" ],
2331- layers_to_ignore = final_ignored_layers ,
2332- verbosity = verbosity
2333- )
2334- processor .experimental_arcflick = False
2335- processor .set_progress_callback (update_progress ) # Full-fledged terminal progress indicator
2336- #processor.set_progress_callback(update_progress_print) # Super simple progress-indicator example
2337-
2338-
2339- # Detect interpreter
2340- IS_CPYTHON = platform .python_implementation () == "CPython"
2341- IS_PYPY = platform .python_implementation () == "PyPy"
2342-
23432415 if verbosity > 0 :
23442416 # Setup optional memory tracking
23452417 if IS_CPYTHON :
0 commit comments