Releases: SunboX/pcb-scene3d-viewer
Release list
v1.3.4
PCB geometry preparation now runs in a dedicated module worker where supported, keeping large boards responsive.
- Transfer generated geometry buffers while retaining source data for model placement and later detail stages.
- Preserve copper around drill clearances and sample curved fill contours correctly.
- Improve repeated component placement, copper occlusion, and shared silkscreen cutout preparation.
Validation: 712 tests passed, 2 skipped; exact-geometry and context-asset benchmarks passed.
Formatting and npm publication dry run passed. The release was also tested against the published CircuitJSON 1.4.3 package.
v1.3.3
pcb-scene3d-viewer 1.3.3
Version 1.3.3 improves external STEP placement when source-authored anchors and
pre-oriented assemblies are present.
STEP placement fidelity
- An explicit
preserveSourceAnchortransform keeps a validated source body
origin fixed without activating component-center recovery. - Embedded STEP assemblies omit a duplicate quarter-turn only when their loaded
mesh envelope proves that the authored depth and height axes are already
exchanged. - Board-space component yaw and the original external-model asset remain
unchanged.
Compatibility
- Detection uses source origin, projection metadata, mesh dimensions, and
bounded error thresholds; it does not inspect filenames, project identities,
component labels, or library names. - Existing scene colors, board geometry, and public APIs remain unchanged.
Verification
- Repository-owned tests cover preserved source anchors and embedded-axis
normalization alongside the existing external-model placement suite. - The complete package suite, formatting check, and npm package dry run are
required for release.
pcb-scene3d-viewer 1.3.2
pcb-scene3d-viewer 1.3.2
Version 1.3.2 adds persistent self-adjusting visibility propagation and fixes
several general copper, via, and solder-mask interactions. The changes derive
from scene topology and authored surface state rather than source filenames or
project-specific rules.
Incremental visibility
PcbScene3dVisibilityGraphapplies render-group visibility and component
visibility as two ordered computations backed by the canonical
SelfAdjustingComputationruntime fromcircuitjson-toolkit1.4.1.- Known toggle paths repair only render-group effects. Selection,
hidden-component, and identity-stable map/set mutations advance an explicit
component revision and repair only component effects. - Unknown topology changes conservatively repair both stages, and runtime
disposal explicitly reclaims retained traces and reverse-reader edges. - The package root and
/scene3dentrypoint export both the canonical runtime
identity and the visibility graph.
Copper and mask correctness
- Tented via faces no longer carry exposed copper geometry through the rendered
solder-mask surface. Fully open vias keep their full span, one-sided tenting
retains only the exposed half, and fully tented vias retain mask treatment
without a visible face-spanning copper annulus. - Filtered tented vias still participate in plated-hole identity checks, so a
matching through-hole pad cannot create a duplicate copper barrel. - Copper-fill clipping with partial subdivision disabled returns as soon as an
uncovered sample proves that a triangle must be kept, while fully sampled
triangles still use exact boundary crossing checks.
Verification
- Tests cover stage-level recomputation, conservative invalidation,
from-scratch visibility consistency, one- and two-sided tenting, duplicate
barrel prevention, and non-subdividing fill overlap behavior. - Release gates include the complete package suite, exact-geometry and context
asset benchmarks, formatting, and npm package dry run.
pcb-scene3d-viewer 1.3.1
pcb-scene3d-viewer 1.3.1
Version 1.3.1 renders source-classified via solder mask as a surface treatment
without replacing the plated copper barrel material.
Via rendering
- Gerber vias with either
isTentingToporisTentingBottomuse the covered
via rendering path; both fields explicitly false retain the exposed path. - Each tented board surface receives its own solder-mask ring above the copper
annulus. Mixed top/bottom tenting is preserved. - The mask ring keeps the authored drill opening clear and leaves the plated
through-hole wall copper-colored. - Blind and buried surface reachability remains authoritative, so mask geometry
is added only where a via actually reaches the corresponding board surface.
Compatibility and verification
- Existing CircuitJSON default-tenting and explicit-opening behavior is
unchanged. - Scene, controller, runtime, export, and package entrypoints are unchanged.
- Tests cover fully tented, mixed, and fully open Gerber classification plus
copper-barrel and one-sided mask-ring material routing.
pcb-scene3d-viewer 1.3.0
pcb-scene3d-viewer 1.3.0
This minor release consumes CircuitJSON Toolkit 1.2 directly and restores exact
PCB surface fidelity without source-format or host-app adapters.
Rendering and API changes
- Oval, rounded-rectangle, pill, polygon, and independently rotated drilled
pads keep their authored copper and drill geometry. - Silkscreen strokes, fills, text dimensions, anchors, mirroring, source-layer
mapping, and surface cutouts render from canonical CircuitJSON fields. - Copper text participates in the same solder-mask and cutout pipeline as other
copper detail. - Blind and buried vias render only on the board surfaces reached by their
explicit layer span. PcbScene3dBoardMaterialPalette.resolveEdgeColor(board)is now public on the
scene3dsubpath. Runtime and exported board edges share its authored-color
lookup and light FR-4 fallback (0xc9ca78).
Models and diagnostics
- Canonical and session CAD assets preserve exact case-sensitive project-path
aliases. Case-insensitive fallback is accepted only when unique, preventing
same-name and same-stem collisions across folders. - Missing-model diagnostics are deferred until resolution has actually failed;
retryable or externally supplied assets are not reported as unavailable
prematurely. - STEP, WRL, GLTF, and text/binary model payload handling avoids redundant
copies and retains the existing opt-in network policy.
Compatibility and performance
- The runtime baseline is
circuitjson-toolkit@^1.2.0; the existing
@sunbox/occt-import-js@^0.0.28WASM package remains compatible and does not
require a coordinated rebuild. - Existing scene descriptions, document envelopes, controller/runtime
parameters, and return shapes remain accepted. The palette method and
CircuitJSON fields above are additive.
v1.2.2
PCB Scene3D Viewer 1.2.2
Version 1.2.2 preserves canonical source identity and aligns solder-mask
coverage with the converged CircuitJSON contract.
API and behavior changes
- Canonical document and prepared-context inputs now retain their exact
source.formatas the rendered scene'ssourceFormat. Dense CircuitJSON
arrays continue to use thecircuitjsonfallback because they carry no
canonical source metadata. - Routed traces and copper pours now default omitted
covered_with_solder_maskvalues to covered. Explicit false values remain
exposed through the solder mask. - Standard vias now honor canonical
is_tentedmetadata. Omitted values
default to tented, whileis_tented: falseremains exposed. - Covered canonical copper follows the existing solder-mask material palette,
including tracks, pours, and via annuli.
Consumers that used the generic circuitjson marker for canonical documents
must now handle the retained source identity such as gerber, altium, or
kicad.
Dependencies and validation
- Requires
circuitjson-toolkit ^1.1.2and Node.js 20 or newer. - The full test suite and both owned performance benchmarks cover the canonical
source, coverage, material, exact-geometry, and prepared-context paths.
pcb-scene3d-viewer 1.2.1
PCB Scene3D Viewer 1.2.1
Version 1.2.1 removes the host-specific OCCT integration layer and consumes the
installed importer package directly.
Compatibility changes
- Requires
@sunbox/occt-import-js ^0.0.28. - STEP workers now load from the scoped package path
/node_modules/@sunbox/occt-import-js/dist/occt-import-js-worker.js. - The no-worker path dynamically imports the package ESM factory and resolves
its WASM through the same package directory. - Classic script injection, global
occtimportjslookup, unscoped package
aliases, and app-vendored importer paths are no longer used. - The package worker stays persistent across imports and failed model or worker
requests remain retryable through the existing cache/reset behavior. - Byte-backed model inputs are copied into loader ownership before worker
transfer, so the caller's typed arrays and buffers are never detached. - Rejected no-worker ESM initialization attempts are evicted, allowing a later
load to recover from transient module or WASM delivery failures.
Hosts serving browser dependencies must expose the installed package dist/
directory byte-for-byte at
/node_modules/@sunbox/occt-import-js/dist/. No copied JavaScript, WASM, or
custom worker is required.
Performance
The viewer consumes the optimized 0.0.28 importer build and continues to retain
typed mesh arrays, compact face-color runs, persistent worker reuse, and parsed
model caching. This avoids script duplication and keeps large STEP payloads off
the main browser thread when workers are available.
pcb-scene3d-viewer 1.2.0
PCB Scene3D Viewer 1.2.0
Version 1.2.0 aligns the viewer boundary with the converged ECAD toolkit APIs.
API changes
PcbScene3dCircuitJsonAdapter.isCircuitJsonModel()andbuild()now accept
ecad-toolkit.document.v1results and prepared
CircuitJsonDocumentContextinstances in addition to CircuitJSON arrays.PcbScene3dCircuitJsonAdapter.prepare()exposes the proof-aware shared
normalization/index boundary. Predicates stay non-mutating and no longer
reject a shared-normalizable legacy row before preparation.PcbScene3dControllerandPcbScene3dRuntimeautomatically route canonical
document envelopes through the direct CircuitJSON path without requiring a
source-format scene builder.- Controller preparation now consistently prefers an explicit
sceneDescription, thenscenePrepClient, then canonical CircuitJSON, and
finally the legacy source builder. Adapter options and session assets survive
asynchronous preparation fallback. PcbScene3dShellRendereraccepts the same legacy, raw CircuitJSON, canonical
document, and prepared-context inputs as the controller, including
component-onlydrawFauxBoardscenes.- Legacy hybrid arrays that carry
pcb,schematic, orbomcompatibility
fields still use the host-provided source-format builder. - Live external model loading now matches every adapter-advertised format:
STEP/STP, WRL/VRML, STL, OBJ, GLTF/GLB, and 3MF. Canonical bytes, session
files, and explicitly enabled model URLs use one consistent runtime policy. - Text-capable loaders accept canonical
text,payloadText, and string
data; raw ZIP export acceptstext,payloadText,data,bytes,
payloadBytes, files, and explicitly enabled URLs. Archive extensions now
preserve every advertised format, including 3MF. modelLoaderOptionsis forwarded fromPcbScene3dControllerto runtime and
archive export. Controller archive names now recognize canonical
source.fileNameon documents and prepared contexts.- Resolved GLTF BIN, OBJ MTL, and WRL texture companions are attached from safe
project-relative session/document assets. WRL textures never trigger an
implicit Three.js network load; local or explicitly fetched bytes are embedded
as data URIs first. - Injected WRL loaders now receive sanitized source with an empty resource base
path. Hosts that previously relied on Three.js resolving relative textures
implicitly must supply local resources or an explicitmodelLoaderOptions
fetch policy. - Static
authHeadersno longer cross the main model origin. The new
authHeadersForUrlcallback is the explicit cross-origin authorization path. - URL fetch scopes enforce safe defaults of 128 MiB per resource, 256 resources,
and 512 MiB aggregate across main sources and sidecars. The limits are
configurable withmaxModelBytes,maxModelResources, and
maxModelTotalBytes. - Raw ZIP entries now use unique pattern directories and original source
basenames. Safe relative GLTF buffers/images, OBJ resources, and WRL textures
are included beside the main source; return rows exposebundleDirectoryand
companionPaths. - Polygon-plated holes now consume the shared CircuitJSON hole primitive model.
pad_outlinedetermines rotation-local copper extents, polygon pads stay
non-circular, and pill drill width/height survive as slot geometry. A 2.6 by
0.6 mm Gerber routed slot no longer collapses to a 1 by 1 mm circular pad. - Slot drill angles are board-space and applied exactly once; diagonal and
vertical routed slots no longer double-rotate with their outer pads. Separate
rectangular-pad and drill rotations remain independent. - Plated-wall classification uses that same board-space drill rotation instead
of adding the outer pad rotation again. Legal rectangular and square holes
retain exact aperture width, height, and rotation through substrate and pad
geometry and assembly export. - Every disjoint CircuitJSON board or panel contour now produces its own board
body, outline, solder-mask faces, and assembly-export substrate mesh. Panel
rows take physical precedence over their child board rows without data loss.
Performance and validation
- Scene adaptation uses
CircuitJsonDocumentContextas the validation boundary
and requests only the sharedelementsindex. - Repeated builds from one prepared context reuse that index instead of
validating and indexing the model again. - Controller routing prepares a canonical document once and passes the context
forward, eliminating duplicate full-model predicate validation. - Descriptor-safe CircuitJSON normalization keeps legacy hidden metadata from
bypassing or breaking the immutable shared model boundary. - CircuitJSON detection predicates validate without freezing or otherwise
mutating caller-owned arrays and unprepared document envelopes. CircuitJsonCadModelAssetResolver.withModelAssetUrls()now preserves common
document envelopes and prepared-context return shapes while deriving explicit
model URL fields from retainedmodel_assetmetadata.- The adapter consumes canonical
model_assetrecords directly and resolves
canonical document assets plus session assets through one descriptor-safe
alias index. Documents without model references skip asset indexing,
prepared contexts cache the canonical index across builds, and payload copies
stay lazy until a matching model is used. Resolver wrappers, hostile session
arrays, option proxies, and metadata accessors cannot execute caller accessors.
ECAD Forge no longer needs an app-side document transform or resolver wrapper. - Canonical accessor-backed
ToolkitAssetsession payloads are materialized
lazily through the shared asset contract before descriptor-safe viewer
copying. Exact STEP and other model bytes now flow from converged project
loaders without weakening hostile-accessor rejection. - Restored route-via, legacy layer, silkscreen/courtyard, oval, copper-pour, and
default-via fixtures now rely on structural normalization in
circuitjson-toolkitinstead of viewer-side compatibility workarounds. - A context-asset benchmark guards the one-index-build repeated-render path.
- Model group, STEP parse, request-cache, and archive identities prefer exact
canonical paths, source streams, and asset IDs. Same-basename files in
different directories remain distinct, identical sources are reused, and
rejected shared requests are evicted for retry. - Asset aliases preserve exact case-sensitive paths. Case-insensitive fallback
resolves only one unique owner and refuses ambiguous case-fold collisions. - Canonical shell BOM counts now use
CircuitJsonBomBuilder, matching toolkit
grouping behavior instead of counting raw source-component rows. - Relative GLTF sidecars resolve beside relative as well as absolute main model
paths. Existing local buffers are reused before any explicitly enabled fetch. - The empty archive diagnostic is format-neutral because export is no longer
limited to STEP and WRL.
Dependencies
- Requires
circuitjson-toolkit ^1.1.0and Node.js 20 or newer. - Pins
earcut3.0.2 so npm deduplication cannot change deterministic triangle
ordering while the CircuitJSON dependency graph is upgraded. - The package version advances from 1.1.50 to 1.2.0 because accepted input
shapes and direct-routing behavior changed incompatibly.
v1.1.50
Release pcb-scene3d-viewer@1.1.50.
Changes:
- Darken board face display colors while preserving authored/source solder-mask color resolution.
- Color generated solder-mask faces and drill interiors through the shared board surface palette.
- Keep mask-covered trace side walls as raised relief and tune trace height above covered fills.
Validation:
- npm test: 437 passed, 0 failed.
- npm run check:format: Prettier clean.
- npm publish --dry-run --cache /private/tmp/pcb-scene3d-viewer-npm-cache: pcb-scene3d-viewer-1.1.50.tgz, 159 files, 327.7 kB package size, 1.8 MB unpacked.
v1.1.49
Release 1.1.49 for covered-copper rendering.
Changes:
- Render Gerber mask-covered copper as a unified layer so filled copper, tracks, and arcs do not double-stack where the same area is already represented.
- Clip covered copper surfaces against filled areas while preserving authored holes and visible regions.
- Render mask-covered pours and traces as flat relief surfaces to avoid visible side-wall artifacts under solder mask.
- Add shared copper prism/test geometry helpers and focused coverage for covered-copper overlap behavior.
- Add polygon-clipping as a runtime dependency for general polygon boolean handling.
Validation:
- npm test: 434 passed, 0 failed.
- npm run check:format: All matched files use Prettier code style.
- npm publish --dry-run --cache /private/tmp/pcb-scene3d-viewer-npm-cache: pcb-scene3d-viewer-1.1.49.tgz, 159 files, 326.7 kB package size, 1.8 MB unpacked.
Commit: 446d263.