altium-toolkit 1.1.32 → 1.1.35
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/docs/model-format.md +2 -3
- package/package.json +1 -1
- package/src/core/altium/AltiumGeneratedLibraryRecordBuilder.mjs +551 -0
- package/src/core/altium/AltiumLibraryRecordBuilder.mjs +286 -2
- package/src/core/altium/AltiumPcbLibExporter.mjs +9 -2
- package/src/core/altium/AltiumSchLibExporter.mjs +1 -1
- package/src/core/altium/PcbComponentBodyPlacementNormalizer.mjs +120 -15
- package/src/core/altium/PcbEmbeddedModelExtractor.mjs +52 -4
- package/src/core/altium/PcbShapeBasedBodyGeometryParser.mjs +85 -11
- package/src/core/altium/SourceComponentBundleNormalizer.mjs +31 -0
- package/src/core/circuit-json/CircuitJsonModelSchema.mjs +1 -1
- package/src/ui/AltiumScene3dAuthoredBodyAnchorAdapter.mjs +30 -2
- package/src/ui/AltiumScene3dExternalPlacementAdapter.mjs +27 -2
- package/src/ui/AltiumScene3dPlacementRotationPolicy.mjs +44 -0
- package/src/ui/AltiumScene3dRepeatedModelOwnerRepair.mjs +171 -6
- package/src/ui/AltiumScene3dShapeStackOwnerAdapter.mjs +782 -0
- package/src/ui/AltiumScene3dTwoRowFootprintDetector.mjs +90 -0
- package/src/ui/PcbScene3dBuilder.mjs +595 -28
- package/src/ui/PcbScene3dCopperRegionDetailBuilder.mjs +280 -0
- package/src/ui/PcbScene3dModelRegistry.mjs +16 -0
- package/src/ui/PcbScene3dPackageDimensionResolver.mjs +107 -0
- package/src/ui/PcbScene3dPackages.mjs +15 -3
- package/src/ui/PcbScene3dPadYawResolver.mjs +200 -0
- package/src/ui/PcbScene3dPlacementSideResolver.mjs +56 -0
- package/src/ui/PcbScene3dStaticBodyPlacementBuilder.mjs +638 -16
- package/src/ui/PcbScene3dStaticBodyRecovery.mjs +891 -0
- package/src/ui/PcbScene3dStaticBodySelectionKeyBuilder.mjs +358 -0
- package/src/ui/PcbScene3dStaticBodySymmetryRecovery.mjs +876 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detects two-row surface-mount footprints from normalized PCB pads.
|
|
3
|
+
*/
|
|
4
|
+
export class AltiumScene3dTwoRowFootprintDetector {
|
|
5
|
+
/**
|
|
6
|
+
* Checks whether a component owns a symmetric two-row surface footprint.
|
|
7
|
+
* @param {object} component PCB component.
|
|
8
|
+
* @param {object[]} pads Source PCB pads.
|
|
9
|
+
* @returns {boolean}
|
|
10
|
+
*/
|
|
11
|
+
static hasTwoRowSurfaceFootprint(component, pads) {
|
|
12
|
+
const surfacePads = AltiumScene3dTwoRowFootprintDetector.#surfacePads(
|
|
13
|
+
component,
|
|
14
|
+
pads
|
|
15
|
+
)
|
|
16
|
+
if (surfacePads.length < 6) {
|
|
17
|
+
return false
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const xSpread = AltiumScene3dTwoRowFootprintDetector.#spread(
|
|
21
|
+
surfacePads,
|
|
22
|
+
'x'
|
|
23
|
+
)
|
|
24
|
+
const ySpread = AltiumScene3dTwoRowFootprintDetector.#spread(
|
|
25
|
+
surfacePads,
|
|
26
|
+
'y'
|
|
27
|
+
)
|
|
28
|
+
const rowAxis = xSpread >= ySpread ? 'y' : 'x'
|
|
29
|
+
const lineAxis = rowAxis === 'x' ? 'y' : 'x'
|
|
30
|
+
const rowSpread = AltiumScene3dTwoRowFootprintDetector.#spread(
|
|
31
|
+
surfacePads,
|
|
32
|
+
rowAxis
|
|
33
|
+
)
|
|
34
|
+
const lineSpread = AltiumScene3dTwoRowFootprintDetector.#spread(
|
|
35
|
+
surfacePads,
|
|
36
|
+
lineAxis
|
|
37
|
+
)
|
|
38
|
+
if (rowSpread <= 0 || lineSpread <= 0) {
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const values = surfacePads.map((pad) => Number(pad?.[rowAxis] || 0))
|
|
43
|
+
const midpoint = (Math.min(...values) + Math.max(...values)) / 2
|
|
44
|
+
const lowerCount = values.filter((value) => value <= midpoint).length
|
|
45
|
+
const upperCount = values.length - lowerCount
|
|
46
|
+
|
|
47
|
+
return Math.min(lowerCount, upperCount) >= 3
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Collects surface pads owned by one component.
|
|
52
|
+
* @param {object} component PCB component.
|
|
53
|
+
* @param {object[]} pads Source PCB pads.
|
|
54
|
+
* @returns {object[]}
|
|
55
|
+
*/
|
|
56
|
+
static #surfacePads(component, pads) {
|
|
57
|
+
const componentIndex = Number(component?.componentIndex)
|
|
58
|
+
if (!Number.isFinite(componentIndex)) {
|
|
59
|
+
return []
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const ownedPads = (Array.isArray(pads) ? pads : []).filter(
|
|
63
|
+
(pad) => Number(pad?.componentIndex) === componentIndex
|
|
64
|
+
)
|
|
65
|
+
const bottom =
|
|
66
|
+
String(component?.layer || '')
|
|
67
|
+
.toUpperCase()
|
|
68
|
+
.includes('BOTTOM') ||
|
|
69
|
+
String(component?.layer || '').toUpperCase() === 'BOT'
|
|
70
|
+
const surfacePads = ownedPads.filter((pad) =>
|
|
71
|
+
bottom
|
|
72
|
+
? Boolean(pad?.hasBottomPasteMaskOpening)
|
|
73
|
+
: Boolean(pad?.hasTopPasteMaskOpening)
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
return surfacePads.length ? surfacePads : ownedPads
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Measures pad center spread on one axis.
|
|
81
|
+
* @param {object[]} pads Source PCB pads.
|
|
82
|
+
* @param {'x' | 'y'} axis Axis key.
|
|
83
|
+
* @returns {number}
|
|
84
|
+
*/
|
|
85
|
+
static #spread(pads, axis) {
|
|
86
|
+
const values = pads.map((pad) => Number(pad?.[axis] || 0))
|
|
87
|
+
|
|
88
|
+
return Math.max(...values) - Math.min(...values)
|
|
89
|
+
}
|
|
90
|
+
}
|