@mylasertools/kerfscript 0.0.0-stage → 0.2.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 +42 -0
- package/CLA.md +73 -0
- package/COMMERCIAL-LICENSE.md +68 -0
- package/LANGUAGE.md +295 -0
- package/LICENSE +661 -0
- package/README.md +148 -2
- package/THIRD-PARTY-NOTICES.md +69 -0
- package/TRADEMARKS.md +39 -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 +19226 -0
- package/dist/customizer.d.cts +19 -0
- package/dist/customizer.d.ts +19 -0
- package/dist/evaluator.d.cts +106 -0
- package/dist/evaluator.d.ts +106 -0
- package/dist/export/dxf.d.cts +3 -0
- package/dist/export/dxf.d.ts +3 -0
- package/dist/export/svg.d.cts +13 -0
- package/dist/export/svg.d.ts +13 -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 +57 -0
- package/dist/render.d.ts +57 -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 +61 -0
- package/docs/compatibility.md +89 -0
- package/docs/customizer.md +62 -0
- package/docs/getting-started.md +98 -0
- package/docs/javascript.md +98 -0
- package/docs/kerf.md +70 -0
- package/docs/layers.md +74 -0
- package/docs/openscad.md +67 -0
- package/docs/parts-and-sheets.md +68 -0
- package/docs/versions.md +43 -0
- package/package.json +85 -4
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Poly } from './geometry.cjs';
|
|
2
|
+
export type Edge = 'out' | 'in' | 'flat';
|
|
3
|
+
export declare function fingerCount(length: number, finger: number): number;
|
|
4
|
+
export declare function fingerRect(w: number, h: number, edges: Edge[], t: number, finger: number): Poly[];
|
|
5
|
+
export declare function fingerHoles(length: number, edge: Edge, t: number, finger: number): Poly[];
|
|
6
|
+
export declare function tslot(d: number, length: number, nutW: number, nutH: number, nutAt: number): Poly[];
|
|
7
|
+
export declare function livingHinge(w: number, h: number, spacing: number, bridge: number, cut: number): Poly[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Poly } from './geometry.js';
|
|
2
|
+
export type Edge = 'out' | 'in' | 'flat';
|
|
3
|
+
export declare function fingerCount(length: number, finger: number): number;
|
|
4
|
+
export declare function fingerRect(w: number, h: number, edges: Edge[], t: number, finger: number): Poly[];
|
|
5
|
+
export declare function fingerHoles(length: number, edge: Edge, t: number, finger: number): Poly[];
|
|
6
|
+
export declare function tslot(d: number, length: number, nutW: number, nutH: number, nutAt: number): Poly[];
|
|
7
|
+
export declare function livingHinge(w: number, h: number, spacing: number, bridge: number, cut: number): Poly[];
|
package/dist/lexer.d.cts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type TokenType = 'num' | 'str' | 'id' | 'punct' | 'eof';
|
|
2
|
+
export interface Pos {
|
|
3
|
+
line: number;
|
|
4
|
+
col: number;
|
|
5
|
+
offset: number;
|
|
6
|
+
}
|
|
7
|
+
export interface Token {
|
|
8
|
+
type: TokenType;
|
|
9
|
+
value: string;
|
|
10
|
+
pos: Pos;
|
|
11
|
+
}
|
|
12
|
+
export interface Comment {
|
|
13
|
+
text: string;
|
|
14
|
+
line: number;
|
|
15
|
+
block: boolean;
|
|
16
|
+
own: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare class KerfError extends Error {
|
|
19
|
+
line?: number;
|
|
20
|
+
col?: number;
|
|
21
|
+
echoes: string[];
|
|
22
|
+
missingFonts?: string[];
|
|
23
|
+
constructor(message: string, pos?: Pos);
|
|
24
|
+
}
|
|
25
|
+
export declare function tokenize(src: string): {
|
|
26
|
+
tokens: Token[];
|
|
27
|
+
comments: Comment[];
|
|
28
|
+
};
|
package/dist/lexer.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export type TokenType = 'num' | 'str' | 'id' | 'punct' | 'eof';
|
|
2
|
+
export interface Pos {
|
|
3
|
+
line: number;
|
|
4
|
+
col: number;
|
|
5
|
+
offset: number;
|
|
6
|
+
}
|
|
7
|
+
export interface Token {
|
|
8
|
+
type: TokenType;
|
|
9
|
+
value: string;
|
|
10
|
+
pos: Pos;
|
|
11
|
+
}
|
|
12
|
+
export interface Comment {
|
|
13
|
+
text: string;
|
|
14
|
+
line: number;
|
|
15
|
+
block: boolean;
|
|
16
|
+
own: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare class KerfError extends Error {
|
|
19
|
+
line?: number;
|
|
20
|
+
col?: number;
|
|
21
|
+
echoes: string[];
|
|
22
|
+
missingFonts?: string[];
|
|
23
|
+
constructor(message: string, pos?: Pos);
|
|
24
|
+
}
|
|
25
|
+
export declare function tokenize(src: string): {
|
|
26
|
+
tokens: Token[];
|
|
27
|
+
comments: Comment[];
|
|
28
|
+
};
|
package/dist/parser.d.ts
ADDED
package/dist/paths.d.cts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Poly } from './geometry.cjs';
|
|
2
|
+
export type Cmd = {
|
|
3
|
+
type: 'M' | 'L';
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
} | {
|
|
7
|
+
type: 'Q';
|
|
8
|
+
x1: number;
|
|
9
|
+
y1: number;
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
} | {
|
|
13
|
+
type: 'C';
|
|
14
|
+
x1: number;
|
|
15
|
+
y1: number;
|
|
16
|
+
x2: number;
|
|
17
|
+
y2: number;
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
} | {
|
|
21
|
+
type: 'Z';
|
|
22
|
+
};
|
|
23
|
+
export interface Flattened {
|
|
24
|
+
closed: Poly[];
|
|
25
|
+
open: Poly[];
|
|
26
|
+
}
|
|
27
|
+
export declare function flatten(cmds: Cmd[], tolerance?: number): Flattened;
|
|
28
|
+
export declare function parseSvgPath(d: string): Cmd[];
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Poly } from './geometry.js';
|
|
2
|
+
export type Cmd = {
|
|
3
|
+
type: 'M' | 'L';
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
} | {
|
|
7
|
+
type: 'Q';
|
|
8
|
+
x1: number;
|
|
9
|
+
y1: number;
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
} | {
|
|
13
|
+
type: 'C';
|
|
14
|
+
x1: number;
|
|
15
|
+
y1: number;
|
|
16
|
+
x2: number;
|
|
17
|
+
y2: number;
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
} | {
|
|
21
|
+
type: 'Z';
|
|
22
|
+
};
|
|
23
|
+
export interface Flattened {
|
|
24
|
+
closed: Poly[];
|
|
25
|
+
open: Poly[];
|
|
26
|
+
}
|
|
27
|
+
export declare function flatten(cmds: Cmd[], tolerance?: number): Flattened;
|
|
28
|
+
export declare function parseSvgPath(d: string): Cmd[];
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type LayerDef } from './evaluator.cjs';
|
|
2
|
+
import { type LayerPath } from './export/svg.cjs';
|
|
3
|
+
import { type Layer } from './geometry.cjs';
|
|
4
|
+
import { type FontSource } from './text.cjs';
|
|
5
|
+
import type { Value } from './values.cjs';
|
|
6
|
+
export interface RenderOptions {
|
|
7
|
+
params?: Record<string, Value>;
|
|
8
|
+
fonts?: Record<string, FontSource>;
|
|
9
|
+
defaultFont?: string;
|
|
10
|
+
resolve?: (path: string) => string | undefined;
|
|
11
|
+
kerf?: number;
|
|
12
|
+
layout?: 'pack' | 'none';
|
|
13
|
+
sheet?: [number, number];
|
|
14
|
+
gap?: number;
|
|
15
|
+
margin?: number;
|
|
16
|
+
guides?: boolean;
|
|
17
|
+
maxSteps?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface PartInfo {
|
|
20
|
+
name: string;
|
|
21
|
+
qty: number;
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
pieces: number;
|
|
25
|
+
cutLength: number;
|
|
26
|
+
thickness: number;
|
|
27
|
+
kerf: number;
|
|
28
|
+
material: string;
|
|
29
|
+
}
|
|
30
|
+
export interface Placed {
|
|
31
|
+
part: string;
|
|
32
|
+
copy: number;
|
|
33
|
+
layers: Map<string, Layer>;
|
|
34
|
+
rotated: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface Sheet {
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
material: string;
|
|
40
|
+
thickness: number;
|
|
41
|
+
items: Placed[];
|
|
42
|
+
paths: LayerPath[];
|
|
43
|
+
svg: string;
|
|
44
|
+
dxf: string;
|
|
45
|
+
}
|
|
46
|
+
export interface RenderResult {
|
|
47
|
+
sheets: Sheet[];
|
|
48
|
+
width: number;
|
|
49
|
+
height: number;
|
|
50
|
+
paths: LayerPath[];
|
|
51
|
+
svg: string;
|
|
52
|
+
parts: PartInfo[];
|
|
53
|
+
layers: LayerDef[];
|
|
54
|
+
warnings: string[];
|
|
55
|
+
echoes: string[];
|
|
56
|
+
}
|
|
57
|
+
export declare function render(source: string, options?: RenderOptions): RenderResult;
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type LayerDef } from './evaluator.js';
|
|
2
|
+
import { type LayerPath } from './export/svg.js';
|
|
3
|
+
import { type Layer } from './geometry.js';
|
|
4
|
+
import { type FontSource } from './text.js';
|
|
5
|
+
import type { Value } from './values.js';
|
|
6
|
+
export interface RenderOptions {
|
|
7
|
+
params?: Record<string, Value>;
|
|
8
|
+
fonts?: Record<string, FontSource>;
|
|
9
|
+
defaultFont?: string;
|
|
10
|
+
resolve?: (path: string) => string | undefined;
|
|
11
|
+
kerf?: number;
|
|
12
|
+
layout?: 'pack' | 'none';
|
|
13
|
+
sheet?: [number, number];
|
|
14
|
+
gap?: number;
|
|
15
|
+
margin?: number;
|
|
16
|
+
guides?: boolean;
|
|
17
|
+
maxSteps?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface PartInfo {
|
|
20
|
+
name: string;
|
|
21
|
+
qty: number;
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
pieces: number;
|
|
25
|
+
cutLength: number;
|
|
26
|
+
thickness: number;
|
|
27
|
+
kerf: number;
|
|
28
|
+
material: string;
|
|
29
|
+
}
|
|
30
|
+
export interface Placed {
|
|
31
|
+
part: string;
|
|
32
|
+
copy: number;
|
|
33
|
+
layers: Map<string, Layer>;
|
|
34
|
+
rotated: boolean;
|
|
35
|
+
}
|
|
36
|
+
export interface Sheet {
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
material: string;
|
|
40
|
+
thickness: number;
|
|
41
|
+
items: Placed[];
|
|
42
|
+
paths: LayerPath[];
|
|
43
|
+
svg: string;
|
|
44
|
+
dxf: string;
|
|
45
|
+
}
|
|
46
|
+
export interface RenderResult {
|
|
47
|
+
sheets: Sheet[];
|
|
48
|
+
width: number;
|
|
49
|
+
height: number;
|
|
50
|
+
paths: LayerPath[];
|
|
51
|
+
svg: string;
|
|
52
|
+
parts: PartInfo[];
|
|
53
|
+
layers: LayerDef[];
|
|
54
|
+
warnings: string[];
|
|
55
|
+
echoes: string[];
|
|
56
|
+
}
|
|
57
|
+
export declare function render(source: string, options?: RenderOptions): RenderResult;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const LIBRARIES: Record<string, string>;
|
package/dist/stdlib.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const LIBRARIES: Record<string, string>;
|
package/dist/text.d.cts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Poly } from './geometry.cjs';
|
|
2
|
+
import { type Cmd } from './paths.cjs';
|
|
3
|
+
export type FontSource = ArrayBuffer | Uint8Array;
|
|
4
|
+
interface OtFont {
|
|
5
|
+
getPath(text: string, x: number, y: number, size: number, options?: object): {
|
|
6
|
+
commands: Cmd[];
|
|
7
|
+
};
|
|
8
|
+
getAdvanceWidth(text: string, size: number, options?: object): number;
|
|
9
|
+
ascender: number;
|
|
10
|
+
descender: number;
|
|
11
|
+
unitsPerEm: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class FontBook {
|
|
14
|
+
private sources;
|
|
15
|
+
private fallback?;
|
|
16
|
+
private parsed;
|
|
17
|
+
readonly missing: Set<string>;
|
|
18
|
+
constructor(sources: Record<string, FontSource>, fallback?: string | undefined);
|
|
19
|
+
names(): string[];
|
|
20
|
+
get(name: string): OtFont;
|
|
21
|
+
}
|
|
22
|
+
export interface TextOptions {
|
|
23
|
+
size: number;
|
|
24
|
+
font: string;
|
|
25
|
+
halign: string;
|
|
26
|
+
valign: string;
|
|
27
|
+
spacing: number;
|
|
28
|
+
}
|
|
29
|
+
export declare function textRegions(book: FontBook, text: string, o: TextOptions): Poly[];
|
|
30
|
+
export declare function textMetrics(book: FontBook, text: string, o: TextOptions): {
|
|
31
|
+
advance: number;
|
|
32
|
+
bounds: number[][];
|
|
33
|
+
ascent: number;
|
|
34
|
+
descent: number;
|
|
35
|
+
};
|
|
36
|
+
export {};
|
package/dist/text.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type Poly } from './geometry.js';
|
|
2
|
+
import { type Cmd } from './paths.js';
|
|
3
|
+
export type FontSource = ArrayBuffer | Uint8Array;
|
|
4
|
+
interface OtFont {
|
|
5
|
+
getPath(text: string, x: number, y: number, size: number, options?: object): {
|
|
6
|
+
commands: Cmd[];
|
|
7
|
+
};
|
|
8
|
+
getAdvanceWidth(text: string, size: number, options?: object): number;
|
|
9
|
+
ascender: number;
|
|
10
|
+
descender: number;
|
|
11
|
+
unitsPerEm: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class FontBook {
|
|
14
|
+
private sources;
|
|
15
|
+
private fallback?;
|
|
16
|
+
private parsed;
|
|
17
|
+
readonly missing: Set<string>;
|
|
18
|
+
constructor(sources: Record<string, FontSource>, fallback?: string | undefined);
|
|
19
|
+
names(): string[];
|
|
20
|
+
get(name: string): OtFont;
|
|
21
|
+
}
|
|
22
|
+
export interface TextOptions {
|
|
23
|
+
size: number;
|
|
24
|
+
font: string;
|
|
25
|
+
halign: string;
|
|
26
|
+
valign: string;
|
|
27
|
+
spacing: number;
|
|
28
|
+
}
|
|
29
|
+
export declare function textRegions(book: FontBook, text: string, o: TextOptions): Poly[];
|
|
30
|
+
export declare function textMetrics(book: FontBook, text: string, o: TextOptions): {
|
|
31
|
+
advance: number;
|
|
32
|
+
bounds: number[][];
|
|
33
|
+
ascent: number;
|
|
34
|
+
descent: number;
|
|
35
|
+
};
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Expr, Param } from './ast.cjs';
|
|
2
|
+
export interface Range {
|
|
3
|
+
type: 'range';
|
|
4
|
+
start: number;
|
|
5
|
+
step: number;
|
|
6
|
+
end: number;
|
|
7
|
+
}
|
|
8
|
+
export interface Closure {
|
|
9
|
+
type: 'function';
|
|
10
|
+
params: Param[];
|
|
11
|
+
body: Expr;
|
|
12
|
+
scope: unknown;
|
|
13
|
+
name?: string;
|
|
14
|
+
}
|
|
15
|
+
export type Value = number | string | boolean | undefined | Value[] | Range | Closure;
|
|
16
|
+
export declare const isRange: (v: Value) => v is Range;
|
|
17
|
+
export declare const isFn: (v: Value) => v is Closure;
|
|
18
|
+
export declare const isNum: (v: Value) => v is number;
|
|
19
|
+
export declare function rangeValues(r: Range, limit: number): number[];
|
|
20
|
+
export declare function truthy(v: Value): boolean;
|
|
21
|
+
export declare function equals(a: Value, b: Value): boolean;
|
|
22
|
+
export declare function typeName(v: Value): string;
|
|
23
|
+
export declare function show(v: Value): string;
|
|
24
|
+
export declare function str(v: Value): string;
|
|
25
|
+
export declare function fmt(n: number): string;
|
package/dist/values.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Expr, Param } from './ast.js';
|
|
2
|
+
export interface Range {
|
|
3
|
+
type: 'range';
|
|
4
|
+
start: number;
|
|
5
|
+
step: number;
|
|
6
|
+
end: number;
|
|
7
|
+
}
|
|
8
|
+
export interface Closure {
|
|
9
|
+
type: 'function';
|
|
10
|
+
params: Param[];
|
|
11
|
+
body: Expr;
|
|
12
|
+
scope: unknown;
|
|
13
|
+
name?: string;
|
|
14
|
+
}
|
|
15
|
+
export type Value = number | string | boolean | undefined | Value[] | Range | Closure;
|
|
16
|
+
export declare const isRange: (v: Value) => v is Range;
|
|
17
|
+
export declare const isFn: (v: Value) => v is Closure;
|
|
18
|
+
export declare const isNum: (v: Value) => v is number;
|
|
19
|
+
export declare function rangeValues(r: Range, limit: number): number[];
|
|
20
|
+
export declare function truthy(v: Value): boolean;
|
|
21
|
+
export declare function equals(a: Value, b: Value): boolean;
|
|
22
|
+
export declare function typeName(v: Value): string;
|
|
23
|
+
export declare function show(v: Value): string;
|
|
24
|
+
export declare function str(v: Value): string;
|
|
25
|
+
export declare function fmt(n: number): string;
|
package/docs/cli.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Command line
|
|
2
|
+
|
|
3
|
+
The `kerf` command renders `.kerf` files to SVG, DXF or JSON. It needs
|
|
4
|
+
Node.js 20 or newer and comes with the `@mylasertools/kerfscript` npm
|
|
5
|
+
package.
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install --global @mylasertools/kerfscript
|
|
9
|
+
kerf render box.kerf -o box.svg
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Or without installing:
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npx @mylasertools/kerfscript render box.kerf -o box.svg
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Commands
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
kerf render <file.kerf> [-o out.svg] [options]
|
|
22
|
+
kerf params <file.kerf> # settings as JSON
|
|
23
|
+
kerf check <file.kerf> # parts, sizes, cut length, sheets and warnings
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Options
|
|
27
|
+
|
|
28
|
+
| Option | What it does |
|
|
29
|
+
| --------------------- | ---------------------------------------------------------------------- |
|
|
30
|
+
| `-o, --out <file>` | output file, `.svg`, `.dxf` or `.json`; default `<file>.svg` |
|
|
31
|
+
| `-D name=value` | set a setting; the value is KerfScript: `40`, `"Oak"`, `true`, `[1,2]` |
|
|
32
|
+
| `-p, --params <file>` | JSON file of setting values |
|
|
33
|
+
| `--font <file.ttf>` | font for `text()`; repeat for more fonts. The name is the file name |
|
|
34
|
+
| `--kerf <mm>` | override kerf compensation for every part |
|
|
35
|
+
| `--sheet <W>x<H>` | sheet size for packing, in mm |
|
|
36
|
+
| `--gap <mm>` | space between packed parts |
|
|
37
|
+
| `--margin <mm>` | space between the parts and the sheet edge (default: the gap) |
|
|
38
|
+
| `--no-pack` | keep parts where the program placed them |
|
|
39
|
+
| `--guides` | include guide layer geometry |
|
|
40
|
+
| `--split` | write one file per sheet (`out-1.svg`, `out-2.svg`, ...) |
|
|
41
|
+
| `-h, --help` | show help |
|
|
42
|
+
| `-v, --version` | show the version |
|
|
43
|
+
|
|
44
|
+
## Examples
|
|
45
|
+
|
|
46
|
+
```sh
|
|
47
|
+
kerf render sign.kerf -D 'name="Ada"' --font Inter-Bold.ttf -o ada.svg
|
|
48
|
+
kerf render box.kerf --sheet 400x300 --kerf 0.12 --split -o box.svg
|
|
49
|
+
kerf render box.kerf -o box.dxf
|
|
50
|
+
kerf check box.kerf
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Warnings go to standard error and do not stop the render. Errors stop it with
|
|
54
|
+
the line and column, and a non-zero exit code.
|
|
55
|
+
|
|
56
|
+
## Fonts
|
|
57
|
+
|
|
58
|
+
KerfScript does not ship fonts and never reads system fonts, so a file
|
|
59
|
+
renders the same everywhere. Pass the fonts a design uses with `--font`. A
|
|
60
|
+
design that asks for `font = "Inter-Bold"` needs `--font Inter-Bold.ttf`; the
|
|
61
|
+
first font given is the default.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Laser software
|
|
2
|
+
|
|
3
|
+
KerfScript writes ordinary SVG and DXF files, so any program that reads
|
|
4
|
+
those can open them. This page says what we have actually checked, in which
|
|
5
|
+
version, and what you still need to set up yourself.
|
|
6
|
+
|
|
7
|
+
## What is in the files
|
|
8
|
+
|
|
9
|
+
**SVG**
|
|
10
|
+
|
|
11
|
+
- Size in millimetres (`width="100mm"`), with a matching `viewBox`, so one
|
|
12
|
+
unit is one millimetre.
|
|
13
|
+
- One group per layer, marked as an Inkscape layer and named after it:
|
|
14
|
+
`engrave`, your own layers, `score`, `cut`, `guide`.
|
|
15
|
+
- Cut lines red `#ff0000`, score lines blue `#0000ff`, 0.1 mm hairline
|
|
16
|
+
strokes. Engraved areas are filled black `#000000` with the even-odd rule.
|
|
17
|
+
- Holes and inner cuts come before outer outlines.
|
|
18
|
+
|
|
19
|
+
**DXF**
|
|
20
|
+
|
|
21
|
+
- R12 (AC1009) polylines, units set to millimetres.
|
|
22
|
+
- One DXF layer per KerfScript layer, in capitals (`CUT`, `SCORE`,
|
|
23
|
+
`ENGRAVE`), with matching AutoCAD colours.
|
|
24
|
+
- DXF R12 has no fills. Engraved areas arrive as outlines; set that layer to
|
|
25
|
+
fill in your laser software.
|
|
26
|
+
- A DXF holds one sheet. Use `--split` for designs with several sheets.
|
|
27
|
+
|
|
28
|
+
## Checked
|
|
29
|
+
|
|
30
|
+
| Program | Version | SVG | DXF | How |
|
|
31
|
+
| -------- | ------- | --- | --- | --------------------------- |
|
|
32
|
+
| Inkscape | 1.4.2 | yes | yes | automatic, `npm run compat` |
|
|
33
|
+
|
|
34
|
+
`npm run compat` renders six reference models (the calibration square, the
|
|
35
|
+
kerf test, a six-panel finger-jointed box, a living hinge card, a coaster
|
|
36
|
+
with an engraved ring, and a jigsaw puzzle), opens every SVG and DXF in
|
|
37
|
+
Inkscape from the command line, and checks that:
|
|
38
|
+
|
|
39
|
+
- the size of the drawing matches KerfScript's geometry within 0.02 mm,
|
|
40
|
+
kerf compensation included;
|
|
41
|
+
- every layer arrives as a layer with the right name;
|
|
42
|
+
- engraved layers are filled in the SVG.
|
|
43
|
+
|
|
44
|
+
All six passed in both formats on 28 October 2026.
|
|
45
|
+
|
|
46
|
+
## Not checked yet
|
|
47
|
+
|
|
48
|
+
We have not yet run the reference set through **LightBurn**, **xTool
|
|
49
|
+
Studio** or **xTool Creative Space**, **RDWorks** or **LaserGRBL**, and we
|
|
50
|
+
have not cut it on machines outside MyLaserTools. Until we have, treat them as
|
|
51
|
+
untested: they read standard SVG and DXF, but each imports colours, layers
|
|
52
|
+
and fills its own way.
|
|
53
|
+
|
|
54
|
+
If you try one, we would like to hear what happened. The checklist below is
|
|
55
|
+
what we look at.
|
|
56
|
+
|
|
57
|
+
## Checklist for a new program
|
|
58
|
+
|
|
59
|
+
Open `calibration-square.svg` and `box.svg` from the
|
|
60
|
+
[models](https://kerfscript.mylasertools.com/models/) and check:
|
|
61
|
+
|
|
62
|
+
1. **Size.** The square is 100.15 mm wide with the default 0.15 mm kerf
|
|
63
|
+
(100 mm plus compensation), not 26.4 mm or 377.95 mm. If it is wrong, the
|
|
64
|
+
program ignored the millimetre units; look for an import DPI or unit
|
|
65
|
+
setting.
|
|
66
|
+
2. **Layers.** Cut, score and engrave arrive as separate layers or colours,
|
|
67
|
+
so each can get its own power and speed.
|
|
68
|
+
3. **Fill.** The engraved text on the square is filled, not just outlined.
|
|
69
|
+
4. **Holes.** The hole in the square is cut, and engraving does not appear
|
|
70
|
+
inside it.
|
|
71
|
+
5. **Order.** The program's cut order cuts holes before outlines. Most
|
|
72
|
+
programs have an "inner shapes first" option; turn it on.
|
|
73
|
+
6. **Parts.** All six box panels arrive, none overlapping.
|
|
74
|
+
|
|
75
|
+
## What the file does not decide
|
|
76
|
+
|
|
77
|
+
The file describes geometry and layers. Your laser software decides how the
|
|
78
|
+
machine runs it:
|
|
79
|
+
|
|
80
|
+
- **Order of operations.** Layer order in an SVG is a hint. Most programs
|
|
81
|
+
sort operations themselves; check that engraving runs before cutting and
|
|
82
|
+
inner cuts before outer ones.
|
|
83
|
+
- **Power, speed, passes and focus** for each layer and material.
|
|
84
|
+
- **Material and thickness.** KerfScript records them per sheet; make sure
|
|
85
|
+
the file you send matches the sheet in the machine.
|
|
86
|
+
- **Kerf.** If your laser software also applies kerf offset, turn one of them
|
|
87
|
+
off, or parts will be compensated twice.
|
|
88
|
+
|
|
89
|
+
Always run a test on scrap before cutting good material.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Settings
|
|
2
|
+
|
|
3
|
+
Top-level variables with a plain value become **settings**: sliders, menus,
|
|
4
|
+
checkboxes and text boxes in the playground, on MyLaserTools, and in any tool
|
|
5
|
+
that reads OpenSCAD customizer comments. The format is the same as
|
|
6
|
+
OpenSCAD's.
|
|
7
|
+
|
|
8
|
+
```kerf
|
|
9
|
+
/* [Size] */
|
|
10
|
+
// Outer width
|
|
11
|
+
width = 120; // [40:5:400]
|
|
12
|
+
// Outer depth
|
|
13
|
+
depth = 80; // [200]
|
|
14
|
+
|
|
15
|
+
/* [Style] */
|
|
16
|
+
shape = "round"; // [round:Round, square:Square]
|
|
17
|
+
holes = 3; // [2, 3, 4]
|
|
18
|
+
lid = true;
|
|
19
|
+
label = "Tools";
|
|
20
|
+
|
|
21
|
+
/* [Hidden] */
|
|
22
|
+
wall = 3;
|
|
23
|
+
|
|
24
|
+
rect([width, depth]);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## What becomes a setting
|
|
28
|
+
|
|
29
|
+
A top-level assignment whose value is a number, a string, `true` or `false`,
|
|
30
|
+
or a list of numbers. An expression like `width / 2` is not a setting; it is
|
|
31
|
+
worked out from the others.
|
|
32
|
+
|
|
33
|
+
## Comments
|
|
34
|
+
|
|
35
|
+
| Comment after the value | Control |
|
|
36
|
+
| --------------------------------- | ----------------------------- |
|
|
37
|
+
| `// [40:5:400]` | slider from 40 to 400, step 5 |
|
|
38
|
+
| `// [40:400]` | slider from 40 to 400 |
|
|
39
|
+
| `// [200]` | number up to 200 |
|
|
40
|
+
| `// [2, 3, 4]` | menu of those values |
|
|
41
|
+
| `// [round:Round, square:Square]` | menu with labels |
|
|
42
|
+
| none, on `true` or `false` | checkbox |
|
|
43
|
+
| none, on a string | text box |
|
|
44
|
+
|
|
45
|
+
- `/* [Group name] */` starts a group for the settings below it.
|
|
46
|
+
`/* [Hidden] */` hides the ones that follow.
|
|
47
|
+
- A `//` comment on its own line just above a setting is its caption.
|
|
48
|
+
A comment at the end of the line before does not count.
|
|
49
|
+
- Put a blank line between a file's opening comment and its first setting,
|
|
50
|
+
so the opening comment is not taken as that setting's caption.
|
|
51
|
+
|
|
52
|
+
## Changing settings without editing the file
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
kerf render box.kerf -D width=200 -D 'label="Oak"'
|
|
56
|
+
kerf render box.kerf --params oak.json
|
|
57
|
+
kerf params box.kerf
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
`-D` values are KerfScript values, so strings need their quotes. `kerf params`
|
|
61
|
+
prints the settings as JSON. From JavaScript, pass `params` to `render()` and
|
|
62
|
+
read them with `parameters()`; see [JavaScript API](javascript.md).
|