pcb-scene3d-viewer 1.1.21 → 1.1.31
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 +3 -2
- package/docs/api.md +27 -1
- package/docs/circuitjson.md +63 -18
- package/docs/model-format.md +13 -2
- package/package.json +1 -1
- package/spec/library-scope.md +2 -2
- package/src/PcbAssemblyBoardSubstrateBuilder.mjs +25 -5
- package/src/PcbAssemblyComponentMeshBuilder.mjs +762 -0
- package/src/PcbAssemblyFillGeometryResolver.mjs +579 -0
- package/src/PcbAssemblyFillRingNormalizer.mjs +209 -0
- package/src/PcbAssemblyGeometryBuilder.mjs +41 -301
- package/src/PcbAssemblyGltfModelMeshParser.mjs +912 -0
- package/src/PcbAssemblyGltfValidator.mjs +460 -0
- package/src/PcbAssemblyGltfWriter.mjs +801 -0
- package/src/PcbAssemblyMeshUtils.mjs +117 -0
- package/src/PcbAssemblyModelMeshLoader.mjs +18 -0
- package/src/PcbAssemblyPadMeshBuilder.mjs +394 -0
- package/src/PcbAssemblyStepWriter.mjs +24 -2
- package/src/PcbAssemblyTextModelMeshParser.mjs +602 -0
- package/src/PcbModelArchiveExporter.mjs +521 -7
- package/src/PcbScene3dCircuitJsonAdapter.mjs +409 -7
- package/src/PcbScene3dCircuitJsonModelTransform.mjs +232 -0
- package/src/PcbScene3dCompanionBasePlacementAdjuster.mjs +242 -0
- package/src/PcbScene3dComponentVisibility.mjs +100 -5
- 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/PcbScene3dExternalCompanionFallback.mjs +202 -0
- 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 +16 -7
- package/src/PcbScene3dFallbackBodyFactory.mjs +105 -0
- package/src/PcbScene3dFallbackVisibility.mjs +58 -1
- package/src/PcbScene3dMaskCoveredCopperSideGroupBuilder.mjs +68 -0
- package/src/PcbScene3dPadFactory.mjs +35 -2
- package/src/PcbScene3dRenderGroupVisibility.mjs +8 -1
- package/src/PcbScene3dRuntime.mjs +94 -100
- package/src/PcbScene3dRuntimeHelpers.mjs +39 -0
- package/src/PcbScene3dSelectionIndexBuilder.mjs +87 -0
- package/src/PcbScene3dSelectionInspectorRenderer.mjs +50 -11
- package/src/PcbScene3dSelectionMarkerFactory.mjs +333 -0
- package/src/PcbScene3dSelectionMarkerOverlay.mjs +70 -0
- package/src/PcbScene3dSelectionStyler.mjs +52 -2
- package/src/PcbScene3dStaticBodyFactory.mjs +263 -0
- package/src/PcbScene3dText.mjs +1 -0
- package/src/PcbScene3dTransparentMeshSplitter.mjs +623 -0
- package/src/PcbScene3dViaFactory.mjs +27 -7
- package/src/scene3d.mjs +3 -0
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,9 @@ 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.
|
|
67
69
|
|
|
68
70
|
`PcbScene3dController` and `PcbScene3dRuntime` call this adapter automatically
|
|
69
71
|
when they receive direct CircuitJSON input. See
|
|
@@ -121,6 +123,30 @@ worker.postMessage({
|
|
|
121
123
|
Workers respond with `scene3d:success` and `sceneDescription`, or
|
|
122
124
|
`scene3d:error` and `message`.
|
|
123
125
|
|
|
126
|
+
## Assembly Geometry Export
|
|
127
|
+
|
|
128
|
+
### `PcbAssemblyGeometryBuilder.build(sceneDescription, options?)`
|
|
129
|
+
|
|
130
|
+
Builds export meshes from a prepared scene description. `options.modelMeshLoader`
|
|
131
|
+
can provide external model meshes, `options.includeModels: false` skips external
|
|
132
|
+
model loading, and `options.renderFallbackBodies: false` disables procedural
|
|
133
|
+
component bodies for unresolved models.
|
|
134
|
+
|
|
135
|
+
### `PcbAssemblyGltfWriter.write(options?)`
|
|
136
|
+
|
|
137
|
+
Writes faceted assembly meshes as GLTF 2.0 JSON or binary GLB.
|
|
138
|
+
|
|
139
|
+
Options:
|
|
140
|
+
|
|
141
|
+
- `name`: scene name.
|
|
142
|
+
- `meshes`: export meshes with `vertices`, `faces`, optional RGB or RGBA
|
|
143
|
+
`color`, optional `opacity`, and optional board `texture` data URIs.
|
|
144
|
+
- `format`: `gltf` or `glb`.
|
|
145
|
+
- `binary`: optional boolean equivalent to `format: 'glb'`.
|
|
146
|
+
|
|
147
|
+
Returns a GLTF JSON object for `gltf` and a `Uint8Array` for `glb`. RGBA colors
|
|
148
|
+
or opacity values below `1` are emitted as blended GLTF materials.
|
|
149
|
+
|
|
124
150
|
## Model Archive Export
|
|
125
151
|
|
|
126
152
|
### `PcbModelArchiveExporter.buildArchive(options?)`
|
package/docs/circuitjson.md
CHANGED
|
@@ -109,6 +109,21 @@ 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
|
+
|
|
112
127
|
`isDirectCircuitJsonModel(value)` returns `false` for compatibility arrays that
|
|
113
128
|
also carry legacy parser fields such as `pcb`, `schematic`, or `bom`. Those
|
|
114
129
|
arrays continue through the host-provided `buildScene` callback so existing
|
|
@@ -120,9 +135,10 @@ CircuitJSON input uses millimeters. The adapter converts all board, component,
|
|
|
120
135
|
pad, via, trace, and silkscreen dimensions into mils before handing the scene to
|
|
121
136
|
the Three.js runtime.
|
|
122
137
|
|
|
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
|
|
138
|
+
The board center defaults to `{ x: 0, y: 0 }` when omitted. If no `pcb_panel`
|
|
139
|
+
or `pcb_board` element is present, the adapter creates a 25.4 mm by 25.4 mm
|
|
140
|
+
board with a 1.6 mm thickness so incomplete test or preview models still
|
|
141
|
+
render.
|
|
126
142
|
|
|
127
143
|
Layer values resolve as follows:
|
|
128
144
|
|
|
@@ -135,18 +151,28 @@ Layer values resolve as follows:
|
|
|
135
151
|
The adapter focuses on renderer-ready PCB geometry and ignores unsupported
|
|
136
152
|
CircuitJSON elements instead of failing the whole scene.
|
|
137
153
|
|
|
138
|
-
| Element type | Rendered as
|
|
139
|
-
| --------------------- |
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
149
|
-
| `
|
|
154
|
+
| Element type | Rendered as |
|
|
155
|
+
| --------------------- | ------------------------------------------------------------------- |
|
|
156
|
+
| `pcb_panel` | Preferred board/panel size, thickness, center, and optional outline |
|
|
157
|
+
| `pcb_board` | Board size, thickness, center, and optional outline |
|
|
158
|
+
| `pcb_cutout` | Through-board cutout loop |
|
|
159
|
+
| `source_component` | Component designator and package metadata |
|
|
160
|
+
| `pcb_component` | Fallback component body and selection target |
|
|
161
|
+
| `cad_component` | External model URL metadata and placement data |
|
|
162
|
+
| `pcb_smtpad` | Top or bottom SMT pad copper |
|
|
163
|
+
| `pcb_plated_hole` | Through-hole pad copper and drill |
|
|
164
|
+
| `pcb_hole` | Non-plated drill opening |
|
|
165
|
+
| `pcb_via` | Via copper and drill |
|
|
166
|
+
| `pcb_trace` | Routed copper track segments |
|
|
167
|
+
| `pcb_silkscreen_line` | Top or bottom silkscreen stroke |
|
|
168
|
+
| `pcb_silkscreen_text` | Top or bottom silkscreen text placeholder |
|
|
169
|
+
|
|
170
|
+
`cad_component` entries can provide external model URLs and model-local
|
|
171
|
+
placement hints. The adapter maps `model_unit_to_mm_scale_factor`,
|
|
172
|
+
`model_origin_position`, `model_offset`, `model_origin_alignment`,
|
|
173
|
+
`model_object_fit`, `model_board_normal_direction`, and `size` into normalized
|
|
174
|
+
model transforms, and maps `show_as_translucent_model` into export/display
|
|
175
|
+
opacity metadata.
|
|
150
176
|
|
|
151
177
|
Board outlines can be supplied as `pcb_board.outline`, using an array of points:
|
|
152
178
|
|
|
@@ -162,6 +188,24 @@ Board outlines can be supplied as `pcb_board.outline`, using an array of points:
|
|
|
162
188
|
}
|
|
163
189
|
```
|
|
164
190
|
|
|
191
|
+
Through-board cutouts can be supplied as polygon, rectangle, or circle
|
|
192
|
+
`pcb_cutout` elements:
|
|
193
|
+
|
|
194
|
+
```js
|
|
195
|
+
{
|
|
196
|
+
type: 'pcb_cutout',
|
|
197
|
+
shape: 'rect',
|
|
198
|
+
center: { x: 25, y: 15 },
|
|
199
|
+
width: 4,
|
|
200
|
+
height: 2
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Component model metadata can be supplied on `cad_component` elements with
|
|
205
|
+
`model_step_url`, `model_wrl_url`, `model_glb_url`, `model_gltf_url`,
|
|
206
|
+
`model_stl_url`, or `model_obj_url`. The adapter emits external placement
|
|
207
|
+
metadata for the host runtime or export pipeline to resolve.
|
|
208
|
+
|
|
165
209
|
Traces can be supplied as a `route` array. Each adjacent point pair becomes one
|
|
166
210
|
track segment:
|
|
167
211
|
|
|
@@ -185,6 +229,7 @@ model conversion. Use `PcbScene3dCircuitJsonAdapter.isCircuitJsonModel(value)`
|
|
|
185
229
|
for a cheap guard when accepting untrusted JSON from users, and catch conversion
|
|
186
230
|
errors around `build(value)` when you need to show a custom diagnostic.
|
|
187
231
|
|
|
188
|
-
The viewer does not fetch external assets for CircuitJSON input
|
|
189
|
-
|
|
190
|
-
applications that create
|
|
232
|
+
The viewer does not fetch external assets for CircuitJSON input by itself.
|
|
233
|
+
Model URL matching, same-origin checks, proxying, and file loading remain the
|
|
234
|
+
responsibility of source-specific toolkits or host applications that create or
|
|
235
|
+
post-process normalized scene descriptions.
|
package/docs/model-format.md
CHANGED
|
@@ -66,7 +66,7 @@ Components describe fallback package bodies and selection metadata:
|
|
|
66
66
|
|
|
67
67
|
## External Placements
|
|
68
68
|
|
|
69
|
-
External placements describe STEP or
|
|
69
|
+
External placements describe STEP, WRL, GLB, GLTF, STL, or OBJ model instances:
|
|
70
70
|
|
|
71
71
|
```js
|
|
72
72
|
{
|
|
@@ -78,8 +78,15 @@ External placements describe STEP or WRL model instances:
|
|
|
78
78
|
bodyRotationDeg: 0,
|
|
79
79
|
modelTransform: {
|
|
80
80
|
rotationDeg: { x: 90, y: 0, z: 0 },
|
|
81
|
-
|
|
81
|
+
offsetMil: { x: 0, y: 0, z: 0 },
|
|
82
|
+
scale: { x: 1, y: 1, z: 1 },
|
|
83
|
+
originPositionMil: { x: 0, y: 0, z: 0 },
|
|
84
|
+
originAlignment: 'center_of_component_on_board_surface',
|
|
85
|
+
objectFit: 'fill_bounds',
|
|
86
|
+
boardNormalDirection: 'z+',
|
|
87
|
+
targetSizeMil: { x: 200, y: 300, z: 60 }
|
|
82
88
|
},
|
|
89
|
+
bodyOpacity: 0.5,
|
|
83
90
|
externalModel: {
|
|
84
91
|
origin: 'session',
|
|
85
92
|
name: 'soic-8.step',
|
|
@@ -90,6 +97,10 @@ External placements describe STEP or WRL model instances:
|
|
|
90
97
|
}
|
|
91
98
|
```
|
|
92
99
|
|
|
100
|
+
OBJ models can carry sidecar material libraries in `resources`, `relatedFiles`,
|
|
101
|
+
`assets`, or similar metadata collections. GLTF/GLB material alpha and mesh
|
|
102
|
+
opacity are preserved in exported GLTF/GLB materials.
|
|
103
|
+
|
|
93
104
|
Embedded STEP models can use:
|
|
94
105
|
|
|
95
106
|
```js
|
package/package.json
CHANGED
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
|
|
@@ -145,13 +145,20 @@ export class PcbAssemblyBoardSubstrateBuilder {
|
|
|
145
145
|
* @returns {number[][][]}
|
|
146
146
|
*/
|
|
147
147
|
static #boardHoleLoops(sceneDescription, outer) {
|
|
148
|
-
const
|
|
149
|
-
PcbAssemblyBoardSubstrateBuilder.#
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
148
|
+
const explicitLoops =
|
|
149
|
+
PcbAssemblyBoardSubstrateBuilder.#explicitCutoutLoops(
|
|
150
|
+
sceneDescription
|
|
151
|
+
)
|
|
152
|
+
const primitiveLoops =
|
|
153
|
+
PcbAssemblyBoardSubstrateBuilder.#primitiveHoleLoops(
|
|
154
|
+
sceneDescription
|
|
155
|
+
)
|
|
156
|
+
const fallbackLoops = primitiveLoops.length
|
|
157
|
+
? primitiveLoops
|
|
158
|
+
: PcbAssemblyBoardSubstrateBuilder.#drillCutoutLoops(
|
|
153
159
|
sceneDescription
|
|
154
160
|
)
|
|
161
|
+
const rawLoops = [...explicitLoops, ...fallbackLoops]
|
|
155
162
|
const seen = new Set()
|
|
156
163
|
const holes = []
|
|
157
164
|
|
|
@@ -187,6 +194,19 @@ export class PcbAssemblyBoardSubstrateBuilder {
|
|
|
187
194
|
return holes
|
|
188
195
|
}
|
|
189
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Reads explicit board cutout contours from the scene board metadata.
|
|
199
|
+
* @param {object} sceneDescription Prepared scene description.
|
|
200
|
+
* @returns {Array<Array<object | number[]>>}
|
|
201
|
+
*/
|
|
202
|
+
static #explicitCutoutLoops(sceneDescription) {
|
|
203
|
+
return PcbAssemblyBoardSubstrateBuilder.#array(
|
|
204
|
+
sceneDescription?.board?.cutouts
|
|
205
|
+
)
|
|
206
|
+
.map((cutout) => cutout?.points || cutout?.vertices || cutout)
|
|
207
|
+
.filter((loop) => Array.isArray(loop))
|
|
208
|
+
}
|
|
209
|
+
|
|
190
210
|
/**
|
|
191
211
|
* Reads existing drill cutout contours from scene silkscreen details.
|
|
192
212
|
* @param {object} sceneDescription Prepared scene description.
|