added export to pm4n
This commit is contained in:
@@ -1,35 +1,156 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
# export.sh — KiCad Gerber export + pm4n generation for Anycubic Photon Mono 4
|
||||
#
|
||||
# Usage:
|
||||
# ./export.sh [OPTIONS] <path/to/board.kicad_pcb>
|
||||
#
|
||||
# Options:
|
||||
# --layers LAYER,LAYER,... KiCad layer names to export (default: F.Cu)
|
||||
# --invert LAYER,LAYER,... Layers to invert (comma-separated, e.g. F.Cu,B.Mask)
|
||||
# --mirror LAYER,LAYER,... Layers to mirror (comma-separated, e.g. F.Cu,F.Mask)
|
||||
# --exposure SECONDS Exposure time in seconds (default: 60)
|
||||
# --dummy FILE Dummy .pm4n template (default: Dummy.pm4n beside this script)
|
||||
# --out DIR Output directory (default: ./output)
|
||||
# --dpmm N Render resolution in dots/mm (default: native 58.824)
|
||||
# --pos X,Y Board position on LCD in mm (default: centred)
|
||||
# -h, --help Show this help
|
||||
#
|
||||
# Example:
|
||||
# ./export.sh --invert F.Cu,B.Mask --mirror F.Cu,F.Mask panel/Flow_Controller_Panel.kicad_pcb
|
||||
#
|
||||
# Layer name → Gerber filename mapping (KiCad default):
|
||||
# F.Cu → <board>-F_Cu.gbr
|
||||
# B.Cu → <board>-B_Cu.gbr
|
||||
# F.Mask → <board>-F_Mask.gbr
|
||||
# B.Mask → <board>-B_Mask.gbr
|
||||
# F.SilkS → <board>-F_Silkscreen.gbr
|
||||
# (etc.)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
GERBERS_DIR="gerbers"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PYTHON="${PYTHON:-python3}"
|
||||
CONVERTER="$SCRIPT_DIR/gerber_to_pm4n.py"
|
||||
|
||||
# ---- defaults ----
|
||||
LAYERS="F.Cu"
|
||||
INVERT_LAYERS=""
|
||||
MIRROR_LAYERS=""
|
||||
EXPOSURE="60"
|
||||
DUMMY="$SCRIPT_DIR/Dummy.pm4n"
|
||||
OUT_DIR="./output"
|
||||
DPMM=""
|
||||
POS=""
|
||||
|
||||
# ---- helpers ----
|
||||
usage() {
|
||||
echo "Usage: $0 <kicad_pcb_file>"
|
||||
exit 1
|
||||
sed -n '/^# Usage/,/^[^#]/{ /^#/{ s/^# \{0,1\}//; p } }' "$0"
|
||||
exit 0
|
||||
}
|
||||
|
||||
PCB_FILE="$1"
|
||||
contains() { # contains <list> <item> — comma-separated list membership
|
||||
local list="$1" item="$2"
|
||||
echo "$list" | tr ',' '\n' | grep -qx "$item"
|
||||
}
|
||||
|
||||
mkdir -p "$GERBERS_DIR"
|
||||
layer_to_filename() { # KiCad layer name → Gerber filename stem
|
||||
local layer="$1"
|
||||
echo "$layer" | sed 's/\./_/g'
|
||||
}
|
||||
|
||||
# Export drill, front and back layers as gerber files.
|
||||
echo "Exporting gerbers..."
|
||||
kicad-cli pcb export drill -o "$GERBERS_DIR" "$PCB_FILE"
|
||||
kicad-cli pcb export gerbers -o "$GERBERS_DIR" -l Front "$PCB_FILE"
|
||||
kicad-cli pcb export gerbers -o "$GERBERS_DIR" -l Back "$PCB_FILE"
|
||||
kicad-cli pcb export gerbers -o "$GERBERS_DIR" -l Edge.Cuts "$PCB_FILE"
|
||||
# ---- parse arguments ----
|
||||
PCB_FILE=""
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--layers) LAYERS="$2"; shift 2 ;;
|
||||
--invert) INVERT_LAYERS="$2"; shift 2 ;;
|
||||
--mirror) MIRROR_LAYERS="$2"; shift 2 ;;
|
||||
--exposure) EXPOSURE="$2"; shift 2 ;;
|
||||
--dummy) DUMMY="$2"; shift 2 ;;
|
||||
--out) OUT_DIR="$2"; shift 2 ;;
|
||||
--dpmm) DPMM="$2"; shift 2 ;;
|
||||
--pos) POS="$2"; shift 2 ;;
|
||||
-h|--help) usage ;;
|
||||
-*) echo "Unknown option: $1"; exit 1 ;;
|
||||
*) PCB_FILE="$1"; shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Export outlines of the penelized board i.e. use the layer 'User.Eco1'.
|
||||
# echo "Exporting panelized outlines from layer 'User.Eco1'..."
|
||||
# python3 export_panel_outlines_gerber.py \
|
||||
# --layers User.Eco1 \
|
||||
# --output "$GERBERS_DIR" \
|
||||
# "$PCB_FILE"
|
||||
if [[ -z "$PCB_FILE" ]]; then
|
||||
echo "ERROR: no .kicad_pcb file specified"
|
||||
echo "Usage: $0 [OPTIONS] <board.kicad_pcb>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Input layers/filenames and all milling/drilling parameters are taken from the config file: 'millproject'.
|
||||
echo "Exporting Gcode..."
|
||||
docker run --rm -i -t \
|
||||
-u "$(id -u):$(id -g)" \
|
||||
-v "$(pwd):/data" \
|
||||
ptodorov/pcb2gcode
|
||||
if [[ ! -f "$PCB_FILE" ]]; then
|
||||
echo "ERROR: file not found: $PCB_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$DUMMY" ]]; then
|
||||
echo "ERROR: dummy .pm4n not found: $DUMMY"
|
||||
echo "Place Dummy.pm4n next to export.sh, or pass --dummy <path>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ---- derive names ----
|
||||
BOARD_NAME="$(basename "$PCB_FILE" .kicad_pcb)"
|
||||
GERBERS_DIR="$OUT_DIR/gerbers"
|
||||
PM4N_DIR="$OUT_DIR/pm4n"
|
||||
|
||||
mkdir -p "$GERBERS_DIR" "$PM4N_DIR"
|
||||
|
||||
# ---- Step 1: export Gerbers via kicad-cli ----
|
||||
echo "=== Exporting Gerbers from KiCad ==="
|
||||
echo " Board: $PCB_FILE"
|
||||
echo " Layers: $LAYERS"
|
||||
echo " Output: $GERBERS_DIR"
|
||||
echo ""
|
||||
|
||||
kicad-cli pcb export gerbers \
|
||||
--output "$GERBERS_DIR" \
|
||||
--layers "$LAYERS" \
|
||||
--no-protel-ext \
|
||||
--subtract-soldermask \
|
||||
"$PCB_FILE"
|
||||
|
||||
echo ""
|
||||
|
||||
# ---- Step 2: convert each layer to .pm4n ----
|
||||
echo "=== Converting Gerbers to .pm4n ==="
|
||||
|
||||
IFS=',' read -ra LAYER_LIST <<< "$LAYERS"
|
||||
for LAYER in "${LAYER_LIST[@]}"; do
|
||||
LAYER_STEM="$(layer_to_filename "$LAYER")"
|
||||
GBR_FILE="$GERBERS_DIR/${BOARD_NAME}-${LAYER_STEM}.gbr"
|
||||
|
||||
if [[ ! -f "$GBR_FILE" ]]; then
|
||||
echo " WARNING: expected Gerber not found: $GBR_FILE — skipping"
|
||||
continue
|
||||
fi
|
||||
|
||||
OUT_PM4N="$PM4N_DIR/${BOARD_NAME}-${LAYER_STEM}.pm4n"
|
||||
|
||||
# Build flags
|
||||
FLAGS=()
|
||||
if contains "$INVERT_LAYERS" "$LAYER"; then FLAGS+=(--invert); fi
|
||||
if contains "$MIRROR_LAYERS" "$LAYER"; then FLAGS+=(--mirror); fi
|
||||
[[ -n "$DPMM" ]] && FLAGS+=(--dpmm "$DPMM")
|
||||
[[ -n "$POS" ]] && FLAGS+=(--pos "$POS")
|
||||
|
||||
echo " Layer: $LAYER"
|
||||
echo " Gerber: $GBR_FILE"
|
||||
echo " pm4n: $OUT_PM4N"
|
||||
echo " Flags: ${FLAGS[*]:-<none>} exposure=${EXPOSURE}s"
|
||||
|
||||
"$PYTHON" "$CONVERTER" \
|
||||
"$DUMMY" \
|
||||
"$GBR_FILE" \
|
||||
--output "$OUT_PM4N" \
|
||||
--exposure "$EXPOSURE" \
|
||||
"${FLAGS[@]}"
|
||||
echo ""
|
||||
done
|
||||
|
||||
echo "=== Done ==="
|
||||
echo "pm4n files in: $PM4N_DIR"
|
||||
Reference in New Issue
Block a user