altium-toolkit 0.1.1 → 0.1.16
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/README.md +24 -6
- package/docs/api.md +42 -4
- package/docs/model-format.md +95 -5
- package/docs/schemas/altium_toolkit/normalized_model_a1.schema.json +553 -0
- package/docs/testing.md +7 -2
- package/package.json +6 -2
- package/spec/library-scope.md +7 -1
- package/src/core/altium/AltiumParser.mjs +22 -325
- package/src/core/altium/NormalizedModelSchema.mjs +28 -0
- package/src/core/altium/PcbArcPrimitiveParser.mjs +87 -0
- package/src/core/altium/PcbBinaryPrimitiveParser.mjs +43 -370
- package/src/core/altium/PcbBoardRegionSemanticsParser.mjs +477 -0
- package/src/core/altium/PcbComponentAnnotationNormalizer.mjs +290 -0
- package/src/core/altium/PcbComponentBodyPlacementNormalizer.mjs +52 -0
- package/src/core/altium/PcbComponentPrimitiveIndexer.mjs +109 -0
- package/src/core/altium/PcbEmbeddedFontExtractor.mjs +484 -0
- package/src/core/altium/PcbFillPrimitiveParser.mjs +84 -0
- package/src/core/altium/PcbFontMetricsParser.mjs +308 -0
- package/src/core/altium/PcbGeometryFlipper.mjs +244 -0
- package/src/core/altium/PcbLayerIdCodec.mjs +136 -0
- package/src/core/altium/PcbLibModelParser.mjs +202 -0
- package/src/core/altium/PcbLibStreamExtractor.mjs +968 -0
- package/src/core/altium/PcbModelParser.mjs +618 -66
- package/src/core/altium/PcbOutlineRecovery.mjs +4 -112
- package/src/core/altium/PcbPadPrimitiveParser.mjs +347 -0
- package/src/core/altium/PcbPadShapeCodec.mjs +158 -0
- package/src/core/altium/PcbPadStackParser.mjs +903 -0
- package/src/core/altium/PcbPrimitiveOwnershipIndexParser.mjs +60 -0
- package/src/core/altium/PcbPrimitiveParameterParser.mjs +212 -0
- package/src/core/altium/PcbPrimitiveRecordSlicer.mjs +243 -0
- package/src/core/altium/PcbRawRecordRegistry.mjs +831 -0
- package/src/core/altium/PcbRegionPrimitiveParser.mjs +317 -0
- package/src/core/altium/PcbRuleParser.mjs +587 -0
- package/src/core/altium/PcbStreamExtractor.mjs +127 -4
- package/src/core/altium/PcbTextPrimitiveParser.mjs +537 -0
- package/src/core/altium/PcbTrackPrimitiveParser.mjs +87 -0
- package/src/core/altium/PcbViaPrimitiveParser.mjs +88 -0
- package/src/core/altium/PcbViaStackParser.mjs +548 -0
- package/src/core/altium/PcbWideStringTableParser.mjs +108 -0
- package/src/core/altium/PrjPcbModelParser.mjs +797 -0
- package/src/core/altium/SchematicComponentTextResolver.mjs +355 -0
- package/src/parser.mjs +13 -0
- package/src/renderers.mjs +5 -0
- package/src/styles/altium-renderers.css +11 -6
- package/src/ui/PcbCopperPrimitiveSplitter.mjs +113 -0
- package/src/ui/PcbEdgeFacingGlyphNormalizer.mjs +6 -5
- package/src/ui/PcbEmbeddedFontFaceRenderer.mjs +126 -0
- package/src/ui/PcbFootprintPrimitiveSelector.mjs +27 -6
- package/src/ui/PcbRegionPrimitiveRenderer.mjs +243 -0
- package/src/ui/PcbSideResolvedRenderModel.mjs +336 -0
- package/src/ui/PcbSvgRenderer.mjs +101 -109
- package/src/ui/PcbTextPrimitiveRenderer.mjs +252 -0
- package/src/ui/SchematicSheetChromeRenderer.mjs +2 -93
- package/src/ui/SchematicSheetZoneRenderer.mjs +104 -0
package/README.md
CHANGED
|
@@ -10,14 +10,24 @@ Altium Toolkit is an ESM JavaScript library for parsing native Altium
|
|
|
10
10
|
schematic and PCB documents and rendering deterministic, non-interactive
|
|
11
11
|
outputs from the recovered model.
|
|
12
12
|
|
|
13
|
-
The package was extracted from ECAD Forge
|
|
14
|
-
|
|
13
|
+
The package was extracted from [ECAD Forge](https://ecadforge.app/), where it
|
|
14
|
+
is used for browser-based Altium document parsing and deterministic render
|
|
15
|
+
output. Its parser behavior, normalized model shape, and renderer output can be
|
|
16
|
+
reused by other browser or Node-based tools.
|
|
15
17
|
|
|
16
18
|
## Features
|
|
17
19
|
|
|
18
|
-
- Parse standalone native `.SchDoc
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
- Parse standalone native `.SchDoc`, `.PcbDoc`, `.PcbLib`, and `.PrjPcb` files from
|
|
21
|
+
`ArrayBuffer`
|
|
22
|
+
- Recover schematic records, PCB outlines, placements, PCB library footprints,
|
|
23
|
+
project document references, variants, parameters, primitives, embedded
|
|
24
|
+
schematic images, component annotations from PrimitiveParameters/Text streams,
|
|
25
|
+
embedded PCB STEP payload metadata, and embedded PCB/PcbLib font payloads with
|
|
26
|
+
basic text metrics
|
|
27
|
+
- Preserve raw PCB primitive records through a read-only record registry so
|
|
28
|
+
unsupported or partially decoded stream data remains inspectable
|
|
29
|
+
- Emit versioned normalized model roots with a machine-readable JSON Schema
|
|
30
|
+
contract
|
|
21
31
|
- Render schematic SVG, PCB SVG, and grouped BOM HTML
|
|
22
32
|
- Build non-interactive PCB 3D scene-description data for host applications
|
|
23
33
|
- Render a static 3D board summary
|
|
@@ -25,6 +35,9 @@ shape, and renderer output can be reused by other browser or Node-based tools.
|
|
|
25
35
|
|
|
26
36
|
## Install
|
|
27
37
|
|
|
38
|
+
The package is published on npm as
|
|
39
|
+
[`altium-toolkit`](https://www.npmjs.com/package/altium-toolkit).
|
|
40
|
+
|
|
28
41
|
```bash
|
|
29
42
|
npm install altium-toolkit
|
|
30
43
|
```
|
|
@@ -36,14 +49,18 @@ import {
|
|
|
36
49
|
AltiumParser,
|
|
37
50
|
SchematicSvgRenderer,
|
|
38
51
|
PcbSvgRenderer,
|
|
52
|
+
preparePcbSideResolvedRenderModel,
|
|
39
53
|
BomTableRenderer,
|
|
40
54
|
PcbScene3dBuilder
|
|
41
55
|
} from 'altium-toolkit'
|
|
42
56
|
|
|
43
57
|
const documentModel = AltiumParser.parseArrayBuffer(file.name, arrayBuffer)
|
|
58
|
+
const backRenderModel = preparePcbSideResolvedRenderModel(documentModel, {
|
|
59
|
+
side: 'back'
|
|
60
|
+
})
|
|
44
61
|
|
|
45
62
|
const schematicMarkup = SchematicSvgRenderer.render(documentModel)
|
|
46
|
-
const pcbMarkup = PcbSvgRenderer.render(
|
|
63
|
+
const pcbMarkup = PcbSvgRenderer.render(backRenderModel)
|
|
47
64
|
const bomMarkup = BomTableRenderer.render(documentModel.bom || [])
|
|
48
65
|
const sceneDescription = PcbScene3dBuilder.build(documentModel)
|
|
49
66
|
```
|
|
@@ -58,6 +75,7 @@ import 'altium-toolkit/styles/altium-renderers.css'
|
|
|
58
75
|
|
|
59
76
|
- [API](docs/api.md)
|
|
60
77
|
- [Model Format](docs/model-format.md)
|
|
78
|
+
- [Normalized Model Schema](docs/schemas/altium_toolkit/normalized_model_a1.schema.json)
|
|
61
79
|
- [Testing](docs/testing.md)
|
|
62
80
|
- [Scope](spec/library-scope.md)
|
|
63
81
|
|
package/docs/api.md
CHANGED
|
@@ -27,10 +27,41 @@ import { AltiumParser } from 'altium-toolkit/parser'
|
|
|
27
27
|
const documentModel = AltiumParser.parseArrayBuffer(fileName, arrayBuffer)
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
`fileName` is used to infer schematic
|
|
31
|
-
The parser accepts native `.SchDoc
|
|
32
|
-
`ArrayBuffer` and returns the
|
|
33
|
-
[Model Format](model-format.md).
|
|
30
|
+
`fileName` is used to infer schematic, PCB document, PCB footprint-library, or
|
|
31
|
+
PCB project parsing from the extension. The parser accepts native `.SchDoc`,
|
|
32
|
+
`.PcbDoc`, `.PcbLib`, and `.PrjPcb` bytes as an `ArrayBuffer` and returns the
|
|
33
|
+
normalized model described in [Model Format](model-format.md). Every parser
|
|
34
|
+
root includes a top-level `schema` id for the emitted normalized model
|
|
35
|
+
contract.
|
|
36
|
+
|
|
37
|
+
PCB parsing reads the main primitive streams together with sidecar streams such
|
|
38
|
+
as `PrimitiveParameters/Data` and `WideStrings6/Data`. Component parameters are
|
|
39
|
+
joined by native primitive unique id, and modern `Texts6` designator records may
|
|
40
|
+
resolve their display string through the wide-string table before the
|
|
41
|
+
normalized component list and BOM are built.
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
import { NormalizedModelSchema } from 'altium-toolkit/parser'
|
|
45
|
+
|
|
46
|
+
if (documentModel.schema !== NormalizedModelSchema.CURRENT_SCHEMA_ID) {
|
|
47
|
+
throw new Error('Unsupported normalized model schema')
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Specialized parser helpers are exported for lower-level integrations, including
|
|
52
|
+
`PcbBoardRegionSemanticsParser`, `PcbComponentPrimitiveIndexer`,
|
|
53
|
+
`PcbEmbeddedFontExtractor`, `PcbFontMetricsParser`, `PcbPadStackParser`,
|
|
54
|
+
`PcbViaStackParser`, `PcbRuleParser`, and `PcbRawRecordRegistry`.
|
|
55
|
+
`PcbBoardRegionSemanticsParser` exposes the substack and bending-line
|
|
56
|
+
normalization used by `.PcbDoc` models. `PcbComponentPrimitiveIndexer` exposes
|
|
57
|
+
the native component-index grouping used to populate
|
|
58
|
+
`pcb.componentPrimitives` and `pcb.componentPrimitiveGroups`. The pad, via, and
|
|
59
|
+
rule helpers expose the same mask/cache, stack, and typed-constraint
|
|
60
|
+
normalization used by `.PcbDoc` parsing. The font helpers expose the same
|
|
61
|
+
embedded font payload and metric shape that `.PcbDoc` and `.PcbLib` parsing adds
|
|
62
|
+
to normalized models. `PcbRawRecordRegistry` exposes immutable primitive stream
|
|
63
|
+
descriptors and the raw-record preservation helpers used by the PcbDoc/PcbLib
|
|
64
|
+
extractors.
|
|
34
65
|
|
|
35
66
|
## Renderers
|
|
36
67
|
|
|
@@ -38,12 +69,19 @@ The parser accepts native `.SchDoc` and `.PcbDoc` document bytes as an
|
|
|
38
69
|
import {
|
|
39
70
|
SchematicSvgRenderer,
|
|
40
71
|
PcbSvgRenderer,
|
|
72
|
+
PcbSideResolvedRenderModel,
|
|
73
|
+
preparePcbSideResolvedRenderModel,
|
|
41
74
|
BomTableRenderer
|
|
42
75
|
} from 'altium-toolkit/renderers'
|
|
43
76
|
```
|
|
44
77
|
|
|
45
78
|
- `SchematicSvgRenderer.render(documentModel)` returns schematic SVG markup.
|
|
46
79
|
- `PcbSvgRenderer.render(documentModel)` returns PCB SVG markup.
|
|
80
|
+
- `PcbSideResolvedRenderModel.resolve(documentModel, { side })` and
|
|
81
|
+
`preparePcbSideResolvedRenderModel(documentModel, { side })` return a
|
|
82
|
+
side-specific PCB render model for top-oriented renderers. Use
|
|
83
|
+
`side: 'back'` to project bottom components, documentation layers, copper
|
|
84
|
+
primitives, vias, and pad stack geometry into the top-facing render surface.
|
|
47
85
|
- `BomTableRenderer.render(rows)` returns grouped BOM table markup.
|
|
48
86
|
|
|
49
87
|
Renderer output is deterministic string markup. The library does not attach DOM
|
package/docs/model-format.md
CHANGED
|
@@ -11,11 +11,22 @@ The parser returns one object per parsed native document.
|
|
|
11
11
|
|
|
12
12
|
## Common Fields
|
|
13
13
|
|
|
14
|
-
- `
|
|
14
|
+
- `schema`: normalized model schema id, currently
|
|
15
|
+
`urn:altium-toolkit:normalized-model:a1`
|
|
16
|
+
- `kind`: `schematic`, `pcb`, `pcb-library`, or `project`
|
|
17
|
+
- `fileType`: `SchDoc`, `PcbDoc`, `PcbLib`, or `PrjPcb`
|
|
15
18
|
- `fileName`: original file name passed to the parser
|
|
16
19
|
- `diagnostics`: parser warnings and recovery notes
|
|
17
20
|
- `bom`: grouped component metadata where available
|
|
18
21
|
|
|
22
|
+
## Schema Contracts
|
|
23
|
+
|
|
24
|
+
The current root model contract is published as a JSON Schema at
|
|
25
|
+
[`docs/schemas/altium_toolkit/normalized_model_a1.schema.json`](schemas/altium_toolkit/normalized_model_a1.schema.json).
|
|
26
|
+
Parser roots expose the same id through the top-level `schema` field, and
|
|
27
|
+
library consumers can compare it with
|
|
28
|
+
`NormalizedModelSchema.CURRENT_SCHEMA_ID`.
|
|
29
|
+
|
|
19
30
|
## Schematic Fields
|
|
20
31
|
|
|
21
32
|
Schematic documents include recovered `schematic` data with sheet metadata,
|
|
@@ -27,10 +38,89 @@ the SVG renderer maps them into SVG space.
|
|
|
27
38
|
|
|
28
39
|
PCB documents include recovered `pcb` data with board outline geometry,
|
|
29
40
|
component placements, layer metadata, primitive detail, copper, pads, vias,
|
|
30
|
-
fills, arcs, embedded model references,
|
|
41
|
+
fills, arcs, embedded model references, model body placement metadata,
|
|
42
|
+
`embeddedFonts`, and `rawRecords`. Embedded font entries include the recovered
|
|
43
|
+
family/style, source stream, self-contained base64 payload, TrueType/OpenType
|
|
44
|
+
format hint, MIME type, byte counts, and basic sfnt metrics such as
|
|
45
|
+
units-per-em, ascent, descent, cell height, cap height, average advance width,
|
|
46
|
+
and weight class. Decoded TrueType PCB text primitives may reference these
|
|
47
|
+
metrics through `embeddedFontIndex` and `fontMetrics`. Raw record entries expose
|
|
48
|
+
the registry id, source stream, primitive family/type, byte offsets, byte
|
|
49
|
+
counts, parse status, encoding style, and a base64 payload for unsupported or
|
|
50
|
+
partially decoded primitive stream data.
|
|
51
|
+
|
|
52
|
+
Component-owned PCB primitives are exposed directly from native Altium owner
|
|
53
|
+
indexes. `pcb.componentPrimitives[componentIndex]` returns the grouped pads,
|
|
54
|
+
tracks, arcs, fills, vias, regions, texts, and component bodies linked to that
|
|
55
|
+
component; missing sparse component indexes are represented as `null`. The
|
|
56
|
+
compatibility list `pcb.componentPrimitiveGroups` carries the same group objects
|
|
57
|
+
in placement order. Board-owned or net-owned primitives without a native
|
|
58
|
+
`componentIndex` are intentionally left out of these component groups.
|
|
59
|
+
|
|
60
|
+
Component annotations may also include `uniqueId`, `parameters`, and
|
|
61
|
+
`parameterSource` when the PCB contains `PrimitiveParameters/Data` entries keyed
|
|
62
|
+
by the component primitive ID. Modern Texts6 designator records are resolved
|
|
63
|
+
through `WideStrings6/Data` when Altium stores the display string in that table;
|
|
64
|
+
when such a Texts6 designator differs from `SOURCEDESIGNATOR`, the public
|
|
65
|
+
component uses the displayed designator and preserves the original value in
|
|
66
|
+
`baseDesignator` with `displayDesignator` and `designatorSource` metadata.
|
|
67
|
+
Component-owned Texts6 comment/value records are marked with `role: 'comment'`
|
|
68
|
+
and `isComment`; unresolved annotation slots are additionally marked with
|
|
69
|
+
`isPlaceholder`.
|
|
70
|
+
|
|
71
|
+
Decoded pad primitives preserve raw `padFlags` plus named tenting and testpoint
|
|
72
|
+
flags. Pad shape codes are kept as raw `shapeTop` / `shapeMid` / `shapeBottom`
|
|
73
|
+
values and mirrored through normalized `shape*Name` labels plus
|
|
74
|
+
`padShapeNames`. Extended pad records also expose named hole shapes, normalized
|
|
75
|
+
`holeGeometry` for round/square/slot drills, merged `middleLayerPads` entries
|
|
76
|
+
that combine middle-layer size and effective shape data, per-layer shape names,
|
|
77
|
+
pad-cache thermal-relief fields through `padCache`, corrected cache-validity
|
|
78
|
+
fields for plane/thermal/power relief, raw paste/solder mask modes, effective
|
|
79
|
+
mask expansions, and side-specific `hasTop*MaskOpening` /
|
|
80
|
+
`hasBottom*MaskOpening` booleans for renderers that need layer-accurate paste
|
|
81
|
+
and solder-mask decisions.
|
|
82
|
+
|
|
83
|
+
PCB design rules preserve native rule-specific `constraints` as strings and add
|
|
84
|
+
typed views for common consumers. `ruleType` exposes a normalized rule kind and
|
|
85
|
+
category, `constraintValues` parses common numeric units such as mil, mm, inch,
|
|
86
|
+
degrees, percentages, and booleans, and `typedConstraints` maps common Width and
|
|
87
|
+
Clearance rule fields to semantic names such as `minWidth`,
|
|
88
|
+
`preferredWidth`, `maxWidth`, `minClearance`, and `genericClearance`.
|
|
89
|
+
|
|
90
|
+
Board-planning regions are decoded separately from copper regions through
|
|
91
|
+
`pcb.boardRegions`. These entries retain their contour geometry and now add
|
|
92
|
+
rigid-flex semantics from BoardRegions/Data properties: `objectKind`, `name`,
|
|
93
|
+
`layerStackId`, `substackIndex`, `substackName`, flex/rigid flags, `locked3d`,
|
|
94
|
+
`cavityHeight`, and typed `bendingLines`. Bend lines preserve the raw
|
|
95
|
+
semicolon-delimited payload while exposing angle, radius, fold index, endpoint
|
|
96
|
+
coordinates, and calculated affected width in mils. Board-level substack
|
|
97
|
+
metadata is exposed in `pcb.layerSubstacks`, and
|
|
98
|
+
`pcb.boardRegionContexts` provides a compact region-to-substack lookup for
|
|
99
|
+
callers that do not need the full geometry.
|
|
100
|
+
|
|
101
|
+
## PCB Library Fields
|
|
102
|
+
|
|
103
|
+
PCB footprint libraries include recovered `pcbLibrary` data with library header
|
|
104
|
+
properties, optional SectionKeys mappings, ComponentParamsTOC entries, and an
|
|
105
|
+
ordered `footprints` list. Each footprint exposes its source storage name,
|
|
106
|
+
parameters, component metadata, primitive order, unknown record markers, and
|
|
107
|
+
decoded pads, tracks, arcs, vias, fills, texts, and regions. Each footprint also
|
|
108
|
+
preserves raw mixed-format primitive records with the same registry metadata
|
|
109
|
+
shape used by PcbDoc raw records. Library-level `embeddedFonts` uses the same
|
|
110
|
+
payload and metric shape as PCB documents.
|
|
111
|
+
|
|
112
|
+
## Project Fields
|
|
113
|
+
|
|
114
|
+
PCB projects include recovered `project` data from `.PrjPcb` files. The parser
|
|
115
|
+
preserves raw INI sections while also exposing normalized document entries,
|
|
116
|
+
document groups, project parameters, project variants, configurations, and
|
|
117
|
+
output groups. Reachable schematic documents follow the durable project
|
|
118
|
+
metadata convention used by Altium: schematic stubs with only `DocumentPath` and
|
|
119
|
+
`DocumentUniqueId` remain listed, but richer schematic document entries are
|
|
120
|
+
preferred in `project.documentGroups.reachableSchematics`.
|
|
31
121
|
|
|
32
122
|
## Compatibility Rule
|
|
33
123
|
|
|
34
|
-
Consumers should treat unknown fields as additive
|
|
35
|
-
but existing field names and shapes should stay
|
|
36
|
-
|
|
124
|
+
Consumers should treat unknown fields as additive within the same schema id.
|
|
125
|
+
Parser fixes may add detail, but existing field names and shapes should stay
|
|
126
|
+
compatible unless a new schema id explicitly documents a model migration.
|