From 37bd515fe17ddfe8981231470ec228fe72f1cbe9 Mon Sep 17 00:00:00 2001 From: TenTech <45683060+TengerTechnologies@users.noreply.github.com> Date: Wed, 22 Jan 2025 19:14:44 +0100 Subject: [PATCH] Add files via upload --- bricklayers.py | 129 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 bricklayers.py diff --git a/bricklayers.py b/bricklayers.py new file mode 100644 index 0000000..c1083af --- /dev/null +++ b/bricklayers.py @@ -0,0 +1,129 @@ +import re +import sys +import logging +import os +import argparse + +# Get the directory where the script is located +script_dir = os.path.dirname(os.path.abspath(__file__)) + +# Configure logging to save in the script's directory +log_file_path = os.path.join(script_dir, "z_shift_log.txt") +logging.basicConfig( + filename=log_file_path, + filemode="w", + level=logging.INFO, + format="%(asctime)s - %(message)s" +) + +def process_gcode(input_file, layer_height, extrusion_multiplier): + current_layer = 0 + current_z = 0.0 + perimeter_type = None + perimeter_block_count = 0 + inside_perimeter_block = False + z_shift = layer_height * 0.5 + logging.info("Starting G-code processing") + logging.info(f"Input file: {input_file}") + logging.info(f"Z-shift: {z_shift} mm, Layer height: {layer_height} mm") + + # Read the input G-code + with open(input_file, 'r') as infile: + lines = infile.readlines() + + # Identify the total number of layers by looking for `G1 Z` commands + total_layers = sum(1 for line in lines if line.startswith("G1 Z")) + + # Process the G-code + modified_lines = [] + for line in lines: + # Detect layer changes + if line.startswith("G1 Z"): + z_match = re.search(r'Z([-\d.]+)', line) + if z_match: + current_z = float(z_match.group(1)) + current_layer = int(current_z / layer_height) + + perimeter_block_count = 0 # Reset block counter for new layer + logging.info(f"Layer {current_layer} detected at Z={current_z:.3f}") + modified_lines.append(line) + continue + + # Detect perimeter types from PrusaSlicer comments + if ";TYPE:External perimeter" in line or ";TYPE:Outer wall" in line: + perimeter_type = "external" + inside_perimeter_block = False + logging.info(f"External perimeter detected at layer {current_layer}") + elif ";TYPE:Perimeter" in line or ";TYPE:Inner wall" in line: + perimeter_type = "internal" + inside_perimeter_block = False + logging.info(f"Internal perimeter block started at layer {current_layer}") + elif ";TYPE:" in line: # Reset for other types + perimeter_type = None + inside_perimeter_block = False + + # Group lines into perimeter blocks + if perimeter_type == "internal" and line.startswith("G1") and "X" in line and "Y" in line and "E" in line: + # Start a new perimeter block if not already inside one + if not inside_perimeter_block: + perimeter_block_count += 1 + inside_perimeter_block = True + logging.info(f"Perimeter block #{perimeter_block_count} detected at layer {current_layer}") + + # Insert the corresponding Z height for this block + is_shifted = False # Flag for whether this block is Z-shifted + if perimeter_block_count % 2 == 1: # Apply Z-shift to odd-numbered blocks + adjusted_z = current_z + z_shift + logging.info(f"Inserting G1 Z{adjusted_z:.3f} for shifted perimeter block #{perimeter_block_count}") + modified_lines.append(f"G1 Z{adjusted_z:.3f} ; Shifted Z for block #{perimeter_block_count}\n") + is_shifted = True + else: # Reset to the true layer height for even-numbered blocks + logging.info(f"Inserting G1 Z{current_z:.3f} for non-shifted perimeter block #{perimeter_block_count}") + modified_lines.append(f"G1 Z{current_z:.3f} ; Reset Z for block #{perimeter_block_count}\n") + + # Adjust extrusion (`E` values) for shifted blocks on the first and last layer + if is_shifted: + e_match = re.search(r'E([-\d.]+)', line) + if e_match: + e_value = float(e_match.group(1)) + if current_layer == 0: # First layer + new_e_value = e_value * 1.5 + logging.info(f"Multiplying E value by 1.5 on first layer (shifted block): {e_value:.5f} -> {new_e_value:.5f}") + line = re.sub(r'E[-\d.]+', f'E{new_e_value:.5f}', line).strip() + line += f" ; Adjusted E for first layer, block #{perimeter_block_count}\n" + elif current_layer == total_layers - 1: # Last layer + new_e_value = e_value * 0.5 + logging.info(f"Multiplying E value by 0.5 on last layer (shifted block): {e_value:.5f} -> {new_e_value:.5f}") + line = re.sub(r'E[-\d.]+', f'E{new_e_value:.5f}', line).strip() + line += f" ; Adjusted E for last layer, block #{perimeter_block_count}\n" + else: + new_e_value = e_value * extrusion_multiplier + logging.info(f"Multiplying E value by extrusionMultiplier") + line = re.sub(r'E[-\d.]+', f'E{new_e_value:.5f}', line).strip() + line += f" ; Adjusted E for extrusionMultiplier, block #{perimeter_block_count}\n" + + elif perimeter_type == "internal" and line.startswith("G1") and "X" in line and "Y" in line and "F" in line: # End of perimeter block + inside_perimeter_block = False + + modified_lines.append(line) + + # Overwrite the input file with the modified G-code + with open(input_file, 'w') as outfile: + outfile.writelines(modified_lines) + + logging.info("G-code processing completed") + logging.info(f"Log file saved at {log_file_path}") + +# Main execution +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Post-process G-code for Z-shifting and extrusion adjustments.") + parser.add_argument("input_file", help="Path to the input G-code file") + parser.add_argument("-layerHeight", type=float, default=0.2, help="Layer height in mm (default: 0.2mm)") + parser.add_argument("-extrusionMultiplier", type=float, default=1, help="Extrusion multiplier for first layer (default: 1.5x)") + args = parser.parse_args() + + process_gcode( + input_file=args.input_file, + layer_height=args.layerHeight, + extrusion_multiplier=args.extrusionMultiplier, + ) \ No newline at end of file