#!/bin/bash # Usage instruction echo "=================================================" echo " PCB2GCODE SCRIPT " echo "=================================================" echo "Uscase:" echo "Automates G-code generation for PCB milling from KiCad files by running pcb2gcode twice: first for standard files (front, back, outline, PTH drills) and then for NPTH drills." echo "It handles file paths dynamically based on the project name, ensures required files exist, renames debug outputs and deletes unnecessary files" echo "" echo "Usage:" echo " ./run.sh [PROJECT_NAME]" echo "If no PROJECT_NAME is provided, it will be derived from the parent folder name." echo "" echo "Requirements:" echo " - The script must be run from a folder within the KiCad project." echo " - A millproject config file must exist in the current folder." echo " - KiCad files must be exported to ../export relative to the script's location." echo "" echo "Example:" echo " Directory structure:" echo " /home/user/git/project-name/pcb2gcode/" echo " - run.sh (this script)" echo " - millproject (config file)" echo " /home/user/git/project-name/export/" echo " - project-name-F_Cu.gbr" echo " - project-name-B_Cu.gbr" echo " - project-name-Edge_Cuts.gbr" echo " - project-name-PTH.drl" echo " - project-name-NPTH.drl" echo "" echo " To run the script:" echo " cd /home/user/git/project-name/pcb2gcode" echo " ./run.sh project-name" echo "=================================================" echo "" echo "" # Define project name # Extract project name from argument or parent folder if [[ -n "$1" ]]; then PROJECT_NAME="$1" else PROJECT_NAME=$(basename "$(dirname "$(pwd)")") echo "No project name provided. Using folder name as project name: $PROJECT_NAME" fi # Define folders INPUT_DIR="../export" OUTPUT_DIR="./out" # Define file paths BACK_FILE="$INPUT_DIR/${PROJECT_NAME}-B_Cu.gbr" FRONT_FILE="$INPUT_DIR/${PROJECT_NAME}-F_Cu.gbr" OUTLINE_FILE="$INPUT_DIR/${PROJECT_NAME}-Edge_Cuts.gbr" PTH_DRILL_FILE="$INPUT_DIR/${PROJECT_NAME}-PTH.drl" NPTH_DRILL_FILE="$INPUT_DIR/${PROJECT_NAME}-NPTH.drl" NPTH_DRILL_OUT_FILE="npth.ngc" CONFIG_FILE="./millproject" TEMP_CONFIG=$(mktemp) # Additional options for pcb2gcode runs PCB2GCODE_OPTIONS="2>&1 | grep -v 'Unsupported'" #-> do not output erros like: #** (process:507955): CRITICAL **: 10:23:56.224: Unsupported G00 (rout mode) code at line 197 in file "../export/power-supply-board_v1.0-PTH.drl" # Create output directory if it doesn't exist mkdir -p "$OUTPUT_DIR" # Function to append file paths to config file append_file_paths() { echo "==> run.sh: Appending file paths to config..." echo "back=$BACK_FILE" >> "$1" echo "front=$FRONT_FILE" >> "$1" echo "outline=$OUTLINE_FILE" >> "$1" echo "drill=$PTH_DRILL_FILE" >> "$1" echo "output-dir=$OUTPUT_DIR" >> "$1" } # Function to check file existence check_file() { if [[ ! -f "$1" ]]; then echo "==> run.sh: Warning: File not found: $1" return 1 fi return 0 } # Run first pass: Generate front, back, outline, and PTH drilling echo "=================================================" echo "=== initiating first run (front, back, holes) ===" echo "=================================================" if check_file "$BACK_FILE" && check_file "$FRONT_FILE" && check_file "$OUTLINE_FILE" && check_file "$PTH_DRILL_FILE"; then cp "$CONFIG_FILE" "$TEMP_CONFIG" append_file_paths "$TEMP_CONFIG" pcb2gcode --config "$TEMP_CONFIG" echo "==> run.sh: First pass complete." else echo "==> run.sh: Skipping first pass due to missing files." fi # Run second pass: Generate NPTH drilling only echo "===========================================" echo "=== initiating second run for NPTH only ===" echo "===========================================" if check_file "$NPTH_DRILL_FILE"; then cp "$CONFIG_FILE" "$TEMP_CONFIG" echo "==> run.sh: Appending NPTH drill file to config..." # rename original drill debug output image echo "drill=$NPTH_DRILL_FILE" >> "$TEMP_CONFIG" echo "outline=$OUTLINE_FILE" >> "$TEMP_CONFIG" #note: outline needed for matching gcode origin echo "drill-output=$NPTH_DRILL_OUT_FILE" >> "$TEMP_CONFIG" echo "output-dir=$OUTPUT_DIR" >> "$TEMP_CONFIG" echo "==> run.sh: Renaming drill debug image from previous run..." mv "$OUTPUT_DIR"/original_drill.svg "$OUTPUT_DIR"/original_drill_normal.svg pcb2gcode --config "$TEMP_CONFIG" mv "$OUTPUT_DIR"/original_drill.svg "$OUTPUT_DIR"/original_drill_NPTH.svg echo "==> run.sh: Second pass complete." else echo "==> run.sh: Skipping second pass due to missing NPTH file: $NPTH_DRILL_FILE" fi # Clean up temporary config file rm -f "$TEMP_CONFIG" # Delete unwanted files echo "==> run.sh: Deleting unwanted files..." rm -f "$OUTPUT_DIR"/*contentions*.svg \ "$OUTPUT_DIR"/*original_outline.svg \ "$OUTPUT_DIR"/*original_front.svg \ "$OUTPUT_DIR"/*original_back.svg \ "$OUTPUT_DIR"/*processed_front.svg \ "$OUTPUT_DIR"/*processed_back.svg \ "$OUTPUT_DIR"/*processed_outline.svg \ "$OUTPUT_DIR"/*traced*.svg \ "$OUTPUT_DIR"/*masked*.svg \ "$OUTPUT_DIR"/*contentions*.svg echo "==> run.sh: G-code generation complete. Output saved in $OUTPUT_DIR."