# UVtools PCB Exposure CLI — Build & Usage Guide

This guide covers building a wrapper for the`UVtoolsCmd`, for headless Gerber → `.pm4n` (or any slicer format) conversion on Ubuntu.

> **Note:** The UVtools maintainer is implementing an official equivalent via
> the generic `run` command and a new `FileArray` reflection property
> (`-p FileArray=file.gbr`). Once that ships in a release 
> ([issue 1127](https://github.com/sn4k3/UVtools/issues/1127)), you can switch to
> `pcb-expose-official.sh` and skip the patch/compile steps entirely — see
> [Option B](#option-b-official-release-no-compiling-required) below.

---

## Option A: Patched local build (`pcb-expose` command)

### 1. Install .NET SDK

```bash
sudo snap install dotnet
export DOTNET_ROOT=/var/snap/dotnet/common/dotnet
dotnet --version
```

Add the `export` line to your `~/.bashrc` so it persists across shells:

```bash
echo 'export DOTNET_ROOT=/var/snap/dotnet/common/dotnet' >> ~/.bashrc
```

### 2. Clone the repo

```bash
cd ~/proj
git clone --depth 1 https://github.com/sn4k3/UVtools.git
cd UVtools
```

### 3. Apply the patch

Copy `pcb-expose.patch` into the repo root, then:

```bash
git apply ../kicad2msla/UVtools/pcb-expose.patch
```

This does two things:
- Adds `UVtools.Cmd/Symbols/PcbExposeCommand.cs` (new `pcb-expose` subcommand)
- Registers it in `UVtools.Cmd/Program.cs`

Verify it applied cleanly:

```bash
git add .
git status
#   modified:   UVtools.Cmd/Program.cs
#   new file:   UVtools.Cmd/Symbols/PcbExposeCommand.cs
```

### 4. Restore & build

```bash
dotnet restore

dotnet publish UVtools.Cmd/UVtools.Cmd.csproj \
    -c Release \
    -r linux-x64 \
    --self-contained false \
    -o ./publish/
```

### 5. Copy the OpenCV native library

The published output doesn't include `libcvextern.so` — copy it from the repo:

```bash
cp build/platforms/linux-x64/libcvextern.so ./publish/
```

### 6. Test it

```bash
./publish/UVtoolsCmd pcb-expose \
    ~/proj/kicad2msla/Dummy.pm4n \
    ~/proj/kicad2msla/gerbers/Flow_Controller_Panel-Front.gtl \
    --invert \
    --mirror \
    --exposure 120 \
    --output ~/proj/kicad2msla/Flow_Controller_Panel-Front.pm4n
```

### 7. Install the wrapper

Copy `pcb-expose-patched.sh` somewhere on your `$PATH`, e.g.:

```bash
# Copy the script
cp ~/proj/kicad2msla/UVtools/pcb-expose-patched.sh ~/.local/bin
# Make it executable
chmod +x ~/.local/bin/pcb-expose-patched.sh
# Create a symlink
ln -s ~/.local/bin/pcb-expose-patched.sh ~/.local/bin/pcb-expose.sh
```

By default the wrapper looks for the build at `~/proj/UVtools/publish/UVtoolsCmd`.
If yours is elsewhere, either edit the `UVTOOLSCMD` variable at the top of the
script, or set it as an environment variable each time:

```bash
export UVTOOLSCMD=~/proj/UVtools/publish/UVtoolsCmd
```

### 8. Usage

```bash
pcb-expose.sh ~/proj/kicad2msla/Dummy.pm4n \
    ~/proj/kicad2msla/gerbers/Flow_Controller_Panel-Front.gtl \
    --invert --mirror --exposure 120 \
    --output ~/proj/kicad2msla/Flow_Controller_Panel-Front.pm4n
```

Multiple files / per-file polarity inversion / merging into one layer:

```bash
pcb-expose.sh Dummy.pm4n \
    Board-F.Cu.gtl Board-B.Cu.gtl \
    --merge --invert-polarity --mirror --exposure 120 \
    --output Board-combined.pm4n
```

---

## Option B: Official release (no compiling required)

Once the maintainer's `FileArray` property ships in an official UVtools
release:

### 1. Download & install the release

Grab the Linux release from the
[UVtools releases page](https://github.com/sn4k3/UVtools/releases) and
extract it, e.g. to `~/UVtools/`. `libcvextern.so` is bundled in official
releases, so no extra steps are needed there.

### 2. Install the wrapper

```bash
# Copy the script
cp ~/proj/kicad2msla/UVtools/pcb-expose-official.sh ~/.local/bin
# Make it executable
chmod +x ~/.local/bin/pcb-expose-official.sh
# Create a symlink
ln -s ~/.local/bin/pcb-expose-official.sh ~/.local/bin/pcb-expose.sh
```

By default it looks for `~/UVtools/UVtoolsCmd`. Override with:

```bash
export UVTOOLSCMD=~/UVtools/UVtoolsCmd
```

### 3. Usage

Same interface as Option A (minus `--invert-polarity`, which the official
`FileArray` property doesn't support per-file):

```bash
pcb-expose.sh ~/proj/kicad2msla/Dummy.pm4n \
    ~/proj/kicad2msla/gerbers/Flow_Controller_Panel-Front.gtl \
    --invert --mirror --exposure 120 \
    --output ~/proj/kicad2msla/Flow_Controller_Panel-Front.pm4n
```

Internally this runs:

```bash
UVtoolsCmd run Dummy.pm4n PCBExposure \
    -p FileArray=Board-F.Cu.gtl \
    -p InvertColor=true \
    -p Mirror=true \
    -p ExposureTime=120 \
    --output Board-F.Cu.pm4n
```

---

## Files in this bundle

| File | Purpose |
|---|---|
| `pcb-expose.patch` | `git apply`-able patch adding the `pcb-expose` command (Option A) |
| `pcb-expose-patched.sh` | Wrapper for the patched local build |
| `pcb-expose-official.sh` | Wrapper for the official release using `run` + `FileArray` |
