pcb-scene3d-viewer 1.1.22 → 1.1.44
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/AGENTS.md +4 -3
- package/README.md +3 -2
- package/docs/api.md +59 -1
- package/docs/circuitjson.md +206 -22
- package/docs/model-format.md +65 -3
- package/package.json +2 -2
- package/spec/library-scope.md +2 -2
- package/src/CircuitJsonCadModelAssetResolver.mjs +261 -0
- package/src/PcbAssemblyBoardSubstrateBuilder.mjs +49 -10
- package/src/PcbAssemblyComponentMeshBuilder.mjs +842 -0
- package/src/PcbAssemblyFillGeometryResolver.mjs +579 -0
- package/src/PcbAssemblyFillRingNormalizer.mjs +209 -0
- package/src/PcbAssemblyGeometryBuildProgress.mjs +3 -0
- package/src/PcbAssemblyGeometryBuilder.mjs +94 -174
- package/src/PcbAssemblyGltfModelMeshParser.mjs +969 -0
- package/src/PcbAssemblyGltfValidator.mjs +460 -0
- package/src/PcbAssemblyGltfWriter.mjs +978 -0
- package/src/PcbAssemblyModelMeshLoader.mjs +330 -2
- package/src/PcbAssemblyPadMeshBuilder.mjs +9 -7
- package/src/PcbAssemblyTextModelMeshParser.mjs +725 -0
- package/src/PcbModelArchiveExporter.mjs +17 -2
- package/src/PcbScene3dCircuitJsonAdapter.mjs +585 -246
- package/src/PcbScene3dCircuitJsonCopperPourBuilder.mjs +298 -0
- package/src/PcbScene3dCircuitJsonDocumentationArtworkBuilder.mjs +606 -0
- package/src/PcbScene3dCircuitJsonGeometry.mjs +542 -0
- package/src/PcbScene3dCircuitJsonLayer.mjs +110 -0
- package/src/PcbScene3dCircuitJsonModelTransform.mjs +232 -0
- package/src/PcbScene3dCircuitJsonModelUrlResolver.mjs +142 -0
- package/src/PcbScene3dCircuitJsonSilkscreenBuilder.mjs +729 -0
- package/src/PcbScene3dCircuitJsonSolderPasteBuilder.mjs +359 -0
- package/src/PcbScene3dCircuitJsonThermalSpokeBuilder.mjs +167 -0
- package/src/PcbScene3dCircuitJsonTraceRouteBuilder.mjs +335 -0
- package/src/PcbScene3dComponentVisibility.mjs +9 -6
- package/src/PcbScene3dController.mjs +25 -55
- package/src/PcbScene3dCopperDetailFilter.mjs +86 -9
- package/src/PcbScene3dCopperDetailGroupBuilder.mjs +186 -15
- package/src/PcbScene3dCopperDrillCutoutBuilder.mjs +258 -0
- package/src/PcbScene3dCopperFactory.mjs +99 -85
- package/src/PcbScene3dCopperFillMeshBuilder.mjs +393 -0
- package/src/PcbScene3dCopperLayerFilter.mjs +32 -3
- package/src/PcbScene3dCutoutGeometryFilter.mjs +17 -14
- package/src/PcbScene3dExternalModelCenteringPolicy.mjs +21 -0
- package/src/PcbScene3dExternalModelOpacity.mjs +51 -0
- package/src/PcbScene3dExternalModelPlacementRepair.mjs +5 -2
- package/src/PcbScene3dExternalModelSourceOriginPolicy.mjs +41 -0
- package/src/PcbScene3dExternalModels.mjs +10 -7
- package/src/PcbScene3dFallbackBodyFactory.mjs +45 -4
- package/src/PcbScene3dFallbackVisibility.mjs +17 -32
- package/src/PcbScene3dFootprintBodyBuilder.mjs +894 -0
- package/src/PcbScene3dMaskCoveredCopperSideGroupBuilder.mjs +68 -0
- package/src/PcbScene3dModelSeatingPolicy.mjs +58 -0
- package/src/PcbScene3dPadFactory.mjs +35 -2
- package/src/PcbScene3dRenderGroupVisibility.mjs +10 -13
- package/src/PcbScene3dRuntime.mjs +99 -91
- package/src/PcbScene3dRuntimeHelpers.mjs +39 -0
- package/src/PcbScene3dRuntimeSurfaceArtworkLoader.mjs +91 -0
- package/src/PcbScene3dSelectionIndexBuilder.mjs +87 -0
- package/src/PcbScene3dSelectionInspectorRenderer.mjs +50 -11
- package/src/PcbScene3dSelectionMarkerFactory.mjs +368 -0
- package/src/PcbScene3dSelectionMarkerOverlay.mjs +70 -0
- package/src/PcbScene3dSelectionStyler.mjs +52 -2
- package/src/PcbScene3dStaticBodyFactory.mjs +30 -8
- package/src/PcbScene3dStepLoader.mjs +42 -6
- package/src/PcbScene3dText.mjs +1 -0
- package/src/PcbScene3dTransparentMeshSplitter.mjs +623 -0
- package/src/PcbScene3dViaFactory.mjs +27 -7
- package/src/scene3d.mjs +4 -0
package/AGENTS.md
CHANGED
|
@@ -35,9 +35,10 @@
|
|
|
35
35
|
## Library Scope
|
|
36
36
|
|
|
37
37
|
- Include browser-side Three.js scene runtime, geometry factories, STEP/WRL
|
|
38
|
-
model loading, component picking, view presets, archive export,
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
model loading, component picking, view presets, archive export, CircuitJSON
|
|
39
|
+
scene adapters and CAD model asset resolution, the optional DOM controller,
|
|
40
|
+
and the optional 3D shell renderer/styles.
|
|
41
|
+
- Do not include ECAD parser logic or source-format-specific scene-description
|
|
41
42
|
builders. Altium and KiCad scene descriptions are produced by their own
|
|
42
43
|
toolkits and passed into this package.
|
|
43
44
|
- Keep renderer fixes universal. Never special-case a specific file name,
|
package/README.md
CHANGED
|
@@ -17,8 +17,9 @@ runtime.
|
|
|
17
17
|
|
|
18
18
|
The package was extracted from [ECAD Forge](https://ecadforge.app/), where it
|
|
19
19
|
is used for browser-based PCB 3D scene rendering. Its runtime, geometry
|
|
20
|
-
factories, model loading, component picking, view presets, archive export,
|
|
21
|
-
optional DOM shell can be reused by other
|
|
20
|
+
factories, model loading, component picking, view presets, archive export,
|
|
21
|
+
GLTF/GLB assembly writing, and optional DOM shell can be reused by other
|
|
22
|
+
browser-based ECAD tools.
|
|
22
23
|
|
|
23
24
|
## Install
|
|
24
25
|
|
package/docs/api.md
CHANGED
|
@@ -63,7 +63,15 @@ Methods:
|
|
|
63
63
|
- `isCircuitJsonModel(value)`: returns true for serialized CircuitJSON arrays.
|
|
64
64
|
- `isDirectCircuitJsonModel(value)`: returns true when the array should bypass
|
|
65
65
|
host `buildScene` callbacks.
|
|
66
|
-
- `build(circuitJson)`: returns a runtime-ready scene description.
|
|
66
|
+
- `build(circuitJson, options?)`: returns a runtime-ready scene description.
|
|
67
|
+
`options.modelUrlResolver` can attach caller-owned URL resolution metadata to
|
|
68
|
+
`cad_component` external models without fetching them. `projectBaseUrl`
|
|
69
|
+
resolves relative model URLs and package-style `node_modules/...` model paths,
|
|
70
|
+
`drawFauxBoard: true` generates a board around component bounds when no board
|
|
71
|
+
or panel exists, `boardDrillQuality` controls generated circular
|
|
72
|
+
drill/cutout sampling, and `showPcbNotes: true` renders note, fabrication,
|
|
73
|
+
and courtyard artwork as silkscreen detail. `showPcbPaste: true` renders
|
|
74
|
+
direct solder-paste artwork as a separate top/bottom overlay.
|
|
67
75
|
|
|
68
76
|
`PcbScene3dController` and `PcbScene3dRuntime` call this adapter automatically
|
|
69
77
|
when they receive direct CircuitJSON input. See
|
|
@@ -121,6 +129,56 @@ worker.postMessage({
|
|
|
121
129
|
Workers respond with `scene3d:success` and `sceneDescription`, or
|
|
122
130
|
`scene3d:error` and `message`.
|
|
123
131
|
|
|
132
|
+
## Assembly Geometry Export
|
|
133
|
+
|
|
134
|
+
### `PcbAssemblyGeometryBuilder.build(sceneDescription, options?)`
|
|
135
|
+
|
|
136
|
+
Builds export meshes from a prepared scene description. `options.modelMeshLoader`
|
|
137
|
+
can provide external model meshes, `options.includeModels: false` skips external
|
|
138
|
+
model loading, and `options.renderFallbackBodies: false` disables procedural
|
|
139
|
+
component bodies for unresolved models. Placements with `renderAsBoundingBox:
|
|
140
|
+
true` are exported as procedural component bodies instead of loading the
|
|
141
|
+
referenced model. Optional solder-paste detail exports as distinct paste meshes
|
|
142
|
+
when present in `sceneDescription.detail.paste`.
|
|
143
|
+
|
|
144
|
+
### `PcbAssemblyGltfWriter.write(options?)`
|
|
145
|
+
|
|
146
|
+
Writes faceted assembly meshes as GLTF 2.0 JSON or binary GLB.
|
|
147
|
+
|
|
148
|
+
Options:
|
|
149
|
+
|
|
150
|
+
- `name`: scene name.
|
|
151
|
+
- `meshes`: export meshes with `vertices`, `faces`, optional RGB or RGBA
|
|
152
|
+
`color`, optional `opacity`, and optional board `texture` data URIs.
|
|
153
|
+
- `format`: `gltf` or `glb`.
|
|
154
|
+
- `binary`: optional boolean equivalent to `format: 'glb'`.
|
|
155
|
+
- `includeSceneMetadata`: when `true`, emits a default camera and punctual light
|
|
156
|
+
for third-party GLTF viewers.
|
|
157
|
+
|
|
158
|
+
Returns a GLTF JSON object for `gltf` and a `Uint8Array` for `glb`. RGBA colors
|
|
159
|
+
or opacity values below `1` are emitted as blended GLTF materials. Mesh
|
|
160
|
+
`vertexColors` are exported as `COLOR_0`, and mesh `material` metadata is
|
|
161
|
+
preserved in material extras.
|
|
162
|
+
|
|
163
|
+
### `new PcbAssemblyModelMeshLoader(options?)`
|
|
164
|
+
|
|
165
|
+
Loads STEP, WRL, STL, OBJ, GLTF, and GLB external models into assembly meshes.
|
|
166
|
+
By default the loader only reads embedded payloads, session files, and provided
|
|
167
|
+
byte buffers. Network loading is opt-in through either an injected `fetch`
|
|
168
|
+
function or `allowNetworkModelFetch: true`. Remote `.gltf` buffer sidecars are
|
|
169
|
+
resolved relative to the `.gltf` URL and use the same fetch, auth-header,
|
|
170
|
+
timeout, and cache policy as the top-level model.
|
|
171
|
+
|
|
172
|
+
Options:
|
|
173
|
+
|
|
174
|
+
- `stepLoader`: custom STEP loader.
|
|
175
|
+
- `fetch`: host-provided fetch function for resolved model URLs.
|
|
176
|
+
- `allowNetworkModelFetch`: use `globalThis.fetch` for `resolvedUrl` or
|
|
177
|
+
`sourceUrl` models when no local payload is present.
|
|
178
|
+
- `authHeaders`: headers forwarded to network model requests.
|
|
179
|
+
- `fetchTimeoutMs`: abort timeout for network model requests.
|
|
180
|
+
- `modelCache`: optional cache map keyed by resolved model URL.
|
|
181
|
+
|
|
124
182
|
## Model Archive Export
|
|
125
183
|
|
|
126
184
|
### `PcbModelArchiveExporter.buildArchive(options?)`
|
package/docs/circuitjson.md
CHANGED
|
@@ -109,6 +109,39 @@ if (PcbScene3dCircuitJsonAdapter.isCircuitJsonModel(circuitJson)) {
|
|
|
109
109
|
}
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
+
Hosts that need URL policy control can pass a synchronous `modelUrlResolver`.
|
|
113
|
+
The adapter records the returned metadata on each external model but does not
|
|
114
|
+
fetch the referenced file:
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
const sceneDescription = PcbScene3dCircuitJsonAdapter.build(circuitJson, {
|
|
118
|
+
modelUrlResolver(url, context) {
|
|
119
|
+
return {
|
|
120
|
+
resolvedUrl: sameOriginProxyUrl(url),
|
|
121
|
+
sameOrigin: context.format === 'step'
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Hosts can also pass `projectBaseUrl` to resolve relative model URLs without a
|
|
128
|
+
custom resolver. Package-style `node_modules/...` paths resolve to the
|
|
129
|
+
project-origin `/package_files/download` endpoint with package and file-path
|
|
130
|
+
query parameters. Package download file paths are normalized under `dist/` when
|
|
131
|
+
the source path does not already include it. Model fetching remains a separate
|
|
132
|
+
host/export decision.
|
|
133
|
+
`boardDrillQuality` accepts `low`, `medium`, or `high` and controls generated
|
|
134
|
+
circle sampling for direct CircuitJSON drill/cutout geometry. When a
|
|
135
|
+
CircuitJSON file has components but no board or panel, `drawFauxBoard: true`
|
|
136
|
+
generates a board from component bounds with a 2 mm margin per side.
|
|
137
|
+
Set `showPcbNotes: true` to render `pcb_note_text`,
|
|
138
|
+
`pcb_fabrication_note_text`, note/fabrication path artwork, and courtyard
|
|
139
|
+
artwork as silkscreen detail. Notes are hidden by default so manufacturing
|
|
140
|
+
annotations do not unexpectedly appear in board previews.
|
|
141
|
+
Set `showPcbPaste: true` to render `pcb_solder_paste` as a grey top/bottom
|
|
142
|
+
surface overlay. Paste is hidden by default so stencil-only manufacturing data
|
|
143
|
+
does not clutter normal board previews.
|
|
144
|
+
|
|
112
145
|
`isDirectCircuitJsonModel(value)` returns `false` for compatibility arrays that
|
|
113
146
|
also carry legacy parser fields such as `pcb`, `schematic`, or `bom`. Those
|
|
114
147
|
arrays continue through the host-provided `buildScene` callback so existing
|
|
@@ -120,14 +153,30 @@ CircuitJSON input uses millimeters. The adapter converts all board, component,
|
|
|
120
153
|
pad, via, trace, and silkscreen dimensions into mils before handing the scene to
|
|
121
154
|
the Three.js runtime.
|
|
122
155
|
|
|
123
|
-
The board center defaults to `{ x: 0, y: 0 }` when omitted. If no `
|
|
124
|
-
element is present, the adapter creates a 25.4 mm by 25.4 mm
|
|
125
|
-
1.6 mm thickness so incomplete test or preview models still
|
|
156
|
+
The board center defaults to `{ x: 0, y: 0 }` when omitted. If no `pcb_panel`
|
|
157
|
+
or `pcb_board` element is present, the adapter creates a 25.4 mm by 25.4 mm
|
|
158
|
+
board with a 1.6 mm thickness so incomplete test or preview models still
|
|
159
|
+
render. With `drawFauxBoard: true`, that fallback board is instead sized around
|
|
160
|
+
the PCB component bounds with a minimum 10 mm by 10 mm footprint.
|
|
161
|
+
|
|
162
|
+
`cad_component` records with `show_as_bounding_box: true` are exported as
|
|
163
|
+
procedural component bodies. If `size` or `model_size` is present, those
|
|
164
|
+
dimensions drive the generated body; otherwise the paired `pcb_component`
|
|
165
|
+
footprint dimensions are used.
|
|
166
|
+
|
|
167
|
+
When a `cad_component` has no explicit model URL, package footprint metadata
|
|
168
|
+
from `footprinter_string`, `footprint_string`, `footprint`, or `package` can
|
|
169
|
+
generate a richer fallback body. Common dual-row, quad-row, SOT-style,
|
|
170
|
+
through-hole pin-header, passive-chip, pushbutton, testpoint, and TO-style
|
|
171
|
+
package strings add simple lead, pin, or terminal geometry while keeping the
|
|
172
|
+
plain box fallback for unrecognized package text.
|
|
126
173
|
|
|
127
174
|
Layer values resolve as follows:
|
|
128
175
|
|
|
129
|
-
- `1`, `top`, `front`,
|
|
130
|
-
|
|
176
|
+
- `1`, `top`, `front`, `f.cu`, and top-side artwork layer names map to the
|
|
177
|
+
top side.
|
|
178
|
+
- `32`, `bottom`, `back`, `b.cu`, and bottom-side artwork layer names map to
|
|
179
|
+
the bottom side.
|
|
131
180
|
- Unknown layer values default to the top side.
|
|
132
181
|
|
|
133
182
|
## Supported Elements
|
|
@@ -135,18 +184,44 @@ Layer values resolve as follows:
|
|
|
135
184
|
The adapter focuses on renderer-ready PCB geometry and ignores unsupported
|
|
136
185
|
CircuitJSON elements instead of failing the whole scene.
|
|
137
186
|
|
|
138
|
-
| Element type
|
|
139
|
-
|
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
149
|
-
| `
|
|
187
|
+
| Element type | Rendered as |
|
|
188
|
+
| --------------------------- | ------------------------------------------------------------------- |
|
|
189
|
+
| `pcb_panel` | Preferred board/panel size, thickness, center, and optional outline |
|
|
190
|
+
| `pcb_board` | Board size, thickness, center, and optional outline |
|
|
191
|
+
| `pcb_cutout` | Through-board cutout loop |
|
|
192
|
+
| `source_component` | Component designator and package metadata |
|
|
193
|
+
| `pcb_component` | Fallback component body and selection target |
|
|
194
|
+
| `cad_component` | External model URL metadata and placement data |
|
|
195
|
+
| `pcb_smtpad` | Top or bottom SMT pad copper, including pill pads |
|
|
196
|
+
| `pcb_plated_hole` | Through-hole pad copper and drill |
|
|
197
|
+
| `pcb_hole` | Non-plated drill opening |
|
|
198
|
+
| `pcb_via` | Via copper and drill |
|
|
199
|
+
| `pcb_trace` | Routed copper track segments and route-derived surface vias |
|
|
200
|
+
| `pcb_copper_pour` | Top or bottom copper zone polygon |
|
|
201
|
+
| `pcb_solder_paste` | Optional top or bottom paste fill when `showPcbPaste` is enabled |
|
|
202
|
+
| `pcb_silkscreen_line` | Top or bottom silkscreen stroke |
|
|
203
|
+
| `pcb_silkscreen_path` | Top or bottom routed silkscreen strokes |
|
|
204
|
+
| `pcb_silkscreen_circle` | Top or bottom full-circle silkscreen stroke |
|
|
205
|
+
| `pcb_silkscreen_rect` | Top or bottom rectangular silkscreen outline |
|
|
206
|
+
| `pcb_silkscreen_oval` | Top or bottom oval silkscreen outline |
|
|
207
|
+
| `pcb_silkscreen_pill` | Top or bottom pill silkscreen outline |
|
|
208
|
+
| `pcb_silkscreen_text` | Top or bottom silkscreen text placeholder |
|
|
209
|
+
| `pcb_note_text` | Optional top or bottom note text when `showPcbNotes` is enabled |
|
|
210
|
+
| `pcb_note_line` | Optional top or bottom note stroke when `showPcbNotes` is enabled |
|
|
211
|
+
| `pcb_note_path` | Optional top or bottom note path when `showPcbNotes` is enabled |
|
|
212
|
+
| `pcb_note_rect` | Optional top or bottom note outline when `showPcbNotes` is enabled |
|
|
213
|
+
| `pcb_fabrication_note_text` | Optional fabrication text when `showPcbNotes` is enabled |
|
|
214
|
+
| `pcb_fabrication_note_path` | Optional fabrication path when `showPcbNotes` is enabled |
|
|
215
|
+
| `pcb_courtyard_rect` | Optional courtyard rectangle when `showPcbNotes` is enabled |
|
|
216
|
+
| `pcb_courtyard_circle` | Optional courtyard circle when `showPcbNotes` is enabled |
|
|
217
|
+
| `pcb_courtyard_outline` | Optional courtyard outline when `showPcbNotes` is enabled |
|
|
218
|
+
|
|
219
|
+
`cad_component` entries can provide external model URLs and model-local
|
|
220
|
+
placement hints. The adapter maps `model_unit_to_mm_scale_factor`,
|
|
221
|
+
`model_origin_position`, `model_offset`, `model_origin_alignment`,
|
|
222
|
+
`model_object_fit`, `model_board_normal_direction`, and `size` into normalized
|
|
223
|
+
model transforms, and maps `show_as_translucent_model` into export/display
|
|
224
|
+
opacity metadata.
|
|
150
225
|
|
|
151
226
|
Board outlines can be supplied as `pcb_board.outline`, using an array of points:
|
|
152
227
|
|
|
@@ -162,8 +237,91 @@ Board outlines can be supplied as `pcb_board.outline`, using an array of points:
|
|
|
162
237
|
}
|
|
163
238
|
```
|
|
164
239
|
|
|
165
|
-
|
|
166
|
-
|
|
240
|
+
Through-board cutouts can be supplied as polygon, rectangle, or circle
|
|
241
|
+
`pcb_cutout` elements. A `pcb_cutout` with `pcb_board_id` only applies when that
|
|
242
|
+
board is selected, while cutouts without a board target are global. Rectangular
|
|
243
|
+
cutouts support `ccw_rotation`:
|
|
244
|
+
|
|
245
|
+
```js
|
|
246
|
+
{
|
|
247
|
+
type: 'pcb_cutout',
|
|
248
|
+
shape: 'rect',
|
|
249
|
+
center: { x: 25, y: 15 },
|
|
250
|
+
width: 4,
|
|
251
|
+
height: 2,
|
|
252
|
+
ccw_rotation: 45
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Drills can use circular, pill, or rotated pill geometry. `hole_offset_x` and
|
|
257
|
+
`hole_offset_y` move the drill center independently of the pad/copper center:
|
|
258
|
+
|
|
259
|
+
```js
|
|
260
|
+
{
|
|
261
|
+
type: 'pcb_plated_hole',
|
|
262
|
+
x: 10,
|
|
263
|
+
y: 8,
|
|
264
|
+
hole_shape: 'rotated_pill',
|
|
265
|
+
hole_width: 0.5,
|
|
266
|
+
hole_height: 1.5,
|
|
267
|
+
hole_offset_x: 0.1,
|
|
268
|
+
hole_offset_y: -0.1,
|
|
269
|
+
outer_diameter: 2
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
SMT pads can use circular, rectangular, rotated rectangular, or pill geometry.
|
|
274
|
+
Pill pads are normalized as rounded rectangles so their copper keeps the
|
|
275
|
+
expected capsule outline:
|
|
276
|
+
|
|
277
|
+
```js
|
|
278
|
+
{
|
|
279
|
+
type: 'pcb_smtpad',
|
|
280
|
+
layer: 'top',
|
|
281
|
+
shape: 'rotated_pill',
|
|
282
|
+
x: 12,
|
|
283
|
+
y: 8,
|
|
284
|
+
width: 2,
|
|
285
|
+
height: 1,
|
|
286
|
+
ccw_rotation: 30
|
|
287
|
+
}
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
SMT pads, plated holes, and vias honor `is_covered_with_solder_mask` and
|
|
291
|
+
`covered_with_solder_mask` when present. `true` keeps the copper under solder
|
|
292
|
+
mask, while `false` exposes the copper on the applicable board side. For vias,
|
|
293
|
+
covered values map to tenting metadata on both sides.
|
|
294
|
+
|
|
295
|
+
Copper pours can use rectangular, polygon, or B-Rep geometry. Rectangular pours
|
|
296
|
+
support `rotation` or `ccw_rotation`; polygon and B-Rep point coordinates are
|
|
297
|
+
converted from millimeters to mils. `covered_with_solder_mask: true` renders the
|
|
298
|
+
zone under solder mask, while false or omitted values expose the copper:
|
|
299
|
+
|
|
300
|
+
```js
|
|
301
|
+
{
|
|
302
|
+
type: 'pcb_copper_pour',
|
|
303
|
+
layer: 'top',
|
|
304
|
+
shape: 'rect',
|
|
305
|
+
center: { x: 25, y: 15 },
|
|
306
|
+
width: 8,
|
|
307
|
+
height: 5,
|
|
308
|
+
rotation: 45,
|
|
309
|
+
covered_with_solder_mask: false
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Silkscreen text uses `anchor_position` when available, falling back to `x` and
|
|
314
|
+
`y`. Common `anchor_alignment` values such as `center`, `bottom_left`, or
|
|
315
|
+
`top_right` are normalized into horizontal and vertical alignment metadata for
|
|
316
|
+
stroke text rendering.
|
|
317
|
+
|
|
318
|
+
Component model metadata can be supplied on `cad_component` elements with
|
|
319
|
+
`model_3mf_url`, `model_step_url`, `model_wrl_url`, `model_glb_url`,
|
|
320
|
+
`model_gltf_url`, `model_stl_url`, or `model_obj_url`. The adapter emits
|
|
321
|
+
external placement metadata for the host runtime or export pipeline to resolve.
|
|
322
|
+
|
|
323
|
+
Traces can be supplied as a `route` array. Each adjacent wire point pair becomes
|
|
324
|
+
one track segment:
|
|
167
325
|
|
|
168
326
|
```js
|
|
169
327
|
{
|
|
@@ -178,6 +336,31 @@ track segment:
|
|
|
178
336
|
}
|
|
179
337
|
```
|
|
180
338
|
|
|
339
|
+
Route entries with `route_type: 'via'` produce via primitives when their
|
|
340
|
+
`from_layer`, `to_layer`, or `layer` touches the top or bottom surface. Adjacent
|
|
341
|
+
surface wire segments remain visible through those vias. Inner-only vias and
|
|
342
|
+
inner-only wire segments are ignored by the surface-copper view. If a route via
|
|
343
|
+
omits `hole_diameter`, `via_hole_diameter`, or `drill_diameter`, the drill
|
|
344
|
+
diameter defaults to half of `via_diameter`.
|
|
345
|
+
|
|
346
|
+
```js
|
|
347
|
+
{
|
|
348
|
+
type: 'pcb_trace',
|
|
349
|
+
route: [
|
|
350
|
+
{ route_type: 'wire', x: 5, y: 5, width: 0.2, layer: 'top' },
|
|
351
|
+
{
|
|
352
|
+
route_type: 'via',
|
|
353
|
+
x: 8,
|
|
354
|
+
y: 5,
|
|
355
|
+
from_layer: 'top',
|
|
356
|
+
to_layer: 'bottom',
|
|
357
|
+
via_diameter: 0.4
|
|
358
|
+
},
|
|
359
|
+
{ route_type: 'wire', x: 8, y: 10, width: 0.2, layer: '32' }
|
|
360
|
+
]
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
181
364
|
## Diagnostics
|
|
182
365
|
|
|
183
366
|
Malformed CircuitJSON input is rejected by `circuitjson-toolkit` before render
|
|
@@ -185,6 +368,7 @@ model conversion. Use `PcbScene3dCircuitJsonAdapter.isCircuitJsonModel(value)`
|
|
|
185
368
|
for a cheap guard when accepting untrusted JSON from users, and catch conversion
|
|
186
369
|
errors around `build(value)` when you need to show a custom diagnostic.
|
|
187
370
|
|
|
188
|
-
The viewer does not fetch external assets for CircuitJSON input
|
|
189
|
-
|
|
190
|
-
applications that create
|
|
371
|
+
The viewer does not fetch external assets for CircuitJSON input by itself.
|
|
372
|
+
Model URL matching, same-origin checks, proxying, and file loading remain the
|
|
373
|
+
responsibility of source-specific toolkits or host applications that create or
|
|
374
|
+
post-process normalized scene descriptions.
|
package/docs/model-format.md
CHANGED
|
@@ -35,6 +35,10 @@ toolkits are responsible for creating this data.
|
|
|
35
35
|
silkscreen: {
|
|
36
36
|
top: {},
|
|
37
37
|
bottom: {}
|
|
38
|
+
},
|
|
39
|
+
paste: {
|
|
40
|
+
top: {},
|
|
41
|
+
bottom: {}
|
|
38
42
|
}
|
|
39
43
|
}
|
|
40
44
|
}
|
|
@@ -66,7 +70,7 @@ Components describe fallback package bodies and selection metadata:
|
|
|
66
70
|
|
|
67
71
|
## External Placements
|
|
68
72
|
|
|
69
|
-
External placements describe STEP or
|
|
73
|
+
External placements describe STEP, WRL, GLB, GLTF, STL, or OBJ model instances:
|
|
70
74
|
|
|
71
75
|
```js
|
|
72
76
|
{
|
|
@@ -78,18 +82,63 @@ External placements describe STEP or WRL model instances:
|
|
|
78
82
|
bodyRotationDeg: 0,
|
|
79
83
|
modelTransform: {
|
|
80
84
|
rotationDeg: { x: 90, y: 0, z: 0 },
|
|
81
|
-
|
|
85
|
+
offsetMil: { x: 0, y: 0, z: 0 },
|
|
86
|
+
scale: { x: 1, y: 1, z: 1 },
|
|
87
|
+
originPositionMil: { x: 0, y: 0, z: 0 },
|
|
88
|
+
originAlignment: 'center_of_component_on_board_surface',
|
|
89
|
+
objectFit: 'fill_bounds',
|
|
90
|
+
boardNormalDirection: 'z+',
|
|
91
|
+
targetSizeMil: { x: 200, y: 300, z: 60 }
|
|
82
92
|
},
|
|
93
|
+
bodyOpacity: 0.5,
|
|
83
94
|
externalModel: {
|
|
84
95
|
origin: 'session',
|
|
85
96
|
name: 'soic-8.step',
|
|
86
97
|
relativePath: 'packages/soic-8.step',
|
|
87
98
|
format: 'step',
|
|
99
|
+
sourceUrl: '/models/soic-8.step',
|
|
100
|
+
resolvedUrl: 'https://assets.example.invalid/models/soic-8.step',
|
|
88
101
|
file: File
|
|
89
102
|
}
|
|
90
103
|
}
|
|
91
104
|
```
|
|
92
105
|
|
|
106
|
+
OBJ models can carry sidecar material libraries in `resources`, `relatedFiles`,
|
|
107
|
+
`assets`, or similar metadata collections. OBJ diffuse, ambient, specular,
|
|
108
|
+
shininess, alpha, and vertex colors are preserved in the parsed mesh metadata.
|
|
109
|
+
GLTF/GLB material alpha, mesh opacity, and `COLOR_0` vertex colors are
|
|
110
|
+
preserved in imported and exported GLTF/GLB materials and primitives.
|
|
111
|
+
GLTF/GLB import consumes triangle primitives and ignores unsupported primitive
|
|
112
|
+
modes such as points or lines. Remote `.gltf` files can reference external
|
|
113
|
+
`buffers[].uri` sidecars; when URL-backed model loading is enabled, the loader
|
|
114
|
+
resolves those sidecars relative to the `.gltf` URL and fetches them with the
|
|
115
|
+
same cache, timeout, and auth-header policy.
|
|
116
|
+
|
|
117
|
+
Resolved model URLs are not fetched by default. Hosts that want URL-backed model
|
|
118
|
+
loading must provide an explicit fetch policy through `PcbAssemblyModelMeshLoader`
|
|
119
|
+
or a higher-level export service. Use `authHeaders`, `fetchTimeoutMs`, and a
|
|
120
|
+
caller-owned `modelCache` when remote model requests are enabled.
|
|
121
|
+
|
|
122
|
+
When `projectBaseUrl` is provided to the CircuitJSON adapter, package-style
|
|
123
|
+
model paths such as `node_modules/package-name/path/to/model.step` are resolved
|
|
124
|
+
to `/package_files/download` on the project origin with
|
|
125
|
+
`package_name_with_version` and `file_path` query parameters. Package download
|
|
126
|
+
file paths are normalized under `dist/` unless they already start there. This
|
|
127
|
+
only records a resolved URL; fetching still requires an explicit loader/export
|
|
128
|
+
fetch policy.
|
|
129
|
+
|
|
130
|
+
CAD placements can request procedural bounding-box output with
|
|
131
|
+
`show_as_bounding_box: true`. The adapter marks those placements with
|
|
132
|
+
`renderAsBoundingBox: true`, copies `size`/`model_size` into fallback body
|
|
133
|
+
dimensions when present, and the assembly geometry builder skips external model
|
|
134
|
+
loading for that placement.
|
|
135
|
+
|
|
136
|
+
When package footprint text is available, fallback bodies can derive simple
|
|
137
|
+
package-specific geometry for passive chips, dual-row and quad-row ICs,
|
|
138
|
+
SOT-style packages, pin headers, pushbuttons, testpoints, and TO-style
|
|
139
|
+
through-hole packages. Testpoints and radial capacitors use round fallback
|
|
140
|
+
bodies in both runtime rendering and assembly export.
|
|
141
|
+
|
|
93
142
|
Embedded STEP models can use:
|
|
94
143
|
|
|
95
144
|
```js
|
|
@@ -107,11 +156,24 @@ The runtime expects pre-normalized primitive lists for:
|
|
|
107
156
|
|
|
108
157
|
- pads and vias with drill and copper dimensions;
|
|
109
158
|
- tracks and arcs with layer metadata;
|
|
110
|
-
- fills and polygons with point loops;
|
|
159
|
+
- fills and polygons with point loops or B-Rep ring metadata;
|
|
111
160
|
- silkscreen tracks, arcs, fills, and texts;
|
|
161
|
+
- optional solder-paste fills in `detail.paste`;
|
|
112
162
|
- copper text primitives.
|
|
113
163
|
|
|
114
164
|
The viewer does not infer source-file semantics. When a scene needs
|
|
115
165
|
format-specific layer mapping, solder-mask interpretation, text layout, or
|
|
116
166
|
model matching, the source toolkit should encode those decisions in the scene
|
|
117
167
|
description.
|
|
168
|
+
|
|
169
|
+
Through-hole pads can describe offset or slotted drills with `holeOffsetX`,
|
|
170
|
+
`holeOffsetY`, `holeSlotLength`, and `holeRotation`. Board substrate export uses
|
|
171
|
+
`detail.drillQuality` values of `low`, `medium`, or `high` to choose circular
|
|
172
|
+
drill sampling density.
|
|
173
|
+
|
|
174
|
+
Rounded SMT pads set `hasRoundedRect`, the side-specific
|
|
175
|
+
`roundedRectShapeTop`/`roundedRectShapeBottom`, and
|
|
176
|
+
`cornerRadiusTop`/`cornerRadiusBottom` as a percent of the shortest copper side.
|
|
177
|
+
Route-derived vias use the same `detail.vias` shape as standalone vias, and
|
|
178
|
+
surface route segments use `layerId: 1` for top copper or `layerId: 32` for
|
|
179
|
+
bottom copper.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pcb-scene3d-viewer",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.44",
|
|
4
4
|
"description": "Reusable Three.js PCB 3D scene viewer for normalized ECAD and CircuitJSON scene descriptions",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pcb",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@sunbox/occt-import-js": "^0.0.25",
|
|
55
|
-
"circuitjson-toolkit": "^1.0.
|
|
55
|
+
"circuitjson-toolkit": "^1.0.10",
|
|
56
56
|
"earcut": "^3.0.2",
|
|
57
57
|
"fflate": "^0.8.2",
|
|
58
58
|
"three": "^0.183.2"
|
package/spec/library-scope.md
CHANGED
|
@@ -8,12 +8,12 @@ scene descriptions.
|
|
|
8
8
|
- Three.js runtime orchestration for PCB scenes.
|
|
9
9
|
- Board, copper, via, drill, silkscreen, solder-mask, and fallback package mesh
|
|
10
10
|
factories.
|
|
11
|
-
- STEP and
|
|
11
|
+
- STEP, WRL, GLB, GLTF, STL, and OBJ model loading and placement.
|
|
12
12
|
- Camera presets, view compensation, selection styling, picking, and visibility
|
|
13
13
|
toggles.
|
|
14
14
|
- Optional DOM shell/controller helpers for hosts that want ready-made scene
|
|
15
15
|
chrome.
|
|
16
|
-
- ZIP export of resolved
|
|
16
|
+
- ZIP export of resolved component model assets.
|
|
17
17
|
- CSS for the optional scene shell.
|
|
18
18
|
|
|
19
19
|
## Out of Scope
|