plottool 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
plottool-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Till Uhde
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,227 @@
1
+ Metadata-Version: 2.4
2
+ Name: plottool
3
+ Version: 0.1.0
4
+ Summary: HPGL plotter/cutter tool with serial port support, path optimization, blade offset compensation, preview, and weeding lines
5
+ Author-email: Till Uhde <till@uhde.com>
6
+ License-Expression: MIT
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: Operating System :: OS Independent
9
+ Classifier: Topic :: Utilities
10
+ Requires-Python: >=3.7
11
+ Description-Content-Type: text/markdown
12
+ License-File: LICENSE
13
+ Requires-Dist: pyserial
14
+ Requires-Dist: numpy
15
+ Requires-Dist: wxPython
16
+ Dynamic: license-file
17
+
18
+ plottool
19
+ ========
20
+
21
+ A tool for sending HPGL files to a plotter or cutting plotter connected over a
22
+ serial port. Includes path optimization, blade offset compensation, scaling,
23
+ rotation, tiling, weeding lines, config profiles, and a graphical preview window.
24
+
25
+ Tested with a Cogi CT-630 cutting plotter @ Stratum0:
26
+ https://stratum0.org/wiki/Cogi_CT-630
27
+
28
+ Also works on macOS, but less reliably — prepare for occasional job cancellation.
29
+
30
+ > Forked from [stratum0/plottool](https://github.com/stratum0/plottool).
31
+
32
+ > This project is being actively extended with the help of
33
+ > [Claude Code](https://claude.ai/code) (Anthropic AI).
34
+
35
+
36
+ Dependencies
37
+ ------------
38
+
39
+ For Debian-based Linux distributions (Ubuntu, Mint):
40
+
41
+ ```
42
+ sudo apt-get install python3-serial python3-wxgtk4.0 python3-numpy
43
+ ```
44
+
45
+ For Arch Linux:
46
+
47
+ ```
48
+ sudo pacman -S python-numpy python-pyserial python-wxpython
49
+ ```
50
+
51
+ For macOS (homebrew + pip):
52
+
53
+ ```
54
+ pip install numpy pyserial && brew install wxpython
55
+ ```
56
+
57
+ Or install via pip from the repository root:
58
+
59
+ ```
60
+ pip install .
61
+ ```
62
+
63
+
64
+ Usage — plottool.py
65
+ --------------------
66
+
67
+ Send an HPGL file to the plotter:
68
+
69
+ ```
70
+ ./plottool.py file.hpgl
71
+ ./plottool.py file.hpgl -m --width 200
72
+ ./plottool.py file.hpgl --profile vinyl
73
+ ```
74
+
75
+ **Options:**
76
+
77
+ | Flag | Default | Description |
78
+ |------|---------|-------------|
79
+ | `--profile NAME` | — | Load a config profile (see Config file) |
80
+ | `-p`, `--port PORT` | `/dev/ttyUSB0` | Serial port |
81
+ | `-b`, `--baud BAUD` | `9600` | Serial baud rate |
82
+ | `-m`, `--magic` | off | Auto-optimize: point reduction + blade offset + reroute |
83
+ | `-w`, `--width MM` | — | Scale to width in mm (mutually exclusive with `-H`, `-s`) |
84
+ | `-H`, `--height MM` | — | Scale to height in mm (mutually exclusive with `-w`, `-s`) |
85
+ | `-s`, `--scale FACTOR` | — | Scale by factor, e.g. `0.5` for half size (mutually exclusive with `-w`, `-H`) |
86
+ | `--mirror` | off | Flip left-right (for inverted cuts, e.g. T-shirts) |
87
+ | `--flip` | off | Flip top-bottom |
88
+ | `--rotate DEG` | — | Rotate counter-clockwise by DEG degrees (uses axis swaps at multiples of 90°) |
89
+ | `-v`, `--preview` | off | Show preview window before plotting |
90
+ | `-o`, `--output FILE` | — | Save processed HPGL to FILE before plotting |
91
+ | `--pen` | off | Disable blade offset compensation (use for pen plotters) |
92
+ | `--blade-offset MM` | `0.25` | Blade trailing offset in mm (ignored with `--pen`) |
93
+ | `--no-blade-prep` | off | Skip the 2 mm seating cut at origin |
94
+ | `--reroute {xy,nearest,none}` | `xy` | Path order: `xy` = boustrophedon rows, `nearest` = greedy nearest-neighbour, `none` = original |
95
+ | `--repeat-x N` | `1` | Tile the design N times along X |
96
+ | `--repeat-y N` | `1` | Tile the design N times along Y |
97
+ | `--gap MM` | `5` | Gap between tiles (both axes) |
98
+ | `--gap-x MM` | — | Gap along X, overrides `--gap` (negative = overlap) |
99
+ | `--gap-y MM` | — | Gap along Y, overrides `--gap` (negative = overlap) |
100
+ | `--offset-x MM` | `0` | X offset per Y-step (stagger rows) |
101
+ | `--offset-y MM` | `0` | Y offset per X-step (stagger columns) |
102
+ | `--weed STRATEGY` | — | Add weeding lines (see Weeding lines) |
103
+ | `--weed-size PCT` | `25` | Max waste piece size as % of bbox area |
104
+ | `--weed-min-x MM` | `1` | Min spacing between vertical weeding lines |
105
+ | `--weed-max-x MM` | — | Max spacing between vertical weeding lines |
106
+ | `--weed-min-y MM` | `1` | Min spacing between horizontal weeding lines |
107
+ | `--weed-max-y MM` | — | Max spacing between horizontal weeding lines |
108
+ | `--weed-margin MM` | `2` | Extend weeding lines beyond bbox |
109
+ | `--weed-tick-length MM` | `5` | Tick/comb tooth length |
110
+ | `--weed-small-size PCT` | auto | Radial inner circle area (default: weed-size/10) |
111
+ | `--weed-min-size PCT` | auto | Drop lines creating waste pieces smaller than this |
112
+ | `--weed-frame-distance MM` | `1` | Distance of outer frame from bbox |
113
+ | `--no-weed-frame` | — | Suppress the automatic outer frame |
114
+ | `--no-weed-adaptive` | — | Disable adaptive clipping at design intersections |
115
+
116
+ On macOS, serial devices follow a different naming convention — look for something
117
+ like `/dev/tty.usbserial-14430` or `/dev/cu.usbserial-14430`.
118
+
119
+
120
+ Usage — hpgl.py
121
+ ----------------
122
+
123
+ Process an HPGL file without plotting (convert, optimise, preview, export):
124
+
125
+ ```
126
+ ./hpgl.py file.hpgl -o out.hpgl -p preview.svg
127
+ ./hpgl.py file.hpgl -m --rotate 90 -o out.hpgl
128
+ ```
129
+
130
+ Supports all flags from `plottool.py` except `--port`, `--baud`, and `--preview`
131
+ (which is `-p SVG` here, exporting to an SVG file instead of opening a window).
132
+
133
+
134
+ Processing pipeline
135
+ -------------------
136
+
137
+ When multiple options are active, they are applied in this order:
138
+
139
+ 1. **Scale** (`--width` / `--height` / `--scale`)
140
+ 2. **Rotate** (`--rotate`)
141
+ 3. **Mirror** (`--mirror`) — flip left-right
142
+ 4. **Flip** (`--flip`) — flip top-bottom
143
+ 5. **Optimize** (`--magic`) — remove redundant points, fit to origin
144
+ 6. **Blade offset** (`--magic`) — overshoot correction at corners
145
+ 7. **Tile** (`--repeat-x` / `--repeat-y`)
146
+ 8. **Weeding lines** (`--weed`)
147
+ 9. **Reroute** (`--reroute`) — reorder paths for travel efficiency
148
+ 10. **Blade prep cut** — 2 mm seating cut prepended at origin (disable with `--no-blade-prep`)
149
+
150
+
151
+ Weeding lines
152
+ -------------
153
+
154
+ Add cut lines to help remove waste vinyl after cutting. Select a strategy with
155
+ `--weed STRATEGY`:
156
+
157
+ | Strategy | Description |
158
+ |----------|-------------|
159
+ | `grid` | Horizontal + vertical lines across the bbox |
160
+ | `horizontal` | Horizontal lines only |
161
+ | `vertical` | Vertical lines only |
162
+ | `diagonal` | 45° lines across the bbox |
163
+ | `rombic` | Both diagonal families (diamond grid) |
164
+ | `frame` | Concentric equal-area rectangles stepping inward |
165
+ | `tick` | Short inward comb-teeth from each bbox edge |
166
+ | `radial` | Evenly-angled spokes from the bbox centre |
167
+
168
+ Line density is controlled by `--weed-size PCT` (max waste piece size as % of bbox
169
+ area, default 25). All strategies support **adaptive clipping** (default on): weeding
170
+ lines are split at design intersections so only waste-area segments are kept. An outer
171
+ frame rectangle (1 mm from bbox by default) is added automatically.
172
+
173
+ See [WEEDING_LINES.md](WEEDING_LINES.md) for full parameter details.
174
+
175
+
176
+ Config file
177
+ -----------
178
+
179
+ Settings can be stored in `~/.plottoolrc` (global) or `plottool.conf` in the current
180
+ directory (local, takes precedence). The format is INI:
181
+
182
+ ```ini
183
+ [default]
184
+ magic = true
185
+ blade-offset = 0.3
186
+
187
+ [vinyl]
188
+ width = 300
189
+ reroute = nearest
190
+
191
+ [shirt]
192
+ mirror = true
193
+ width = 300
194
+
195
+ [pen]
196
+ pen = true
197
+ no-blade-prep = true
198
+ ```
199
+
200
+ The `[default]` section always applies. Use `--profile NAME` to also apply a named
201
+ section on top. Command-line arguments always override config values. See
202
+ `plottool.conf.example` for a full annotated example.
203
+
204
+
205
+ Preview window
206
+ --------------
207
+
208
+ The preview window (`-v` in `plottool.py`, `-p SVG` exports to file in `hpgl.py`)
209
+ shows the processed paths with:
210
+
211
+ - Direction arrows on cut paths, travel moves, and the return-to-origin line
212
+ - Dotted travel (pen-up) lines
213
+ - Start-of-cut (filled blue dot) and end-of-cut (blue ring) markers at every pen transition
214
+ - The design bounding box before weeding lines are added (green rectangle)
215
+
216
+ Interactive controls (plottool.py preview window):
217
+
218
+ | Input | Action |
219
+ |-------|--------|
220
+ | Left-drag | Pan |
221
+ | Scroll wheel | Zoom (centred on cursor) |
222
+ | `+` / `=` | Zoom in |
223
+ | `-` | Zoom out |
224
+ | `f` | Fit view |
225
+ | Arrow keys | Pan |
226
+ | Enter | Confirm and proceed to plot |
227
+ | Esc | Cancel |
@@ -0,0 +1,210 @@
1
+ plottool
2
+ ========
3
+
4
+ A tool for sending HPGL files to a plotter or cutting plotter connected over a
5
+ serial port. Includes path optimization, blade offset compensation, scaling,
6
+ rotation, tiling, weeding lines, config profiles, and a graphical preview window.
7
+
8
+ Tested with a Cogi CT-630 cutting plotter @ Stratum0:
9
+ https://stratum0.org/wiki/Cogi_CT-630
10
+
11
+ Also works on macOS, but less reliably — prepare for occasional job cancellation.
12
+
13
+ > Forked from [stratum0/plottool](https://github.com/stratum0/plottool).
14
+
15
+ > This project is being actively extended with the help of
16
+ > [Claude Code](https://claude.ai/code) (Anthropic AI).
17
+
18
+
19
+ Dependencies
20
+ ------------
21
+
22
+ For Debian-based Linux distributions (Ubuntu, Mint):
23
+
24
+ ```
25
+ sudo apt-get install python3-serial python3-wxgtk4.0 python3-numpy
26
+ ```
27
+
28
+ For Arch Linux:
29
+
30
+ ```
31
+ sudo pacman -S python-numpy python-pyserial python-wxpython
32
+ ```
33
+
34
+ For macOS (homebrew + pip):
35
+
36
+ ```
37
+ pip install numpy pyserial && brew install wxpython
38
+ ```
39
+
40
+ Or install via pip from the repository root:
41
+
42
+ ```
43
+ pip install .
44
+ ```
45
+
46
+
47
+ Usage — plottool.py
48
+ --------------------
49
+
50
+ Send an HPGL file to the plotter:
51
+
52
+ ```
53
+ ./plottool.py file.hpgl
54
+ ./plottool.py file.hpgl -m --width 200
55
+ ./plottool.py file.hpgl --profile vinyl
56
+ ```
57
+
58
+ **Options:**
59
+
60
+ | Flag | Default | Description |
61
+ |------|---------|-------------|
62
+ | `--profile NAME` | — | Load a config profile (see Config file) |
63
+ | `-p`, `--port PORT` | `/dev/ttyUSB0` | Serial port |
64
+ | `-b`, `--baud BAUD` | `9600` | Serial baud rate |
65
+ | `-m`, `--magic` | off | Auto-optimize: point reduction + blade offset + reroute |
66
+ | `-w`, `--width MM` | — | Scale to width in mm (mutually exclusive with `-H`, `-s`) |
67
+ | `-H`, `--height MM` | — | Scale to height in mm (mutually exclusive with `-w`, `-s`) |
68
+ | `-s`, `--scale FACTOR` | — | Scale by factor, e.g. `0.5` for half size (mutually exclusive with `-w`, `-H`) |
69
+ | `--mirror` | off | Flip left-right (for inverted cuts, e.g. T-shirts) |
70
+ | `--flip` | off | Flip top-bottom |
71
+ | `--rotate DEG` | — | Rotate counter-clockwise by DEG degrees (uses axis swaps at multiples of 90°) |
72
+ | `-v`, `--preview` | off | Show preview window before plotting |
73
+ | `-o`, `--output FILE` | — | Save processed HPGL to FILE before plotting |
74
+ | `--pen` | off | Disable blade offset compensation (use for pen plotters) |
75
+ | `--blade-offset MM` | `0.25` | Blade trailing offset in mm (ignored with `--pen`) |
76
+ | `--no-blade-prep` | off | Skip the 2 mm seating cut at origin |
77
+ | `--reroute {xy,nearest,none}` | `xy` | Path order: `xy` = boustrophedon rows, `nearest` = greedy nearest-neighbour, `none` = original |
78
+ | `--repeat-x N` | `1` | Tile the design N times along X |
79
+ | `--repeat-y N` | `1` | Tile the design N times along Y |
80
+ | `--gap MM` | `5` | Gap between tiles (both axes) |
81
+ | `--gap-x MM` | — | Gap along X, overrides `--gap` (negative = overlap) |
82
+ | `--gap-y MM` | — | Gap along Y, overrides `--gap` (negative = overlap) |
83
+ | `--offset-x MM` | `0` | X offset per Y-step (stagger rows) |
84
+ | `--offset-y MM` | `0` | Y offset per X-step (stagger columns) |
85
+ | `--weed STRATEGY` | — | Add weeding lines (see Weeding lines) |
86
+ | `--weed-size PCT` | `25` | Max waste piece size as % of bbox area |
87
+ | `--weed-min-x MM` | `1` | Min spacing between vertical weeding lines |
88
+ | `--weed-max-x MM` | — | Max spacing between vertical weeding lines |
89
+ | `--weed-min-y MM` | `1` | Min spacing between horizontal weeding lines |
90
+ | `--weed-max-y MM` | — | Max spacing between horizontal weeding lines |
91
+ | `--weed-margin MM` | `2` | Extend weeding lines beyond bbox |
92
+ | `--weed-tick-length MM` | `5` | Tick/comb tooth length |
93
+ | `--weed-small-size PCT` | auto | Radial inner circle area (default: weed-size/10) |
94
+ | `--weed-min-size PCT` | auto | Drop lines creating waste pieces smaller than this |
95
+ | `--weed-frame-distance MM` | `1` | Distance of outer frame from bbox |
96
+ | `--no-weed-frame` | — | Suppress the automatic outer frame |
97
+ | `--no-weed-adaptive` | — | Disable adaptive clipping at design intersections |
98
+
99
+ On macOS, serial devices follow a different naming convention — look for something
100
+ like `/dev/tty.usbserial-14430` or `/dev/cu.usbserial-14430`.
101
+
102
+
103
+ Usage — hpgl.py
104
+ ----------------
105
+
106
+ Process an HPGL file without plotting (convert, optimise, preview, export):
107
+
108
+ ```
109
+ ./hpgl.py file.hpgl -o out.hpgl -p preview.svg
110
+ ./hpgl.py file.hpgl -m --rotate 90 -o out.hpgl
111
+ ```
112
+
113
+ Supports all flags from `plottool.py` except `--port`, `--baud`, and `--preview`
114
+ (which is `-p SVG` here, exporting to an SVG file instead of opening a window).
115
+
116
+
117
+ Processing pipeline
118
+ -------------------
119
+
120
+ When multiple options are active, they are applied in this order:
121
+
122
+ 1. **Scale** (`--width` / `--height` / `--scale`)
123
+ 2. **Rotate** (`--rotate`)
124
+ 3. **Mirror** (`--mirror`) — flip left-right
125
+ 4. **Flip** (`--flip`) — flip top-bottom
126
+ 5. **Optimize** (`--magic`) — remove redundant points, fit to origin
127
+ 6. **Blade offset** (`--magic`) — overshoot correction at corners
128
+ 7. **Tile** (`--repeat-x` / `--repeat-y`)
129
+ 8. **Weeding lines** (`--weed`)
130
+ 9. **Reroute** (`--reroute`) — reorder paths for travel efficiency
131
+ 10. **Blade prep cut** — 2 mm seating cut prepended at origin (disable with `--no-blade-prep`)
132
+
133
+
134
+ Weeding lines
135
+ -------------
136
+
137
+ Add cut lines to help remove waste vinyl after cutting. Select a strategy with
138
+ `--weed STRATEGY`:
139
+
140
+ | Strategy | Description |
141
+ |----------|-------------|
142
+ | `grid` | Horizontal + vertical lines across the bbox |
143
+ | `horizontal` | Horizontal lines only |
144
+ | `vertical` | Vertical lines only |
145
+ | `diagonal` | 45° lines across the bbox |
146
+ | `rombic` | Both diagonal families (diamond grid) |
147
+ | `frame` | Concentric equal-area rectangles stepping inward |
148
+ | `tick` | Short inward comb-teeth from each bbox edge |
149
+ | `radial` | Evenly-angled spokes from the bbox centre |
150
+
151
+ Line density is controlled by `--weed-size PCT` (max waste piece size as % of bbox
152
+ area, default 25). All strategies support **adaptive clipping** (default on): weeding
153
+ lines are split at design intersections so only waste-area segments are kept. An outer
154
+ frame rectangle (1 mm from bbox by default) is added automatically.
155
+
156
+ See [WEEDING_LINES.md](WEEDING_LINES.md) for full parameter details.
157
+
158
+
159
+ Config file
160
+ -----------
161
+
162
+ Settings can be stored in `~/.plottoolrc` (global) or `plottool.conf` in the current
163
+ directory (local, takes precedence). The format is INI:
164
+
165
+ ```ini
166
+ [default]
167
+ magic = true
168
+ blade-offset = 0.3
169
+
170
+ [vinyl]
171
+ width = 300
172
+ reroute = nearest
173
+
174
+ [shirt]
175
+ mirror = true
176
+ width = 300
177
+
178
+ [pen]
179
+ pen = true
180
+ no-blade-prep = true
181
+ ```
182
+
183
+ The `[default]` section always applies. Use `--profile NAME` to also apply a named
184
+ section on top. Command-line arguments always override config values. See
185
+ `plottool.conf.example` for a full annotated example.
186
+
187
+
188
+ Preview window
189
+ --------------
190
+
191
+ The preview window (`-v` in `plottool.py`, `-p SVG` exports to file in `hpgl.py`)
192
+ shows the processed paths with:
193
+
194
+ - Direction arrows on cut paths, travel moves, and the return-to-origin line
195
+ - Dotted travel (pen-up) lines
196
+ - Start-of-cut (filled blue dot) and end-of-cut (blue ring) markers at every pen transition
197
+ - The design bounding box before weeding lines are added (green rectangle)
198
+
199
+ Interactive controls (plottool.py preview window):
200
+
201
+ | Input | Action |
202
+ |-------|--------|
203
+ | Left-drag | Pan |
204
+ | Scroll wheel | Zoom (centred on cursor) |
205
+ | `+` / `=` | Zoom in |
206
+ | `-` | Zoom out |
207
+ | `f` | Fit view |
208
+ | Arrow keys | Pan |
209
+ | Enter | Confirm and proceed to plot |
210
+ | Esc | Cancel |