@thi.ng/geom-axidraw 0.3.12 → 0.5.0
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.
- package/CHANGELOG.md +24 -1
- package/README.md +56 -3
- package/api.d.ts +37 -0
- package/as-axidraw.d.ts +1 -1
- package/as-axidraw.js +58 -24
- package/as-geometry.js +17 -11
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
- **Last updated**: 2023-03-
|
|
3
|
+
- **Last updated**: 2023-03-22T22:24:21Z
|
|
4
4
|
- **Generator**: [thi.ng/monopub](https://thi.ng/monopub)
|
|
5
5
|
|
|
6
6
|
All notable changes to this project will be documented in this file.
|
|
@@ -9,6 +9,29 @@ See [Conventional Commits](https://conventionalcommits.org/) for commit guidelin
|
|
|
9
9
|
**Note:** Unlisted _patch_ versions only involve non-code or otherwise excluded changes
|
|
10
10
|
and/or version bumps of transitive dependencies.
|
|
11
11
|
|
|
12
|
+
## [0.5.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom-axidraw@0.5.0) (2023-03-22)
|
|
13
|
+
|
|
14
|
+
#### 🚀 Features
|
|
15
|
+
|
|
16
|
+
- add support for new draw commands ([e5e994c](https://github.com/thi-ng/umbrella/commit/e5e994c))
|
|
17
|
+
- update asGeometry() to handle new move commands
|
|
18
|
+
|
|
19
|
+
## [0.4.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom-axidraw@0.4.0) (2023-03-19)
|
|
20
|
+
|
|
21
|
+
#### 🚀 Features
|
|
22
|
+
|
|
23
|
+
- add InterleaveOpts for point clouds ([78012a0](https://github.com/thi-ng/umbrella/commit/78012a0))
|
|
24
|
+
- add InterleaveOpts & docs
|
|
25
|
+
- update AxiDrawAttribs
|
|
26
|
+
- update point cloud processing to support command sequence interleaving
|
|
27
|
+
- add interleave opts support for shape groups ([57783ff](https://github.com/thi-ng/umbrella/commit/57783ff))
|
|
28
|
+
- update asAxiDraw() impl for shape groups
|
|
29
|
+
|
|
30
|
+
#### ♻️ Refactoring
|
|
31
|
+
|
|
32
|
+
- update draw command handling ([18cd5bc](https://github.com/thi-ng/umbrella/commit/18cd5bc))
|
|
33
|
+
- update InterleaveOpts ([0866f9f](https://github.com/thi-ng/umbrella/commit/0866f9f))
|
|
34
|
+
|
|
12
35
|
## [0.3.0](https://github.com/thi-ng/umbrella/tree/@thi.ng/geom-axidraw@0.3.0) (2023-01-10)
|
|
13
36
|
|
|
14
37
|
#### 🚀 Features
|
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ This project is part of the
|
|
|
18
18
|
- [Basic usage & examples](#basic-usage--examples)
|
|
19
19
|
- [Interpolated polygons](#interpolated-polygons)
|
|
20
20
|
- [Clipping](#clipping)
|
|
21
|
+
- [Supporting custom drawing tools](#supporting-custom-drawing-tools)
|
|
21
22
|
- [Status](#status)
|
|
22
23
|
- [Related packages](#related-packages)
|
|
23
24
|
- [Installation](#installation)
|
|
@@ -43,10 +44,10 @@ package is responsible for the actual plotter output...
|
|
|
43
44
|
| circle | circle<sup>(1)</sup> |
|
|
44
45
|
| cubic | cubic bezier segment<sup>(1)</sup> |
|
|
45
46
|
| ellipse | ellipse<sup>(1)</sup> |
|
|
46
|
-
| group | shape group (possibly nested)
|
|
47
|
+
| group | shape group (possibly nested)<sup>(3)</sup> |
|
|
47
48
|
| line | line segment<sup>(2)</sup> |
|
|
48
49
|
| path | single outline only, no holes |
|
|
49
|
-
| points | point cloud (stippling)
|
|
50
|
+
| points | point cloud (stippling)<sup>(3)</sup> |
|
|
50
51
|
| polyline | polyline (any number of vertices)<sup>(2)</sup> |
|
|
51
52
|
| polygon | simple polygon, no holes<sup>(2)</sup> |
|
|
52
53
|
| quad | arbitrary 4-gon<sup>(2)</sup> |
|
|
@@ -56,6 +57,7 @@ package is responsible for the actual plotter output...
|
|
|
56
57
|
|
|
57
58
|
- <sup>(1)</sup> always interpolated/sampled
|
|
58
59
|
- <sup>(2)</sup> only interpolated if forced via attrib
|
|
60
|
+
- <sup>(3)</sup> supports command sequence interleaving
|
|
59
61
|
|
|
60
62
|
### AxiDraw specific shape attributes
|
|
61
63
|
|
|
@@ -81,6 +83,8 @@ any package-specific attribs must be stored under the `__axi` key:
|
|
|
81
83
|
- `sort`: Ordering function (in lieu of full path planning/optimization, which
|
|
82
84
|
is planned for a later stage). For shapes other than `points()`, order of
|
|
83
85
|
appearance is used by default.
|
|
86
|
+
- `interleave`: Currently only supported for point clouds. See [Supporting
|
|
87
|
+
custom drawing tools](#supporting-custom-drawing-tools).
|
|
84
88
|
|
|
85
89
|
```ts
|
|
86
90
|
// a circle which will be plotted at only 10% of the normal speed
|
|
@@ -220,6 +224,55 @@ import { writeFileSync } from "fs";
|
|
|
220
224
|
})();
|
|
221
225
|
```
|
|
222
226
|
|
|
227
|
+
### Supporting custom drawing tools
|
|
228
|
+
|
|
229
|
+
AxiDraw (and other pen plotters) are not restricted to just using pens, but can
|
|
230
|
+
be used with all sorts of custom drawing tools, some of which (like paint
|
|
231
|
+
brushes) require regular "refills" every N strokes/dots. For that reason, some
|
|
232
|
+
shape types (currently **only** shape groups and point clouds) are supporting
|
|
233
|
+
config & behavior options for interleaving their normal shape command sequence
|
|
234
|
+
with additional tool-specific arbitrary utility command sequences (e.g. to
|
|
235
|
+
regularly dip a brush into a paint pot/palette).
|
|
236
|
+
|
|
237
|
+
```ts tangle:export/readme-interleave.ts
|
|
238
|
+
import { AxiDraw, COMMENT, dip, MOVE } from "@thi.ng/axidraw";
|
|
239
|
+
import { circle, points, vertices } from "@thi.ng/geom";
|
|
240
|
+
import { asAxiDraw } from "@thi.ng/geom-axidraw";
|
|
241
|
+
|
|
242
|
+
(async () => {
|
|
243
|
+
// create point cloud container
|
|
244
|
+
const pts = points(
|
|
245
|
+
// using 24 points on a circle w/ origin @ 150,150, radius=100
|
|
246
|
+
vertices(circle([150, 150], 100), 24),
|
|
247
|
+
{ __axi: {
|
|
248
|
+
// use command interleaving
|
|
249
|
+
interleave: {
|
|
250
|
+
// every 5 points/dots
|
|
251
|
+
num: 5,
|
|
252
|
+
// insert these draw commands:
|
|
253
|
+
// (this function is being re-called every `num` points and
|
|
254
|
+
// can produce different commands to insert each time...)
|
|
255
|
+
commands: (n) => [
|
|
256
|
+
// no-op command, but will be logged during plotting
|
|
257
|
+
COMMENT(`--- refill brush (@ ${n} points) ---`),
|
|
258
|
+
// move to XY pos (i.e. position of paint reservoir)
|
|
259
|
+
MOVE([10,50]),
|
|
260
|
+
// dip the brush 3x times down & up (each time wait 200ms whilst down)
|
|
261
|
+
// (dip() creates a cmd sequence, so need to use the spread operator `...` here)
|
|
262
|
+
...dip(3, { downDelay: 200 }),
|
|
263
|
+
// (...and then drawing continues w/ next 5 points)
|
|
264
|
+
]
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// actually connect & send to plotter
|
|
270
|
+
const axi = new AxiDraw();
|
|
271
|
+
await axi.connect();
|
|
272
|
+
await axi.draw(asAxiDraw(pts));
|
|
273
|
+
})();
|
|
274
|
+
```
|
|
275
|
+
|
|
223
276
|
## Status
|
|
224
277
|
|
|
225
278
|
**ALPHA** - bleeding edge / work-in-progress
|
|
@@ -250,7 +303,7 @@ For Node.js REPL:
|
|
|
250
303
|
const geomAxidraw = await import("@thi.ng/geom-axidraw");
|
|
251
304
|
```
|
|
252
305
|
|
|
253
|
-
Package sizes (brotli'd, pre-treeshake): ESM: 1.
|
|
306
|
+
Package sizes (brotli'd, pre-treeshake): ESM: 1.50 KB
|
|
254
307
|
|
|
255
308
|
## Dependencies
|
|
256
309
|
|
package/api.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Fn } from "@thi.ng/api";
|
|
2
|
+
import type { DrawCommand } from "@thi.ng/axidraw";
|
|
2
3
|
import type { IShape, SamplingOpts } from "@thi.ng/geom-api";
|
|
3
4
|
import type { ReadonlyVec } from "@thi.ng/vectors";
|
|
4
5
|
/**
|
|
@@ -58,6 +59,11 @@ export interface AxiDrawAttribs {
|
|
|
58
59
|
* detail test runs.
|
|
59
60
|
*/
|
|
60
61
|
skip: number;
|
|
62
|
+
/**
|
|
63
|
+
* Currently only supported for shape groups and point clouds. See
|
|
64
|
+
* {@link InterleaveOpts} for details.
|
|
65
|
+
*/
|
|
66
|
+
interleave: InterleaveOpts;
|
|
61
67
|
}
|
|
62
68
|
export interface AsAxiDrawOpts {
|
|
63
69
|
/**
|
|
@@ -76,6 +82,37 @@ export interface AsAxiDrawOpts {
|
|
|
76
82
|
*/
|
|
77
83
|
clip: ReadonlyVec[];
|
|
78
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Config & behavior options for interleaving the normal shape command sequence
|
|
87
|
+
* with tool-specific arbitrary utility command sequences (e.g. to regularly dip
|
|
88
|
+
* a brush into a paint pot/palette).
|
|
89
|
+
*/
|
|
90
|
+
export interface InterleaveOpts {
|
|
91
|
+
/**
|
|
92
|
+
* Number of elements after which to insert the interleave command sequence
|
|
93
|
+
*/
|
|
94
|
+
num: number;
|
|
95
|
+
/**
|
|
96
|
+
* Single arg function which is called every `num` elements (with the count
|
|
97
|
+
* of elements already processed given as arg) and each time yielding a
|
|
98
|
+
* [`DrawCommand`](https://docs.thi.ng/umbrella/axidraw/types/DrawCommand.html)
|
|
99
|
+
* sequence, which will be inserted as-is into the generated main command
|
|
100
|
+
* sequence of the currently processed shape.
|
|
101
|
+
*
|
|
102
|
+
* @param num
|
|
103
|
+
*/
|
|
104
|
+
commands: Fn<number, Iterable<DrawCommand>>;
|
|
105
|
+
/**
|
|
106
|
+
* If true (default), call the given `commands` fn at the beginning of the
|
|
107
|
+
* shape processing (with arg=0).
|
|
108
|
+
*/
|
|
109
|
+
start?: boolean;
|
|
110
|
+
/**
|
|
111
|
+
* If true (default: false), call the given `commands` fn at the end of the
|
|
112
|
+
* shape processing (with arg=number of points/elements in the shape).
|
|
113
|
+
*/
|
|
114
|
+
end?: boolean;
|
|
115
|
+
}
|
|
79
116
|
export type PointOrdering = Fn<ReadonlyVec[], Iterable<ReadonlyVec>>;
|
|
80
117
|
export type ShapeOrdering = Fn<IShape[], Iterable<IShape>>;
|
|
81
118
|
//# sourceMappingURL=api.d.ts.map
|
package/as-axidraw.d.ts
CHANGED
package/as-axidraw.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { UP } from "@thi.ng/axidraw/
|
|
1
|
+
import { DOWN, MOVE, UP } from "@thi.ng/axidraw/commands";
|
|
2
2
|
import { polyline } from "@thi.ng/axidraw/polyline";
|
|
3
3
|
import { defmulti } from "@thi.ng/defmulti/defmulti";
|
|
4
4
|
import { clipPolylinePoly } from "@thi.ng/geom-clip-line/clip-poly";
|
|
@@ -69,24 +69,42 @@ export const asAxiDraw = defmulti(__dispatch, {
|
|
|
69
69
|
group: ($, opts) => __group($, opts),
|
|
70
70
|
});
|
|
71
71
|
function* __group($, opts) {
|
|
72
|
-
const
|
|
73
|
-
const
|
|
72
|
+
const $sampleOpts = __sampleAttribs(opts?.samples, $.attribs);
|
|
73
|
+
const { skip, sort, interleave } = __axiAttribs($.attribs);
|
|
74
74
|
const children = skip ? [...takeNth(skip + 1, $.children)] : $.children;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
75
|
+
function* emitChunk(chunk) {
|
|
76
|
+
const iter = sort ? sort(chunk) : chunk;
|
|
77
|
+
for (let child of iter) {
|
|
78
|
+
const shape = applyTransforms(child);
|
|
79
|
+
shape.attribs = {
|
|
80
|
+
...$.attribs,
|
|
81
|
+
...shape.attribs,
|
|
82
|
+
__samples: __sampleAttribs($sampleOpts, shape.attribs),
|
|
83
|
+
};
|
|
84
|
+
yield* asAxiDraw(shape, opts);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (interleave) {
|
|
88
|
+
const { num, commands } = interleave;
|
|
89
|
+
if (interleave.start !== false)
|
|
90
|
+
yield* commands(0);
|
|
91
|
+
for (let i = 0, n = children.length; i < n;) {
|
|
92
|
+
yield* emitChunk(children.slice(i, i + num));
|
|
93
|
+
i += num;
|
|
94
|
+
if (i < n)
|
|
95
|
+
yield* commands(i);
|
|
96
|
+
}
|
|
97
|
+
if (interleave.end)
|
|
98
|
+
yield* interleave.commands(children.length);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
yield* emitChunk(children);
|
|
84
102
|
}
|
|
85
103
|
}
|
|
86
104
|
function* __points(pts, attribs, opts) {
|
|
87
105
|
if (!pts.length)
|
|
88
106
|
return;
|
|
89
|
-
const { clip, delayDown, delayUp, down, skip, speed, sort } = {
|
|
107
|
+
const { clip, delayDown, delayUp, down, skip, speed, sort, interleave } = {
|
|
90
108
|
sort: pointsByNearestNeighbor(),
|
|
91
109
|
...__axiAttribs(attribs),
|
|
92
110
|
};
|
|
@@ -99,18 +117,34 @@ function* __points(pts, attribs, opts) {
|
|
|
99
117
|
if (skip) {
|
|
100
118
|
pts = [...takeNth(skip + 1, pts)];
|
|
101
119
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
120
|
+
function* emitChunk($pts) {
|
|
121
|
+
if (down != undefined)
|
|
122
|
+
yield ["pen", down];
|
|
123
|
+
for (let p of sort ? sort($pts) : $pts) {
|
|
124
|
+
yield MOVE(p, speed);
|
|
125
|
+
yield DOWN(delayDown);
|
|
126
|
+
yield UP(delayUp);
|
|
127
|
+
}
|
|
128
|
+
if (down != undefined)
|
|
129
|
+
yield ["pen"];
|
|
130
|
+
}
|
|
131
|
+
yield UP();
|
|
132
|
+
if (interleave) {
|
|
133
|
+
const { num, commands } = interleave;
|
|
134
|
+
if (interleave.start !== false)
|
|
135
|
+
yield* commands(0);
|
|
136
|
+
for (let i = 0, n = pts.length; i < n;) {
|
|
137
|
+
yield* emitChunk(pts.slice(i, i + num));
|
|
138
|
+
i += num;
|
|
139
|
+
if (i < n)
|
|
140
|
+
yield* commands(i);
|
|
141
|
+
}
|
|
142
|
+
if (interleave.end)
|
|
143
|
+
yield* interleave.commands(pts.length);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
yield* emitChunk(pts);
|
|
111
147
|
}
|
|
112
|
-
if (down != undefined)
|
|
113
|
-
yield ["pen"];
|
|
114
148
|
}
|
|
115
149
|
function* __polyline(pts, attribs, opts) {
|
|
116
150
|
if (!pts.length)
|
package/as-geometry.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { group } from "@thi.ng/geom/group";
|
|
2
2
|
import { points } from "@thi.ng/geom/points";
|
|
3
3
|
import { polyline } from "@thi.ng/geom/polyline";
|
|
4
|
-
import {
|
|
4
|
+
import { add2 } from "@thi.ng/vectors/add";
|
|
5
|
+
import { copy } from "@thi.ng/vectors/copy";
|
|
5
6
|
const DEFAULT_ATTRIBS = {
|
|
6
7
|
paths: { stroke: "#000" },
|
|
7
8
|
rapids: { stroke: "#0ff" },
|
|
@@ -40,19 +41,24 @@ export const asGeometry = (src, opts = {}) => {
|
|
|
40
41
|
let penDown = false;
|
|
41
42
|
let pts = null;
|
|
42
43
|
let currPos = [0, 0];
|
|
44
|
+
const $move = (newPos) => {
|
|
45
|
+
if (penDown || opts.rapids) {
|
|
46
|
+
if (!pts)
|
|
47
|
+
pts = [copy(currPos), newPos];
|
|
48
|
+
else
|
|
49
|
+
pts.push(newPos);
|
|
50
|
+
}
|
|
51
|
+
currPos = newPos;
|
|
52
|
+
};
|
|
43
53
|
for (let cmd of src) {
|
|
44
54
|
switch (cmd[0]) {
|
|
55
|
+
// absolute
|
|
56
|
+
case "M":
|
|
57
|
+
$move(copy(cmd[1]));
|
|
58
|
+
break;
|
|
59
|
+
// relative
|
|
45
60
|
case "m":
|
|
46
|
-
|
|
47
|
-
const newPos = copy(cmd[1]);
|
|
48
|
-
if (penDown || opts.rapids) {
|
|
49
|
-
if (!pts)
|
|
50
|
-
pts = [copy(currPos), newPos];
|
|
51
|
-
else
|
|
52
|
-
pts.push(newPos);
|
|
53
|
-
}
|
|
54
|
-
currPos = newPos;
|
|
55
|
-
}
|
|
61
|
+
$move(add2([], currPos, cmd[1]));
|
|
56
62
|
break;
|
|
57
63
|
case "u":
|
|
58
64
|
if (pts) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thi.ng/geom-axidraw",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Conversion and preparation of thi.ng/geom shapes & shape groups to/from AxiDraw pen plotter draw commands",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./index.js",
|
|
@@ -36,16 +36,16 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"@thi.ng/api": "^8.7.4",
|
|
38
38
|
"@thi.ng/arrays": "^2.5.8",
|
|
39
|
-
"@thi.ng/axidraw": "^
|
|
39
|
+
"@thi.ng/axidraw": "^1.1.0",
|
|
40
40
|
"@thi.ng/compare": "^2.1.27",
|
|
41
41
|
"@thi.ng/defmulti": "^2.1.33",
|
|
42
|
-
"@thi.ng/geom": "^4.
|
|
43
|
-
"@thi.ng/geom-accel": "^3.3.
|
|
44
|
-
"@thi.ng/geom-api": "^3.4.
|
|
45
|
-
"@thi.ng/geom-clip-line": "^2.3.
|
|
46
|
-
"@thi.ng/geom-isec": "^2.1.
|
|
47
|
-
"@thi.ng/transducers": "^8.
|
|
48
|
-
"@thi.ng/vectors": "^7.6.
|
|
42
|
+
"@thi.ng/geom": "^4.3.0",
|
|
43
|
+
"@thi.ng/geom-accel": "^3.3.9",
|
|
44
|
+
"@thi.ng/geom-api": "^3.4.10",
|
|
45
|
+
"@thi.ng/geom-clip-line": "^2.3.10",
|
|
46
|
+
"@thi.ng/geom-isec": "^2.1.52",
|
|
47
|
+
"@thi.ng/transducers": "^8.4.0",
|
|
48
|
+
"@thi.ng/vectors": "^7.6.9"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@microsoft/api-extractor": "^7.34.4",
|
|
@@ -121,5 +121,5 @@
|
|
|
121
121
|
"status": "alpha",
|
|
122
122
|
"year": 2022
|
|
123
123
|
},
|
|
124
|
-
"gitHead": "
|
|
124
|
+
"gitHead": "5b3d731c0e192c53f65efb4baed97be0e4029a33\n"
|
|
125
125
|
}
|