@mylasertools/kerfscript 0.0.0-stage → 0.2.1
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 +60 -0
- package/CLA.md +76 -0
- package/COMMERCIAL-LICENSE.md +63 -0
- package/LANGUAGE.md +398 -0
- package/LICENSE +661 -0
- package/README.md +187 -2
- package/THIRD-PARTY-NOTICES.md +124 -0
- package/TRADEMARKS.md +45 -0
- package/dist/ast.d.cts +160 -0
- package/dist/ast.d.ts +160 -0
- package/dist/cli.d.cts +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +19416 -0
- package/dist/customizer.d.cts +19 -0
- package/dist/customizer.d.ts +19 -0
- package/dist/evaluator.d.cts +129 -0
- package/dist/evaluator.d.ts +129 -0
- package/dist/export/dxf.d.cts +3 -0
- package/dist/export/dxf.d.ts +3 -0
- package/dist/export/svg.d.cts +15 -0
- package/dist/export/svg.d.ts +15 -0
- package/dist/functions.d.cts +4 -0
- package/dist/functions.d.ts +4 -0
- package/dist/geometry.d.cts +44 -0
- package/dist/geometry.d.ts +44 -0
- package/dist/index.cjs +44 -0
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +44 -0
- package/dist/joinery.d.cts +7 -0
- package/dist/joinery.d.ts +7 -0
- package/dist/lexer.d.cts +28 -0
- package/dist/lexer.d.ts +28 -0
- package/dist/parser.d.cts +6 -0
- package/dist/parser.d.ts +6 -0
- package/dist/paths.d.cts +28 -0
- package/dist/paths.d.ts +28 -0
- package/dist/render.d.cts +58 -0
- package/dist/render.d.ts +58 -0
- package/dist/stdlib.d.cts +1 -0
- package/dist/stdlib.d.ts +1 -0
- package/dist/text.d.cts +36 -0
- package/dist/text.d.ts +36 -0
- package/dist/values.d.cts +25 -0
- package/dist/values.d.ts +25 -0
- package/docs/cli.md +76 -0
- package/docs/compatibility.md +64 -0
- package/docs/customizer.md +74 -0
- package/docs/getting-started.md +115 -0
- package/docs/javascript.md +153 -0
- package/docs/kerf.md +67 -0
- package/docs/layers.md +108 -0
- package/docs/openscad.md +71 -0
- package/docs/parts-and-sheets.md +82 -0
- package/docs/versions.md +33 -0
- package/package.json +86 -4
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Getting started
|
|
2
|
+
|
|
3
|
+
Make a small sign with two hanging holes and engraved text. You can follow
|
|
4
|
+
this guide in the [playground](https://kerfscript.mylasertools.com/playground/)
|
|
5
|
+
without installing anything.
|
|
6
|
+
|
|
7
|
+
## Your first part
|
|
8
|
+
|
|
9
|
+
Clear the playground editor and enter:
|
|
10
|
+
|
|
11
|
+
```kerf
|
|
12
|
+
rect([80, 50], r = 4);
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This draws an 80 × 50 mm rectangle with 4 mm corner radii. KerfScript uses
|
|
16
|
+
millimetres for lengths and degrees for angles. Shapes go on the cut layer
|
|
17
|
+
unless you assign another layer.
|
|
18
|
+
|
|
19
|
+
## Holes
|
|
20
|
+
|
|
21
|
+
Replace the rectangle with this code:
|
|
22
|
+
|
|
23
|
+
```kerf
|
|
24
|
+
difference() {
|
|
25
|
+
rect([80, 50], r = 4);
|
|
26
|
+
translate([10, 25]) circle(d = 5);
|
|
27
|
+
translate([70, 25]) circle(d = 5);
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`difference()` subtracts the two circles from the rectangle. Each hole is
|
|
32
|
+
5 mm across, centred 10 mm from a side and halfway up the sign.
|
|
33
|
+
|
|
34
|
+
`translate([x, y])` moves a shape. The x axis points right and the y axis
|
|
35
|
+
points up. A rectangle starts at `[0, 0]`; use `center = true` to centre it
|
|
36
|
+
on that point.
|
|
37
|
+
|
|
38
|
+
## Engraving and scoring
|
|
39
|
+
|
|
40
|
+
Add a scored border and engraved text:
|
|
41
|
+
|
|
42
|
+
```kerf
|
|
43
|
+
difference() {
|
|
44
|
+
rect([80, 50], r = 4);
|
|
45
|
+
translate([10, 25]) circle(d = 5);
|
|
46
|
+
translate([70, 25]) circle(d = 5);
|
|
47
|
+
}
|
|
48
|
+
score() translate([20, 10]) rect([40, 30], r = 2);
|
|
49
|
+
engrave() translate([40, 25])
|
|
50
|
+
text("Oak", size = 10, halign = "center", valign = "center");
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`score()` marks the border's outline. `engrave()` fills the letters. Both
|
|
54
|
+
stay within the sign's cut outline, excluding the holes. The playground
|
|
55
|
+
supplies a font for this example.
|
|
56
|
+
|
|
57
|
+
See [Layers](layers.md) for custom layers and guide lines.
|
|
58
|
+
|
|
59
|
+
## Settings
|
|
60
|
+
|
|
61
|
+
Give dimensions names so you can change them without editing every shape:
|
|
62
|
+
|
|
63
|
+
```kerf
|
|
64
|
+
width = 80; // [40:5:200]
|
|
65
|
+
height = 50; // [30:5:120]
|
|
66
|
+
label = "Oak";
|
|
67
|
+
|
|
68
|
+
difference() {
|
|
69
|
+
rect([width, height], r = 4);
|
|
70
|
+
translate([10, height / 2]) circle(d = 5);
|
|
71
|
+
translate([width - 10, height / 2]) circle(d = 5);
|
|
72
|
+
}
|
|
73
|
+
engrave() translate([width / 2, height / 2])
|
|
74
|
+
text(label, size = 10, halign = "center", valign = "center");
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The comments create sliders for width and height. `[40:5:200]` means a
|
|
78
|
+
minimum of 40, a step of 5 and a maximum of 200. `label` becomes a text
|
|
79
|
+
field. The text and holes stay centred as the dimensions change.
|
|
80
|
+
|
|
81
|
+
In the playground, changing a control also updates its value in the code.
|
|
82
|
+
See [Settings](customizer.md) for menus, groups and captions.
|
|
83
|
+
|
|
84
|
+
## Kerf
|
|
85
|
+
|
|
86
|
+
The beam removes some material along each cut. To account for that width,
|
|
87
|
+
add your measured kerf near the top of the program:
|
|
88
|
+
|
|
89
|
+
```kerf
|
|
90
|
+
$kerf = 0.15;
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Here, `0.15` is an example in millimetres. Use the
|
|
94
|
+
[calibration square](../examples/calibration-square.kerf) to measure a value
|
|
95
|
+
for your machine and material. [Kerf](kerf.md) explains the measurement and
|
|
96
|
+
how it affects the exported outlines.
|
|
97
|
+
|
|
98
|
+
## Getting the file
|
|
99
|
+
|
|
100
|
+
Choose **SVG** or **DXF** in the playground, then open the file in your laser
|
|
101
|
+
software. Assign the cut, score and engrave layers their power, speed and
|
|
102
|
+
operation order. In DXF, set engraved areas to fill.
|
|
103
|
+
|
|
104
|
+
If you used `$kerf`, leave kerf compensation off in the laser software to
|
|
105
|
+
avoid applying it twice. The [import guide](compatibility.md) covers sizes,
|
|
106
|
+
layers and tested programs.
|
|
107
|
+
|
|
108
|
+
Download **.kerf** to keep an editable copy of the design.
|
|
109
|
+
|
|
110
|
+
## Next
|
|
111
|
+
|
|
112
|
+
- [Layers](layers.md): separate cutting, scoring and engraving.
|
|
113
|
+
- [Parts and sheets](parts-and-sheets.md): arrange several parts by material.
|
|
114
|
+
- [Coming from OpenSCAD](openscad.md): adapt an existing 2D design.
|
|
115
|
+
- [Language reference](../LANGUAGE.md): look up syntax and functions.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# JavaScript API
|
|
2
|
+
|
|
3
|
+
Add KerfScript rendering to a JavaScript application with the
|
|
4
|
+
`@mylasertools/kerfscript` package. The library runs in browsers and Node.js
|
|
5
|
+
and includes TypeScript definitions.
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install @mylasertools/kerfscript
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## render()
|
|
12
|
+
|
|
13
|
+
Pass a program as a string. The result contains its geometry, files, parts
|
|
14
|
+
and warnings:
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
import { render } from '@mylasertools/kerfscript';
|
|
18
|
+
|
|
19
|
+
const source = 'width = 80; rect([width, 50]);';
|
|
20
|
+
const result = render(source, {
|
|
21
|
+
params: { width: 120 },
|
|
22
|
+
sheet: [600, 400],
|
|
23
|
+
margin: 0,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
console.log(result.svg);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
This exports a 120 × 50 mm rectangle. `params` overrides `width` without
|
|
30
|
+
changing the source string.
|
|
31
|
+
|
|
32
|
+
### Options
|
|
33
|
+
|
|
34
|
+
| Option | Value |
|
|
35
|
+
| --- | --- |
|
|
36
|
+
| `params` | Parameter values keyed by name |
|
|
37
|
+
| `fonts` | Font files keyed by name, as `ArrayBuffer` or `Uint8Array` |
|
|
38
|
+
| `defaultFont` | Name to use when `text()` does not specify a font |
|
|
39
|
+
| `resolve` | `(path) => source` callback for libraries outside the standard library |
|
|
40
|
+
| `kerf` | Kerf override for every part, in millimetres |
|
|
41
|
+
| `layout` | `"pack"` or `"none"` |
|
|
42
|
+
| `sheet` | `[width, height]` in millimetres |
|
|
43
|
+
| `gap` | Space between parts, in millimetres |
|
|
44
|
+
| `margin` | Space at sheet edges, in millimetres; defaults to `gap` |
|
|
45
|
+
| `guides` | Whether to include guide geometry |
|
|
46
|
+
| `maxSteps` | Evaluation step limit |
|
|
47
|
+
| `limits` | Memory limits, see below; any you leave out keep their default |
|
|
48
|
+
|
|
49
|
+
Supply a font for programs that use text:
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
const response = await fetch('/fonts/Inter.ttf');
|
|
53
|
+
const font = await response.arrayBuffer();
|
|
54
|
+
const result = render(source, {
|
|
55
|
+
fonts: { Inter: font },
|
|
56
|
+
defaultFont: 'Inter',
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The URL should point to a font file provided by your application.
|
|
61
|
+
|
|
62
|
+
### Result
|
|
63
|
+
|
|
64
|
+
| Field | Contents |
|
|
65
|
+
| --- | --- |
|
|
66
|
+
| `svg` | Combined SVG containing all sheets |
|
|
67
|
+
| `width`, `height` | Combined SVG dimensions in millimetres |
|
|
68
|
+
| `sheets` | Each sheet's dimensions, material, thickness, SVG, DXF, paths and placed items |
|
|
69
|
+
| `parts` | Part names, quantities, dimensions, piece counts, cut lengths and material properties |
|
|
70
|
+
| `paths` | Layer paths with `name`, `mode`, `color`, `d`, `regions` and `lines` |
|
|
71
|
+
| `layers` | Layer definitions in output order |
|
|
72
|
+
| `warnings` | Problems that did not stop the render |
|
|
73
|
+
| `echoes` | Output from the program's `echo()` calls |
|
|
74
|
+
|
|
75
|
+
Use `result.svg` for a combined preview. Use `result.sheets[i].svg` or
|
|
76
|
+
`.dxf` to export individual sheets, particularly when they use different
|
|
77
|
+
materials.
|
|
78
|
+
|
|
79
|
+
For a custom preview, `d` contains all paths in a layer. `regions` contains
|
|
80
|
+
closed outlines and `lines` contains open paths. On a `fill` layer, draw
|
|
81
|
+
regions with the even-odd fill rule and draw open paths as strokes.
|
|
82
|
+
|
|
83
|
+
## parameters()
|
|
84
|
+
|
|
85
|
+
Read a program's editable settings without rendering its geometry:
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
import { parameters } from '@mylasertools/kerfscript';
|
|
89
|
+
|
|
90
|
+
const source = 'width = 80; // [40:5:200]\nrect([width, 50]);';
|
|
91
|
+
const settings = parameters(source).parameters;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Each setting includes `name`, `caption`, `group`, `type`, `initial` and
|
|
95
|
+
`span`. Ranges add `min`, `max` and `step`; menus add `options`.
|
|
96
|
+
|
|
97
|
+
`type` is `"number"`, `"string"` or `"boolean"`. A numeric vector has
|
|
98
|
+
type `"number"` and an array as its `initial` value.
|
|
99
|
+
|
|
100
|
+
`span` gives the source offsets `[start, end]` of the value. An editor can
|
|
101
|
+
use them to update one setting:
|
|
102
|
+
|
|
103
|
+
```js
|
|
104
|
+
const width = settings.find((p) => p.name === 'width');
|
|
105
|
+
if (width) {
|
|
106
|
+
const next = source.slice(0, width.span[0]) + '120' + source.slice(width.span[1]);
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Read the settings again after editing the source; the offsets refer to the
|
|
111
|
+
string passed to `parameters()`.
|
|
112
|
+
|
|
113
|
+
## Errors
|
|
114
|
+
|
|
115
|
+
Language errors use `KerfError`. Its `line` and `col` identify the source
|
|
116
|
+
location when available, and `echoes` contains output produced before the
|
|
117
|
+
error. `missingFonts` lists fonts the application needs to supply.
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
import { KerfError, render } from '@mylasertools/kerfscript';
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
render('rect([80, 50]);');
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (error instanceof KerfError) {
|
|
126
|
+
console.error(error.message, error.line, error.col);
|
|
127
|
+
} else {
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Running untrusted code
|
|
134
|
+
|
|
135
|
+
Run browser renders in a web worker so they do not block the page. Set a
|
|
136
|
+
timeout and terminate the worker if it takes too long. Evaluation limits
|
|
137
|
+
bound program steps and recursion, but geometry work also takes time.
|
|
138
|
+
|
|
139
|
+
Memory limits stop a program before it asks for more memory than a browser
|
|
140
|
+
tab can give: part copies, circle segments, list sizes, text length, shape
|
|
141
|
+
points, exported points and sheets. The defaults are in
|
|
142
|
+
[Limits](../LANGUAGE.md#limits) and in `DEFAULT_LIMITS`. Lower them with the
|
|
143
|
+
`limits` option if your worker has little memory:
|
|
144
|
+
|
|
145
|
+
```js
|
|
146
|
+
import { render, DEFAULT_LIMITS } from '@mylasertools/kerfscript';
|
|
147
|
+
|
|
148
|
+
render(source, { limits: { maxPoints: DEFAULT_LIMITS.maxPoints / 2 } });
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
KerfScript programs have no direct file or network access. `use` and
|
|
152
|
+
`include` can load the standard library and sources returned by your
|
|
153
|
+
`resolve` callback. Restrict that callback to libraries you intend to expose.
|
package/docs/kerf.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Kerf
|
|
2
|
+
|
|
3
|
+
Kerf is the width of material removed by a laser cut. Allowing for it helps
|
|
4
|
+
parts finish at the intended size and joints fit together. Measure it for
|
|
5
|
+
the material and cutting settings you use.
|
|
6
|
+
|
|
7
|
+
## Setting it
|
|
8
|
+
|
|
9
|
+
Set `$kerf` in millimetres:
|
|
10
|
+
|
|
11
|
+
```kerf
|
|
12
|
+
$kerf = 0.15;
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
With this value, KerfScript moves an outer cut path outward by 0.075 mm and
|
|
16
|
+
a hole's path inward by the same amount. The offset compensates for material
|
|
17
|
+
removed on either side of the beam.
|
|
18
|
+
|
|
19
|
+
Only closed cut outlines receive the offset. Engraving, scoring and open
|
|
20
|
+
cuts such as living hinges keep their original paths.
|
|
21
|
+
|
|
22
|
+
To use a value for a particular material, set it inside `material()`:
|
|
23
|
+
|
|
24
|
+
```kerf
|
|
25
|
+
material(thickness = 4, kerf = 0.12, name = "birch") {
|
|
26
|
+
part("side", qty = 2) finger_rect([100, 60], "out");
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
On the command line, `--kerf 0.1` overrides the value for every part. Apply
|
|
31
|
+
kerf compensation in either KerfScript or your laser software, once per job.
|
|
32
|
+
|
|
33
|
+
## Measuring your kerf
|
|
34
|
+
|
|
35
|
+
1. Cut the [calibration square](../examples/calibration-square.kerf) with
|
|
36
|
+
`$kerf = 0`. Leave any offset in your laser software at zero too.
|
|
37
|
+
2. Measure the square across the middle with calipers.
|
|
38
|
+
3. Subtract that measurement from 100 mm. A square measuring 99.82 mm gives
|
|
39
|
+
a kerf of 0.18 mm.
|
|
40
|
+
4. Set `$kerf = 0.18` and cut another sample. Check the outside against
|
|
41
|
+
100 mm and the hole against 20 mm, then adjust the value if needed.
|
|
42
|
+
|
|
43
|
+
Repeat the measurement when the material or cutting settings change. Thick
|
|
44
|
+
material can have a different cut width at its top and bottom faces.
|
|
45
|
+
|
|
46
|
+
## Checking a fit
|
|
47
|
+
|
|
48
|
+
After calibrating kerf, measure your sheet's thickness and set `$thickness`
|
|
49
|
+
to that measurement. The nominal thickness on a material label can differ
|
|
50
|
+
from the sheet itself.
|
|
51
|
+
|
|
52
|
+
The [kerf and fit test](../examples/kerf-test.kerf) cuts slots slightly
|
|
53
|
+
narrower and wider than `$thickness`. Try a scrap from the same sheet in each
|
|
54
|
+
slot. A positive label means a wider slot; a negative label means a narrower
|
|
55
|
+
one. Choose the fit you need and use the result to refine your dimensions.
|
|
56
|
+
|
|
57
|
+
Both kerf and sheet thickness affect the fit. A tight or loose slot alone
|
|
58
|
+
does not tell you which value needs adjusting.
|
|
59
|
+
|
|
60
|
+
## Limits
|
|
61
|
+
|
|
62
|
+
- Compensation can close a hole or notch narrower than the kerf. KerfScript
|
|
63
|
+
warns when a hole disappears.
|
|
64
|
+
- Narrow bridges and fingers may be fragile or char during cutting even
|
|
65
|
+
when their dimensions are correct. Test small features in your material.
|
|
66
|
+
- Compensation adjusts the 2D outline. It does not remove taper from the
|
|
67
|
+
cut face in thick material.
|
package/docs/layers.md
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Layers
|
|
2
|
+
|
|
3
|
+
Layers separate cutting, scoring and engraving in the exported file. Use
|
|
4
|
+
them to give different parts of a design different operations in your laser
|
|
5
|
+
software. Unassigned shapes go on the `cut` layer.
|
|
6
|
+
|
|
7
|
+
## The built-in layers
|
|
8
|
+
|
|
9
|
+
| Layer | Wrap shapes in | Colour in the file | Intended operation |
|
|
10
|
+
| --- | --- | --- | --- |
|
|
11
|
+
| `engrave` | `engrave()` | black `#000000` | Fill an area |
|
|
12
|
+
| `score` | `score()` | blue `#0000ff` | Mark a line or outline |
|
|
13
|
+
| `cut` | `cut()` | red `#ff0000` | Cut through the material |
|
|
14
|
+
| `guide` | `guide()` | light blue | Show construction geometry |
|
|
15
|
+
|
|
16
|
+
This coaster has a cut outline and hole, an engraved ring and a scored border:
|
|
17
|
+
|
|
18
|
+
```kerf
|
|
19
|
+
difference() {
|
|
20
|
+
circle(d = 90);
|
|
21
|
+
circle(d = 6);
|
|
22
|
+
}
|
|
23
|
+
engrave() difference() { circle(d = 74); circle(d = 68); }
|
|
24
|
+
score() circle(d = 84);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The layer describes the operation. Set its power, speed and passes in your
|
|
28
|
+
laser software.
|
|
29
|
+
|
|
30
|
+
Place `#` or `%` before a module call to move it to the guide layer.
|
|
31
|
+
Guides are excluded from the output unless you request them with
|
|
32
|
+
`--guides` on the command line or `guides: true` in the API.
|
|
33
|
+
|
|
34
|
+
## Areas and lines
|
|
35
|
+
|
|
36
|
+
Shapes such as `rect()`, `circle()` and `text()` define areas. On an
|
|
37
|
+
engrave layer, those areas are filled. On cut and score layers, their
|
|
38
|
+
outlines become paths.
|
|
39
|
+
|
|
40
|
+
`line()`, `polyline()`, `arc()` and `living_hinge()` produce lines. They
|
|
41
|
+
remain lines on every layer. A living hinge, for example, is a pattern of
|
|
42
|
+
open cuts within a part.
|
|
43
|
+
|
|
44
|
+
Use `stroke(width)` to turn a line into an area of a specified width. Use
|
|
45
|
+
`outline()` to turn an area's boundary into lines.
|
|
46
|
+
|
|
47
|
+
### Overlapping shapes merge
|
|
48
|
+
|
|
49
|
+
The areas inside one `score()` are merged first, like a `union()`, and
|
|
50
|
+
only the outline of the result is scored. Two nested circles become one
|
|
51
|
+
disc, so this scores a single ring:
|
|
52
|
+
|
|
53
|
+
```kerf
|
|
54
|
+
circle(d = 60);
|
|
55
|
+
score() {
|
|
56
|
+
circle(d = 50);
|
|
57
|
+
circle(d = 40); // inside the first circle: merged away
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
To score every shape's own outline, turn each one into lines first with
|
|
62
|
+
`outline()`. Lines are never merged, so this scores both rings:
|
|
63
|
+
|
|
64
|
+
```kerf
|
|
65
|
+
circle(d = 60);
|
|
66
|
+
score() {
|
|
67
|
+
outline() circle(d = 50);
|
|
68
|
+
outline() circle(d = 40);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
One `outline()` around both circles would not help: it merges them before
|
|
73
|
+
it traces them. The same rule holds on the cut layer and on custom
|
|
74
|
+
layers. Use `difference()` when you want the area between two outlines,
|
|
75
|
+
such as a ring to engrave.
|
|
76
|
+
|
|
77
|
+
## The material
|
|
78
|
+
|
|
79
|
+
Closed shapes on a part's cut layer define its material. KerfScript clips
|
|
80
|
+
engraving, scoring and open cut lines to that area, excluding holes. Start
|
|
81
|
+
with a cut shape when adding marks to a part.
|
|
82
|
+
|
|
83
|
+
If the cut shapes form separate pieces, KerfScript reports a warning. Check
|
|
84
|
+
for a missing connection or define the pieces as separate parts.
|
|
85
|
+
|
|
86
|
+
## Your own layers
|
|
87
|
+
|
|
88
|
+
Use `layer(name, mode, color)` when you need another operation, such as a
|
|
89
|
+
second engraving depth:
|
|
90
|
+
|
|
91
|
+
```kerf
|
|
92
|
+
rect([60, 40]);
|
|
93
|
+
layer("deep", mode = "fill", color = "#00aa00")
|
|
94
|
+
translate([10, 10]) rect([20, 20]);
|
|
95
|
+
engrave() translate([40, 20]) circle(d = 12);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The rectangle and circle use separate engraving layers. You can assign each
|
|
99
|
+
a different power in your laser software. Supported modes are `"cut"`,
|
|
100
|
+
`"line"`, `"fill"` and `"guide"`.
|
|
101
|
+
|
|
102
|
+
## Order in the file
|
|
103
|
+
|
|
104
|
+
KerfScript writes layers in this order: engrave, custom layers, score, cut,
|
|
105
|
+
then guide. Within a cut layer, inner paths precede outer outlines.
|
|
106
|
+
|
|
107
|
+
Laser software may reorder these paths. Check its job preview so engraving
|
|
108
|
+
runs before cutting and holes are cut before the surrounding part.
|
package/docs/openscad.md
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Coming from OpenSCAD
|
|
2
|
+
|
|
3
|
+
KerfScript uses syntax familiar to OpenSCAD users, with features for laser
|
|
4
|
+
cutting. Existing OpenSCAD files may need changes to run in KerfScript.
|
|
5
|
+
This guide covers the shared syntax and the differences that affect a port.
|
|
6
|
+
|
|
7
|
+
## The same
|
|
8
|
+
|
|
9
|
+
You can use familiar building blocks:
|
|
10
|
+
|
|
11
|
+
- Modules, functions, `for`, `if`, `let`, `each`, list comprehensions,
|
|
12
|
+
ranges and function literals.
|
|
13
|
+
- `children()`, `children(i)` and `$children`.
|
|
14
|
+
- Dynamically scoped `$` variables, plus `$fn`, `$fa` and `$fs` for curve
|
|
15
|
+
resolution.
|
|
16
|
+
- 2D shapes: `square()` or `rect()`, `circle()`, `polygon()` and `text()`.
|
|
17
|
+
- Transforms: `translate`, `rotate`, `scale`, `mirror` and `multmatrix`.
|
|
18
|
+
- Shape operations: `union`, `difference`, `intersection`, `hull` and `offset`.
|
|
19
|
+
- `echo()`, `assert()`, `use <...>` and `include <...>`.
|
|
20
|
+
- Customizer comments for ranges, choices, groups and captions.
|
|
21
|
+
|
|
22
|
+
See the [language reference](../LANGUAGE.md) for supported arguments.
|
|
23
|
+
|
|
24
|
+
## Different
|
|
25
|
+
|
|
26
|
+
| Feature | OpenSCAD | KerfScript |
|
|
27
|
+
| --- | --- | --- |
|
|
28
|
+
| Geometry | 3D and 2D | 2D parts for laser cutting |
|
|
29
|
+
| Output | 3D formats and 2D exports | SVG and DXF with operation layers |
|
|
30
|
+
| Assignments | The last assignment in a scope applies throughout that scope | Assignments take effect in order |
|
|
31
|
+
| Type errors | Many produce `undef` and a warning | Stop evaluation with an error |
|
|
32
|
+
| `color()` | Sets a shape's colour | Use `cut()`, `score()`, `engrave()` or `layer()` |
|
|
33
|
+
| Fonts | Looks up system fonts | Uses fonts supplied by the application or CLI |
|
|
34
|
+
| Libraries | Can load local files | Loads the standard library and sources allowed by the host |
|
|
35
|
+
|
|
36
|
+
Assignment order is especially important when adapting a design. A value
|
|
37
|
+
assigned later in a KerfScript program does not change earlier geometry.
|
|
38
|
+
|
|
39
|
+
## Not in KerfScript
|
|
40
|
+
|
|
41
|
+
KerfScript does not support `cube`, `sphere`, `cylinder`, `polyhedron`,
|
|
42
|
+
`linear_extrude`, `rotate_extrude` or `projection`. It also does not support
|
|
43
|
+
`minkowski`, `resize`, `color`, `import`, `surface` or `render`.
|
|
44
|
+
|
|
45
|
+
Calls to these modules produce an error. For a design based on an extruded
|
|
46
|
+
2D outline, start with that outline and remove the extrusion.
|
|
47
|
+
|
|
48
|
+
## Only in KerfScript
|
|
49
|
+
|
|
50
|
+
- **Operations:** `cut()`, `score()`, `engrave()`, `guide()` and `layer()`.
|
|
51
|
+
- **Material settings:** `$kerf` for cut compensation and `$thickness` for
|
|
52
|
+
material-dependent joints.
|
|
53
|
+
- **Parts and layout:** `part()`, `material()`, quantities, `$sheet` and `$gap`.
|
|
54
|
+
- **Joinery:** `finger_rect`, `finger_holes`, `tslot` and `living_hinge`.
|
|
55
|
+
- **Paths:** `line`, `polyline`, `arc`, `path`, `stroke` and `outline`.
|
|
56
|
+
- **Additional shapes:** `ellipse`, `regular_polygon`, `star` and rounded
|
|
57
|
+
rectangles with `rect(r = ...)`.
|
|
58
|
+
- **Text measurement:** `text_width()` and `text_metrics()`.
|
|
59
|
+
|
|
60
|
+
## Porting a 2D design
|
|
61
|
+
|
|
62
|
+
1. Keep the 2D geometry and remove extrusion or other 3D operations.
|
|
63
|
+
2. Assign shapes to cut, score or engrave layers.
|
|
64
|
+
3. Check repeated assignments and put each value before the code that uses it.
|
|
65
|
+
4. Supply the fonts used by `text()`.
|
|
66
|
+
5. Set the measured material thickness and kerf. Use the joinery modules
|
|
67
|
+
where they suit the design.
|
|
68
|
+
|
|
69
|
+
Render the result and check the dimensions and layers before exporting.
|
|
70
|
+
The [layers](layers.md), [kerf](kerf.md) and
|
|
71
|
+
[parts and sheets](parts-and-sheets.md) guides cover those steps.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Parts and sheets
|
|
2
|
+
|
|
3
|
+
Use parts to name the pieces in a design, set quantities and assign
|
|
4
|
+
materials. KerfScript lays them out on sheets, grouping parts that use the
|
|
5
|
+
same material and thickness.
|
|
6
|
+
|
|
7
|
+
## Parts
|
|
8
|
+
|
|
9
|
+
```kerf
|
|
10
|
+
part("side", qty = 2) rect([100, 60]);
|
|
11
|
+
part("base") rect([100, 100]);
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
This creates two side panels and one base. Each `part()` has its own layers
|
|
15
|
+
and appears in the parts list with dimensions and cut length. The default
|
|
16
|
+
quantity is one.
|
|
17
|
+
|
|
18
|
+
Shapes outside a `part()` are collected into a part named `part`.
|
|
19
|
+
|
|
20
|
+
Transforms and operations such as `translate()`, `difference()` and
|
|
21
|
+
`offset()` can wrap a part and change all of it. Layer wrappers such as
|
|
22
|
+
`score()` and `engrave()` go inside the part instead, since a whole part on
|
|
23
|
+
the score layer would have nothing to cut:
|
|
24
|
+
|
|
25
|
+
```kerf
|
|
26
|
+
part("tag") {
|
|
27
|
+
rect([60, 30], r = 3);
|
|
28
|
+
score() translate([5, 5]) rect([50, 20]);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Materials
|
|
33
|
+
|
|
34
|
+
`material()` sets the thickness, kerf and material name for its parts:
|
|
35
|
+
|
|
36
|
+
```kerf
|
|
37
|
+
material(thickness = 3, kerf = 0.15, name = "plywood") {
|
|
38
|
+
part("front") rect([100, 60]);
|
|
39
|
+
part("back") rect([100, 60]);
|
|
40
|
+
}
|
|
41
|
+
material(thickness = 2, kerf = 0.1, name = "acrylic") {
|
|
42
|
+
part("window") rect([80, 40]);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The two plywood panels share a sheet. The acrylic window goes on a separate
|
|
47
|
+
sheet. Each part records the `$thickness`, `$kerf` and `$material` values in
|
|
48
|
+
effect where it is defined.
|
|
49
|
+
|
|
50
|
+
## Sheets
|
|
51
|
+
|
|
52
|
+
Set the available sheet size and spacing in millimetres:
|
|
53
|
+
|
|
54
|
+
```kerf
|
|
55
|
+
$sheet = [300, 200];
|
|
56
|
+
$gap = 4;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
With the default `$layout = "pack"`, KerfScript arranges copies of each part
|
|
60
|
+
in rows, leaving the specified gap. It rotates a part 90° if that lets it
|
|
61
|
+
fit the sheet. The default sheet is 600 × 400 mm, with a 3 mm gap between
|
|
62
|
+
parts and at the sheet edges.
|
|
63
|
+
|
|
64
|
+
A part larger than the sheet produces a warning. Set `$layout = "none"`
|
|
65
|
+
to keep the positions from your code instead of packing the parts.
|
|
66
|
+
|
|
67
|
+
The CLI `--margin` option and API `margin` option let you set the edge
|
|
68
|
+
spacing separately from the gap between parts.
|
|
69
|
+
|
|
70
|
+
## One file per sheet
|
|
71
|
+
|
|
72
|
+
A combined SVG stacks all sheets in one preview. For the material example
|
|
73
|
+
above, export the plywood and acrylic sheets separately and cut each with
|
|
74
|
+
the matching material settings.
|
|
75
|
+
|
|
76
|
+
- On the command line, add `--split` to write `design-1.svg`,
|
|
77
|
+
`design-2.svg` and so on. `kerf check` lists each sheet's material and
|
|
78
|
+
thickness.
|
|
79
|
+
- In JavaScript, `result.sheets` provides the SVG, DXF, material and
|
|
80
|
+
thickness for each sheet.
|
|
81
|
+
|
|
82
|
+
DXF exports contain one sheet per file.
|
package/docs/versions.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Versions
|
|
2
|
+
|
|
3
|
+
KerfScript 0.2.0 implements language version 0.1. The package version tracks
|
|
4
|
+
the software release; the language version tracks the syntax and behavior
|
|
5
|
+
of `.kerf` programs.
|
|
6
|
+
|
|
7
|
+
Package updates can include bug fixes, export options and JavaScript API
|
|
8
|
+
changes without changing the language version. Use `kerf --version` to see
|
|
9
|
+
both numbers, or read the `VERSION` and `LANGUAGE_VERSION` exports in JavaScript.
|
|
10
|
+
|
|
11
|
+
## Before 1.0
|
|
12
|
+
|
|
13
|
+
The language may change before 1.0. Release notes identify changes that
|
|
14
|
+
affect existing programs or their output, including geometry and text layout
|
|
15
|
+
fixes. Removing or renaming a language feature requires a new language version.
|
|
16
|
+
|
|
17
|
+
Check the changelog when upgrading a tool that renders saved designs.
|
|
18
|
+
|
|
19
|
+
## From 1.0
|
|
20
|
+
|
|
21
|
+
The compatibility policy for language version 1.x is to keep existing
|
|
22
|
+
programs working throughout that series. New features will be added without
|
|
23
|
+
changing existing syntax. Bug fixes that affect output will be listed in
|
|
24
|
+
the changelog; other breaking changes will require language version 2.0.
|
|
25
|
+
|
|
26
|
+
## Pinning a version
|
|
27
|
+
|
|
28
|
+
For repeatable exports, record the interpreter version, settings and font
|
|
29
|
+
files used with a design. Applications that store designs should retain
|
|
30
|
+
that information and compare the output before upgrading the interpreter.
|
|
31
|
+
|
|
32
|
+
Pin the npm package to an exact version when your application needs a fixed
|
|
33
|
+
renderer, for example `@mylasertools/kerfscript@0.2.0`.
|