@mylasertools/kerfscript 0.2.0 → 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.
@@ -1,8 +1,8 @@
1
1
  # JavaScript API
2
2
 
3
- The same interpreter that runs the command line and the playground is a
4
- TypeScript library with no native code. It runs in browsers, web workers,
5
- Node.js and edge runtimes.
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
6
 
7
7
  ```sh
8
8
  npm install @mylasertools/kerfscript
@@ -10,89 +10,144 @@ npm install @mylasertools/kerfscript
10
10
 
11
11
  ## render()
12
12
 
13
+ Pass a program as a string. The result contains its geometry, files, parts
14
+ and warnings:
15
+
13
16
  ```js
14
17
  import { render } from '@mylasertools/kerfscript';
15
18
 
19
+ const source = 'width = 80; rect([width, 50]);';
16
20
  const result = render(source, {
17
- params: { width: 200 },
18
- fonts: { Inter: await (await fetch('/Inter.ttf')).arrayBuffer() },
19
- defaultFont: 'Inter',
21
+ params: { width: 120 },
20
22
  sheet: [600, 400],
23
+ margin: 0,
21
24
  });
25
+
26
+ console.log(result.svg);
22
27
  ```
23
28
 
29
+ This exports a 120 × 50 mm rectangle. `params` overrides `width` without
30
+ changing the source string.
31
+
24
32
  ### Options
25
33
 
26
- | Option | Meaning |
27
- | ------------- | ------------------------------------------------------------------------------------ |
28
- | `params` | setting values by name, overriding the top-level assignments |
29
- | `fonts` | font files by name, as `ArrayBuffer` or `Uint8Array` |
30
- | `defaultFont` | font used when `text()` names none |
31
- | `resolve` | `(path) => source` for `use <path>` and `include <path>` beyond the standard library |
32
- | `kerf` | override kerf compensation for every part |
33
- | `layout` | `"pack"` or `"none"` |
34
- | `sheet` | `[width, height]` in mm |
35
- | `gap` | space between packed parts |
36
- | `margin` | space around the sheet edge (default: `gap`) |
37
- | `guides` | include guide layer geometry |
38
- | `maxSteps` | step limit before the program is stopped |
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:
39
50
 
40
- ### Result
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.
41
61
 
42
- | Field | Contents |
43
- | ----------------- | ---------------------------------------------------------------------------------------------------------- |
44
- | `svg` | every sheet in one SVG, for previews |
45
- | `width`, `height` | size of that combined SVG in mm |
46
- | `sheets` | one entry per sheet: `width`, `height`, `material`, `thickness`, `svg`, `dxf`, `paths`, `items` |
47
- | `parts` | `name`, `qty`, `width`, `height`, `pieces`, `cutLength`, `thickness`, `kerf`, `material` |
48
- | `paths` | per layer: `name`, `mode`, `color`, `d` (all path data), `regions` (closed outlines), `lines` (open lines) |
49
- | `layers` | the layer definitions in output order |
50
- | `warnings` | problems that did not stop the render |
51
- | `echoes` | `echo()` output |
62
+ ### Result
52
63
 
53
- `paths` is for apps that draw the result themselves. Fill `regions` with the
54
- even-odd rule on `fill` layers, and stroke `lines`.
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.
55
82
 
56
83
  ## parameters()
57
84
 
85
+ Read a program's editable settings without rendering its geometry:
86
+
58
87
  ```js
59
88
  import { parameters } from '@mylasertools/kerfscript';
60
89
 
61
- parameters(source).parameters;
62
- // [{ name, caption, group, type, initial, min, max, step, options, span }]
90
+ const source = 'width = 80; // [40:5:200]\nrect([width, 50]);';
91
+ const settings = parameters(source).parameters;
63
92
  ```
64
93
 
65
- `type` is `"number"`, `"string"` or `"boolean"`; a list of numbers is
66
- `"number"` with a list `initial`, as in OpenSCAD's parameter JSON. `span` is
67
- `[start, end]`, the offsets of the value in the source, so an editor can change
68
- a value without touching anything else:
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:
69
102
 
70
103
  ```js
71
- const p = parameters(source).parameters.find((p) => p.name === 'width');
72
- const next = source.slice(0, p.span[0]) + '200' + source.slice(p.span[1]);
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
+ }
73
108
  ```
74
109
 
110
+ Read the settings again after editing the source; the offsets refer to the
111
+ string passed to `parameters()`.
112
+
75
113
  ## Errors
76
114
 
77
- Errors are thrown as `KerfError` with `line` and `col`. They also carry
78
- `echoes`, the `echo()` output up to the error, and `missingFonts` when a font
79
- was not supplied, so an app can load those fonts and render again.
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.
80
118
 
81
119
  ```js
82
120
  import { KerfError, render } from '@mylasertools/kerfscript';
83
121
 
84
122
  try {
85
- render(source, { fonts });
86
- } catch (e) {
87
- if (e instanceof KerfError && e.missingFonts) {
88
- // load e.missingFonts, then render again
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;
89
129
  }
90
130
  }
91
131
  ```
92
132
 
93
133
  ## Running untrusted code
94
134
 
95
- Programs cannot read files or the network: `use` and `include` reach only the
96
- standard library and whatever your `resolve` returns. Step and recursion limits
97
- stop runaway programs. A render is still ordinary synchronous work, so run
98
- it in a web worker, and stop the worker if it takes too long.
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 CHANGED
@@ -1,27 +1,25 @@
1
1
  # Kerf
2
2
 
3
- The laser beam burns away a thin line of material as it cuts. That width is
4
- the **kerf**, usually somewhere between 0.05 and 0.3 mm depending on the
5
- machine, the lens, the material and its thickness. Without compensation every
6
- part comes out smaller than drawn by about one kerf, and every hole bigger.
7
- For a sign that hardly matters. For finger joints and press fits it decides
8
- whether the box holds together.
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.
9
6
 
10
7
  ## Setting it
11
8
 
9
+ Set `$kerf` in millimetres:
10
+
12
11
  ```kerf
13
12
  $kerf = 0.15;
14
13
  ```
15
14
 
16
- KerfScript offsets every cut outline outward by half the kerf when it writes
17
- the file. The beam then runs half a kerf outside the part and burns away
18
- material that was never part of it, so the part ends up the size you typed.
19
- Holes are offset inward the same way, so they end up the size you typed too.
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.
20
18
 
21
- Only closed outlines on cut layers are offset. Engraving, scoring and open cut
22
- lines (like a living hinge) are left as drawn.
19
+ Only closed cut outlines receive the offset. Engraving, scoring and open
20
+ cuts such as living hinges keep their original paths.
23
21
 
24
- You can set the kerf for one material only, together with its thickness:
22
+ To use a value for a particular material, set it inside `material()`:
25
23
 
26
24
  ```kerf
27
25
  material(thickness = 4, kerf = 0.12, name = "birch") {
@@ -29,42 +27,41 @@ material(thickness = 4, kerf = 0.12, name = "birch") {
29
27
  }
30
28
  ```
31
29
 
32
- On the command line, `--kerf 0.1` overrides the value for every part.
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.
33
32
 
34
33
  ## Measuring your kerf
35
34
 
36
35
  1. Cut the [calibration square](../examples/calibration-square.kerf) with
37
- `$kerf = 0`.
38
- 2. Measure the outside of the square with calipers, across the middle.
39
- 3. Your kerf is `100 - measured`. If the square measures 99.82 mm, use
40
- `$kerf = 0.18`.
41
- 4. Cut it again with that value. The square should now be 100 mm and the hole
42
- 20 mm. If the square is still small and the hole big, raise `$kerf` a
43
- little; if the square is big, lower it.
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.
44
42
 
45
- Measure each material you use. Thicker material usually has a wider kerf, and
46
- the kerf can differ between the top and bottom face.
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.
47
45
 
48
46
  ## Checking a fit
49
47
 
50
- For joints, the [kerf and fit test](../examples/kerf-test.kerf) cuts a row of
51
- slots from slightly narrower to slightly wider than `$thickness`. Push a scrap
52
- of the same sheet into each slot:
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.
53
51
 
54
- - if the slot marked `0` is snug, your kerf and thickness are right;
55
- - if a `+` slot fits best, the sheet is thicker than `$thickness` says
56
- (plywood often is);
57
- - if a `-` slot fits best, it is thinner.
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.
58
56
 
59
- Set `$thickness` to the thickness you measured rather than the one on the
60
- label, and joints follow.
57
+ Both kerf and sheet thickness affect the fit. A tight or loose slot alone
58
+ does not tell you which value needs adjusting.
61
59
 
62
60
  ## Limits
63
61
 
64
- - A hole, slot or notch narrower than the kerf cannot be cut: the beam is
65
- wider than the gap, so compensation closes it. KerfScript warns when that
66
- happens to a hole.
67
- - Thin bridges and fingers come out the right size but are fragile, and can
68
- char in thin material. Keep them several times wider than the kerf.
69
- - The beam is not perfectly straight in thick material, so cut faces taper a
70
- little. Compensation works on the average width.
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 CHANGED
@@ -1,17 +1,19 @@
1
1
  # Layers
2
2
 
3
- Every shape in KerfScript is on a layer, and the layer decides what the
4
- laser does with it. Shapes that are not wrapped in a layer module are on
5
- `cut`.
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
6
 
7
7
  ## The built-in layers
8
8
 
9
- | Layer | Wrap shapes in | Colour in the file | What the laser does |
10
- | --------- | -------------- | ------------------ | ------------------------------------------------- |
11
- | `engrave` | `engrave()` | black `#000000` | engraves the area of the shapes |
12
- | `score` | `score()` | blue `#0000ff` | marks lines and outlines without cutting through |
13
- | `cut` | `cut()` | red `#ff0000` | cuts the outlines through, with kerf compensation |
14
- | `guide` | `guide()` | light blue | nothing; shown only when you ask for guide lines |
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:
15
17
 
16
18
  ```kerf
17
19
  difference() {
@@ -22,53 +24,85 @@ engrave() difference() { circle(d = 74); circle(d = 68); }
22
24
  score() circle(d = 84);
23
25
  ```
24
26
 
25
- `#` and `%` in front of a module call move it to the guide layer, which is
26
- handy for checking where something is without cutting it.
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.
27
33
 
28
34
  ## Areas and lines
29
35
 
30
- Layers hold two kinds of geometry:
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:
31
63
 
32
- - **Areas** come from shapes like `rect()`, `circle()` and `text()`. On
33
- `engrave` the area is filled; on `cut` and `score` its outline is followed.
34
- - **Lines** come from `line()`, `polyline()`, `arc()` and `living_hinge()`.
35
- They are followed as they are, on any layer. On `cut` they are cut through,
36
- which is how a living hinge is made.
64
+ ```kerf
65
+ circle(d = 60);
66
+ score() {
67
+ outline() circle(d = 50);
68
+ outline() circle(d = 40);
69
+ }
70
+ ```
37
71
 
38
- `stroke(width)` turns lines into areas, for engraving a line of a given
39
- width. `outline()` turns areas into their outline lines.
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.
40
76
 
41
77
  ## The material
42
78
 
43
- When a part is finished, KerfScript takes the union of everything on the cut
44
- layer as the **material**. Then:
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.
45
82
 
46
- - engraving and scoring are clipped to the material, so nothing is marked
47
- inside a hole or off the part;
48
- - cut lines are clipped to the material too;
49
- - if the material falls apart into separate pieces, you get a warning,
50
- because that usually means a missing bridge.
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.
51
85
 
52
86
  ## Your own layers
53
87
 
54
- `layer(name, mode, color)` makes a layer of your own, for example a second
55
- engraving pass at a different power:
88
+ Use `layer(name, mode, color)` when you need another operation, such as a
89
+ second engraving depth:
56
90
 
57
91
  ```kerf
58
92
  rect([60, 40]);
59
- layer("deep", mode = "fill", color = "#00aa00") translate([10, 10]) rect([20, 20]);
93
+ layer("deep", mode = "fill", color = "#00aa00")
94
+ translate([10, 10]) rect([20, 20]);
60
95
  engrave() translate([40, 20]) circle(d = 12);
61
96
  ```
62
97
 
63
- Modes are `"cut"`, `"line"` (score), `"fill"` (engrave) and `"guide"`.
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"`.
64
101
 
65
102
  ## Order in the file
66
103
 
67
- Layers are written in this order: engrave, your own layers, score, cut,
68
- guide. Within the cut layer, holes and inner cuts come before outer outlines,
69
- so a part does not drop out before its holes are cut.
104
+ KerfScript writes layers in this order: engrave, custom layers, score, cut,
105
+ then guide. Within a cut layer, inner paths precede outer outlines.
70
106
 
71
- That order is a good default, but it does not control your machine. Most
72
- laser software sorts and orders operations itself. Check the cut order, and
73
- set power, speed and passes for each layer, in your laser software before you
74
- run the job.
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 CHANGED
@@ -1,67 +1,71 @@
1
1
  # Coming from OpenSCAD
2
2
 
3
- KerfScript borrows OpenSCAD's syntax on purpose: if you have written
4
- OpenSCAD, you can read KerfScript and write it within minutes. It is not a
5
- drop-in replacement. It only makes flat parts, and a few rules are different.
6
- OpenSCAD files do not run unchanged.
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.
7
6
 
8
7
  ## The same
9
8
 
10
- - Statements, modules, functions, `for`, `if`, `let`, `each`, list
11
- comprehensions, ranges like `[0:2:10]`, function literals.
9
+ You can use familiar building blocks:
10
+
11
+ - Modules, functions, `for`, `if`, `let`, `each`, list comprehensions,
12
+ ranges and function literals.
12
13
  - `children()`, `children(i)` and `$children`.
13
- - Special variables that start with `$` are dynamically scoped, and `$fn`,
14
- `$fa` and `$fs` set curve resolution.
15
- - 2D shapes: `square()` (also called `rect()`), `circle(r)` or `circle(d =)`,
16
- `polygon(points, paths)`, `text()`.
17
- - Transforms: `translate`, `rotate`, `scale`, `mirror`, `multmatrix`.
18
- - Combining: `union`, `difference`, `intersection`, `hull`, `offset(r)`,
19
- `offset(delta, chamfer)`.
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`.
20
19
  - `echo()`, `assert()`, `use <...>` and `include <...>`.
21
- - Customizer comments: `// [40:5:400]`, `/* [Group] */`, `/* [Hidden] */`,
22
- and captions on the line above. Tools that read OpenSCAD settings read
23
- these.
20
+ - Customizer comments for ranges, choices, groups and captions.
21
+
22
+ See the [language reference](../LANGUAGE.md) for supported arguments.
24
23
 
25
24
  ## Different
26
25
 
27
- | | OpenSCAD | KerfScript |
28
- | ----------- | --------------------------------------------- | --------------------------------------------------------------- |
29
- | Output | a solid, as STL, 3MF and more | a cut file, as SVG or DXF |
30
- | Dimensions | 3D, and 2D for export | 2D only |
31
- | Assignments | the last one in a scope wins everywhere in it | run in order; a later one takes effect from that line |
32
- | Errors | many mistakes give `undef` and a warning | type mistakes stop the program, naming the line |
33
- | `color()` | colours a shape | not available; use `cut()`, `score()`, `engrave()` or `layer()` |
34
- | Fonts | system fonts | only fonts you pass in, so a file renders the same everywhere |
35
- | Libraries | any file on disk | the standard library and whatever the host allows |
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.
36
38
 
37
39
  ## Not in KerfScript
38
40
 
39
- 3D modules (`cube`, `sphere`, `cylinder`, `polyhedron`,
40
- `linear_extrude`, `rotate_extrude`, `projection`), `minkowski`, `resize`,
41
- `color`, `import`, `surface` and `render`. Each stops with an error that
42
- names it, so you find out at once.
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.
43
47
 
44
48
  ## Only in KerfScript
45
49
 
46
- - Layers: `cut()`, `score()`, `engrave()`, `guide()` and `layer()`.
47
- See [Layers](layers.md).
48
- - Kerf compensation with `$kerf`. See [Kerf](kerf.md).
49
- - Parts, quantities, materials and sheet packing: `part()`, `material()`,
50
- `$sheet`, `$gap`. See [Parts and sheets](parts-and-sheets.md).
51
- - Joinery that reads `$thickness`: `finger_rect`, `finger_holes`, `tslot`,
52
- `living_hinge`.
53
- - Lines as well as areas: `line()`, `polyline()`, `arc()`, `path()`,
54
- `stroke()` and `outline()`.
55
- - Shapes OpenSCAD lacks: `ellipse`, `regular_polygon`, `star`, rounded
56
- `rect(r =)`.
57
- - `text_width()` and `text_metrics()`, to size a part to its text.
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()`.
58
59
 
59
60
  ## Porting a 2D design
60
61
 
61
- 1. Drop `linear_extrude()` and any 3D parts.
62
- 2. Replace `color()` with the layer the shape belongs on.
63
- 3. Check assignments: code that relied on a later assignment overriding an
64
- earlier one should assign once.
65
- 4. Pass the fonts your `text()` calls use.
66
- 5. Add `$kerf` and `$thickness`, and replace hand-made finger joints with
67
- `finger_rect()` if you want them to follow the material.
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.