# Minilase

This tool parses and patches Minilase EZCAD save files with values specified in a YAML config file.
The EZCAD format as implemented in this crate was reverse engineered from sample files, so not all formats or options are supported.

TODO:

* Write settings to output file by default
* Figure out some sort of formula to sweep power density

## Usage

``` text
Usage: minilase.exe [OPTIONS] --input <INPUT> <COMMAND>

Commands:
  diff   Diff two .mlp files and print differences between the two
  query  Queries input .mlp file for pen or object info
  apply  Applies configuration YAML to input .mlp file
  help   Print this message or the help of the given subcommand(s)

Options:
  -i, --input <INPUT>  Input .mlp file to parse
  -v, --verbose...     Increase logging verbosity
  -q, --quiet...       Decrease logging verbosity
  -h, --help           Print help
```

### Sub-Commands

Diff two .mlp files and print differences between the two.

``` text
Usage: minilase.exe --input <INPUT> diff [OPTIONS] --diff-file <DIFF_FILE>

Options:
  -d, --diff-file <DIFF_FILE>  File to diff input against
  -v, --verbose...             Increase logging verbosity
  -q, --quiet...               Decrease logging verbosity
  -h, --help                   Print help
```

Queries input .mlp file for pen or object info.

`<Pen>` and `<Object>` supports indexes (`6`) and ranges (`..3`, `2..=3`, or `5..`).

``` text
Usage: minilase.exe --input <INPUT> query [OPTIONS]

Options:
  -p, --pen <PEN>                    Print info for pens
  -o, --object <OBJECT>              Print info for objects
  -b, --object-layer <OBJECT_LAYER>  Object layer to query object on
  -v, --verbose...                   Increase logging verbosity
  -q, --quiet...                     Decrease logging verbosity
  -h, --help                         Print help
```

Applies configuration YAML to input .mlp file.

``` text
Usage: minilase.exe --input <INPUT> apply [OPTIONS] --config <CONFIG>

Options:
  -c, --config <CONFIG>  Configuration file
  -o, --output <OUTPUT>  Output file to write to
  -w, --overwrite        Overwrite output file if it exists
  -v, --verbose...       Increase logging verbosity
  -q, --quiet...         Decrease logging verbosity
  -h, --help             Print help
```

## Configuration File

Operations defined in the configuration file are applied in order of definition.

## Machine Parameters

`<PulseWidth>` can be 2/4/6/8/12/20/30/45/60/80/100/150/200/250/350/500.

Note: each pulse width has a minimum and maximum frequency for model YDFLP-20-M7-S-R:
``` text
2ns => 850kHz to 4MHz
4ns => 500kHz to 4MHz
6ns => 320kHz to 4MHz
8ns => 250kHz to 4MHz
12ns => 170kHz to 3MHz
20ns => 115kHz to 3MHz
30ns => 90kHz to 3MHz
45ns => 75kHz to 2MHz
60ns => 65kHz to 2MHz
80ns => 60kHz to 2MHz
100ns => 45kHz to 1MHz
150ns => 30kHz to 1MHz
200ns => 25kHz to 1MHz
250ns => 25kHz to 900kHz
350ns => 25kHz to 600kHz
500ns => 25kHz to 500kHz
```

Power density of a hatch pattern is estimated using the following formula:

Power density = 1/line spacing * power * 1/speed * frequency * pulse width power

### Pen Operations

Setting values of specific fields for a given pen:

``` yaml
Ops: 
  - !PatchPen
    Pen: 0 # Target pen

    # Specify one or more of the following:
    Color: [127, 127, 127]
    Enabled: true
    LoopCount: 3
    Speed: 1.234
    Power: 10.5
    Frequency: 10000
    PulseWidth: <PulseWidth>
```

Cloning pen(s) (and optionally override settings):

``` yaml
Ops: 
  - !ClonePen
    From: 0
    To: 1

    # Specify one or more of the following:
    Inclusive: true
    
    Patch:
      Color: [64, 64, 64]
      Enabled: true
      LoopCount: 3
      Speed: 1.234
      Power: 10.5
      Frequency: 10000
```

Incrementing a specific field by some value across a sequence of pens:

``` yaml
Ops: 
  - !PatternPen
    Index: 1
    Count: 5
    Field: <PenPattern>
```

Where `<PenPattern>` is one of the following:

``` yaml
Field: !Loops 1
Field: !Speed 100.0
Field: !Power 10.0
Field: !Frequency 1000
Field: !PulseWidth 2 # Increment
```

Randomizing pen values:

``` yaml
Op:
  - !RandomizePen
    Index: 0
    Count: 10
    
    # Specify one or more of the following:
    Speed: [100, 1000, 100] # [min, max, step]
    Power: [10, 100, 5] # [min, max, step]
    Frequency: [20000, 100000, 1000] # [min, max, step]
    PulseWidth: [2, 350, 2] # [min, max, step]

    PowerDensity: [10000, 1000000] # [min, max]

    EnforceLimits: bool # Enforces pulse width / frequency limitations
```

Exporting a pen to a file:

``` yaml
Ops:
  - !ExportPen
    Index: 0
    Path: "exported_pen.bin"
```

Importing a pen from a file:

``` yaml
Ops:
  - !ImportPen
    Index: 0
    Path: "exported_pen.bin"
```

### Object Operations

Deleting all objects from a layer:

``` yaml
Ops:
  - !DeleteObjects
    Layer: 0
    Object: 3 # Optional, will delete specific object instead
```

All other operations:

``` yaml
Ops:
  - !Object
    Input: <InputObject>

    # Specify one or more of the following
    Z: 0.0
    Origin: { X: 10.0, Y: 10.0 }
    Pen: 3
    Layer: 2
    Array: <ArrayOptions>
    Hatch: <HatchOptions>
    Export: "exported_object.bin"
    ReplaceObject: 0
```

Where `<InputObject>` is one of the following:

``` yaml
Input: !Rectangle { Width: 3.0, Height: 2.0 }
Input: !Circle { Radius: 3.0 }
Input: !Import { Path: "exported_object.bin" }
Input: !Existing { Layer: 0, Object: 1 }
```

Where `<ArrayOptions>` is:

``` yaml
Array:
  Columns: 3
  Rows: 2
  Spacing: 1.0
  RandomizeOrder: True
  StartingPen: 1
  PatternPenX: <PenPattern> // Optional
  PatternPenY: <PenPattern> // Optional
  PatternHatchX: <HatchPattern> // Optional
  PatternHatchY: <HatchPattern> // Optional
```

Where `<HatchPattern>` is one of the following:

``` yaml
Field: !Count 1
Field: !LineSpacing 0.001
Field: !EdgeOffset 0.1
Field: !StartOffset 0.1
Field: !EndOffset 0.1
Field: !Angle 45.0
Field: !RotateAngle 45.0
Field: !LineReduction 1.0
Field: !LoopDistance 1.0
Field: !LoopCount 1
```
Where `<HatchOptions>` is:

``` yaml
Hatch:
  LineSpacing: 0.1

  # Specify one or more of the following
  Pen: 1
  Count: 3
  EdgeOffset: 0.0
  StartOffset: 0.0
  EndOffset: 0.0
  Angle: 3.0
  RotateAngle: 0.0
  LineReduction: 0.0
  LoopDistance: 0.0
  LoopCount: 0.0
  Pattern: <Pattern>
  FollowEdgeOnce: True
  Crosshatch: True
```

Where `<Pattern>` is one of the following:

``` yaml
Pattern: !Directional
Pattern: !Bidirectional
Pattern: !Ring
Pattern: !Continuous
Pattern: !Gong
Pattern: !Background # (not supported)
Pattern: !Fill
Pattern: !Zigzag
```

## Settings

### Stainless Steel (mirror finish)

