altium-to-circuit-json 0.0.39 → 0.0.40
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/dist/index.js +93 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -47,7 +47,9 @@ function mapAltiumCopperLayer(layer) {
|
|
|
47
47
|
|
|
48
48
|
// lib/pcb/convert-altium-copper-areas.ts
|
|
49
49
|
var MILS_TO_MILLIMETERS = 0.0254;
|
|
50
|
-
function convertAltiumCopperAreas(document
|
|
50
|
+
function convertAltiumCopperAreas(document, {
|
|
51
|
+
getSourceNetId = () => void 0
|
|
52
|
+
} = {}) {
|
|
51
53
|
const polygonIndexesWithRegions = new Set(
|
|
52
54
|
document.records.flatMap((record) => {
|
|
53
55
|
if (!(record instanceof AltiumRegionRecord) || record.recordKind !== "Region") {
|
|
@@ -62,24 +64,37 @@ function convertAltiumCopperAreas(document) {
|
|
|
62
64
|
);
|
|
63
65
|
return document.records.flatMap((record, recordIndex) => {
|
|
64
66
|
if (record instanceof AltiumRegionRecord) {
|
|
65
|
-
return convertCopperRegion({
|
|
67
|
+
return convertCopperRegion({
|
|
68
|
+
record,
|
|
69
|
+
recordIndex,
|
|
70
|
+
sourceNetId: getSourceNetId(record)
|
|
71
|
+
});
|
|
66
72
|
}
|
|
67
73
|
if (record instanceof AltiumPolygonRecord) {
|
|
68
74
|
const polygonIndex = polygonIndexes.get(record);
|
|
69
75
|
if (record.shelved === true || polygonIndex === void 0 || polygonIndexesWithRegions.has(polygonIndex)) {
|
|
70
76
|
return [];
|
|
71
77
|
}
|
|
72
|
-
return convertCopperPolygon({
|
|
78
|
+
return convertCopperPolygon({
|
|
79
|
+
polygonIndex,
|
|
80
|
+
record,
|
|
81
|
+
sourceNetId: getSourceNetId(record)
|
|
82
|
+
});
|
|
73
83
|
}
|
|
74
84
|
if (record instanceof AltiumFillRecord) {
|
|
75
|
-
return convertCopperFill({
|
|
85
|
+
return convertCopperFill({
|
|
86
|
+
record,
|
|
87
|
+
recordIndex,
|
|
88
|
+
sourceNetId: getSourceNetId(record)
|
|
89
|
+
});
|
|
76
90
|
}
|
|
77
91
|
return [];
|
|
78
92
|
});
|
|
79
93
|
}
|
|
80
94
|
function convertCopperRegion({
|
|
81
95
|
record,
|
|
82
|
-
recordIndex
|
|
96
|
+
recordIndex,
|
|
97
|
+
sourceNetId
|
|
83
98
|
}) {
|
|
84
99
|
if (record.recordKind !== "Region" || record.regionKind !== "COPPER") {
|
|
85
100
|
return [];
|
|
@@ -95,6 +110,7 @@ function convertCopperRegion({
|
|
|
95
110
|
{
|
|
96
111
|
type: "pcb_copper_pour",
|
|
97
112
|
pcb_copper_pour_id: `pcb_copper_pour_altium_region_${recordIndex}`,
|
|
113
|
+
...sourceNetId ? { source_net_id: sourceNetId } : {},
|
|
98
114
|
covered_with_solder_mask: true,
|
|
99
115
|
layer,
|
|
100
116
|
shape: "polygon",
|
|
@@ -106,6 +122,7 @@ function convertCopperRegion({
|
|
|
106
122
|
{
|
|
107
123
|
type: "pcb_copper_pour",
|
|
108
124
|
pcb_copper_pour_id: `pcb_copper_pour_altium_region_${recordIndex}`,
|
|
125
|
+
...sourceNetId ? { source_net_id: sourceNetId } : {},
|
|
109
126
|
covered_with_solder_mask: true,
|
|
110
127
|
layer,
|
|
111
128
|
shape: "brep",
|
|
@@ -118,7 +135,8 @@ function convertCopperRegion({
|
|
|
118
135
|
}
|
|
119
136
|
function convertCopperPolygon({
|
|
120
137
|
polygonIndex,
|
|
121
|
-
record
|
|
138
|
+
record,
|
|
139
|
+
sourceNetId
|
|
122
140
|
}) {
|
|
123
141
|
const layer = mapAltiumCopperLayer(record.layer);
|
|
124
142
|
if (!layer) return [];
|
|
@@ -128,6 +146,7 @@ function convertCopperPolygon({
|
|
|
128
146
|
{
|
|
129
147
|
type: "pcb_copper_pour",
|
|
130
148
|
pcb_copper_pour_id: `pcb_copper_pour_altium_polygon_${polygonIndex}`,
|
|
149
|
+
...sourceNetId ? { source_net_id: sourceNetId } : {},
|
|
131
150
|
covered_with_solder_mask: true,
|
|
132
151
|
layer,
|
|
133
152
|
shape: "polygon",
|
|
@@ -137,7 +156,8 @@ function convertCopperPolygon({
|
|
|
137
156
|
}
|
|
138
157
|
function convertCopperFill({
|
|
139
158
|
record,
|
|
140
|
-
recordIndex
|
|
159
|
+
recordIndex,
|
|
160
|
+
sourceNetId
|
|
141
161
|
}) {
|
|
142
162
|
const layer = mapAltiumCopperLayer(record.layer);
|
|
143
163
|
if (!layer || !record.bounds) return [];
|
|
@@ -148,6 +168,7 @@ function convertCopperFill({
|
|
|
148
168
|
{
|
|
149
169
|
type: "pcb_copper_pour",
|
|
150
170
|
pcb_copper_pour_id: `pcb_copper_pour_altium_fill_${recordIndex}`,
|
|
171
|
+
...sourceNetId ? { source_net_id: sourceNetId } : {},
|
|
151
172
|
covered_with_solder_mask: true,
|
|
152
173
|
layer,
|
|
153
174
|
shape: "rect",
|
|
@@ -463,6 +484,8 @@ var ALTIUM_TEXT_ANCHORS = [
|
|
|
463
484
|
];
|
|
464
485
|
function convertAltiumPcbDocToCircuitJson(document, options = {}) {
|
|
465
486
|
const elements = [];
|
|
487
|
+
const netContext = createPcbNetContext(document);
|
|
488
|
+
elements.push(...netContext.elements);
|
|
466
489
|
if (options.includeBoardOutline !== false) {
|
|
467
490
|
elements.push(createBoard(document));
|
|
468
491
|
for (const [index, cutout] of document.boardGeometry.cutouts.entries()) {
|
|
@@ -503,7 +526,11 @@ function convertAltiumPcbDocToCircuitJson(document, options = {}) {
|
|
|
503
526
|
elements.push(...convertCourtyards(document));
|
|
504
527
|
}
|
|
505
528
|
if (options.includeCopperAreas !== false) {
|
|
506
|
-
elements.push(
|
|
529
|
+
elements.push(
|
|
530
|
+
...convertAltiumCopperAreas(document, {
|
|
531
|
+
getSourceNetId: netContext.getSourceNetId
|
|
532
|
+
})
|
|
533
|
+
);
|
|
507
534
|
}
|
|
508
535
|
for (const [index, record] of document.records.entries()) {
|
|
509
536
|
if (record instanceof AltiumArcRecord2 && isKeepoutLayer2(record.layer) && options.includeKeepouts !== false) {
|
|
@@ -537,13 +564,13 @@ function convertAltiumPcbDocToCircuitJson(document, options = {}) {
|
|
|
537
564
|
const line = convertSilkscreenLine(record, index);
|
|
538
565
|
if (line) elements.push(line);
|
|
539
566
|
} else if (options.includeTraces !== false) {
|
|
540
|
-
const trace = convertTrack(record, index);
|
|
567
|
+
const trace = convertTrack(record, index, netContext);
|
|
541
568
|
if (trace) elements.push(trace);
|
|
542
569
|
}
|
|
543
570
|
continue;
|
|
544
571
|
}
|
|
545
572
|
if (record instanceof AltiumViaRecord2 && options.includeVias !== false) {
|
|
546
|
-
const via = convertVia(record, index);
|
|
573
|
+
const via = convertVia(record, index, netContext);
|
|
547
574
|
if (via) elements.push(via);
|
|
548
575
|
continue;
|
|
549
576
|
}
|
|
@@ -554,7 +581,7 @@ function convertAltiumPcbDocToCircuitJson(document, options = {}) {
|
|
|
554
581
|
const path = convertSilkscreenArc(record, index);
|
|
555
582
|
if (path) elements.push(path);
|
|
556
583
|
} else if (options.includeTraces !== false) {
|
|
557
|
-
const trace = convertArcTrack(record, index);
|
|
584
|
+
const trace = convertArcTrack(record, index, netContext);
|
|
558
585
|
if (trace) elements.push(trace);
|
|
559
586
|
}
|
|
560
587
|
continue;
|
|
@@ -852,15 +879,61 @@ function getFallbackPcbBounds(records) {
|
|
|
852
879
|
}
|
|
853
880
|
return getAltiumBounds2(points) ?? { minX: 0, minY: 0, maxX: 1e3, maxY: 800 };
|
|
854
881
|
}
|
|
855
|
-
function
|
|
882
|
+
function createPcbNetContext(document) {
|
|
883
|
+
const sourceNetIdByAltiumNet = new Map(
|
|
884
|
+
document.nets.map((net, index) => [net, `source_net_altium_pcb_${index}`])
|
|
885
|
+
);
|
|
886
|
+
const sourceTraceIdByAltiumNet = new Map(
|
|
887
|
+
document.nets.map((net, index) => [
|
|
888
|
+
net,
|
|
889
|
+
`source_trace_altium_pcb_${index}`
|
|
890
|
+
])
|
|
891
|
+
);
|
|
892
|
+
const elements = document.nets.flatMap((net, index) => {
|
|
893
|
+
const name = net.name?.trim() || `Net ${index + 1}`;
|
|
894
|
+
const sourceNetId = sourceNetIdByAltiumNet.get(net);
|
|
895
|
+
const sourceTraceId = sourceTraceIdByAltiumNet.get(net);
|
|
896
|
+
if (!sourceNetId || !sourceTraceId) return [];
|
|
897
|
+
return [
|
|
898
|
+
{
|
|
899
|
+
type: "source_net",
|
|
900
|
+
source_net_id: sourceNetId,
|
|
901
|
+
name,
|
|
902
|
+
member_source_group_ids: []
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
type: "source_trace",
|
|
906
|
+
source_trace_id: sourceTraceId,
|
|
907
|
+
connected_source_port_ids: [],
|
|
908
|
+
connected_source_net_ids: [sourceNetId],
|
|
909
|
+
name,
|
|
910
|
+
display_name: name
|
|
911
|
+
}
|
|
912
|
+
];
|
|
913
|
+
});
|
|
914
|
+
return {
|
|
915
|
+
elements,
|
|
916
|
+
getSourceNetId: (record) => {
|
|
917
|
+
const net = document.getNetForRecord(record);
|
|
918
|
+
return net ? sourceNetIdByAltiumNet.get(net) : void 0;
|
|
919
|
+
},
|
|
920
|
+
getSourceTraceId: (record) => {
|
|
921
|
+
const net = document.getNetForRecord(record);
|
|
922
|
+
return net ? sourceTraceIdByAltiumNet.get(net) : void 0;
|
|
923
|
+
}
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
function convertTrack(record, index, netContext) {
|
|
856
927
|
const start = record.start;
|
|
857
928
|
const end = record.end;
|
|
858
929
|
const layer = mapAltiumCopperLayer(record.layer);
|
|
859
930
|
if (!start || !end || !layer) return void 0;
|
|
860
931
|
const width = milsToMillimeters2(record.widthMils ?? 4);
|
|
932
|
+
const sourceTraceId = netContext.getSourceTraceId(record);
|
|
861
933
|
return {
|
|
862
934
|
type: "pcb_trace",
|
|
863
935
|
pcb_trace_id: `pcb_trace_altium_${index}`,
|
|
936
|
+
...sourceTraceId ? { source_trace_id: sourceTraceId } : {},
|
|
864
937
|
should_round_corners: true,
|
|
865
938
|
route: [
|
|
866
939
|
{ route_type: "wire", ...toMillimeterPoint(start), width, layer },
|
|
@@ -868,7 +941,7 @@ function convertTrack(record, index) {
|
|
|
868
941
|
]
|
|
869
942
|
};
|
|
870
943
|
}
|
|
871
|
-
function convertArcTrack(record, index) {
|
|
944
|
+
function convertArcTrack(record, index, netContext) {
|
|
872
945
|
if (!record.center || !record.radiusMils) return void 0;
|
|
873
946
|
const layer = mapAltiumCopperLayer(record.layer);
|
|
874
947
|
if (!layer) return void 0;
|
|
@@ -879,9 +952,11 @@ function convertArcTrack(record, index) {
|
|
|
879
952
|
startAngle: record.startAngle,
|
|
880
953
|
endAngle: record.endAngle
|
|
881
954
|
});
|
|
955
|
+
const sourceTraceId = netContext.getSourceTraceId(record);
|
|
882
956
|
return {
|
|
883
957
|
type: "pcb_trace",
|
|
884
958
|
pcb_trace_id: `pcb_trace_altium_arc_${index}`,
|
|
959
|
+
...sourceTraceId ? { source_trace_id: sourceTraceId } : {},
|
|
885
960
|
should_round_corners: true,
|
|
886
961
|
route: points.map((point) => ({
|
|
887
962
|
route_type: "wire",
|
|
@@ -910,15 +985,19 @@ function convertCopperText(record, index) {
|
|
|
910
985
|
is_mirrored: record.mirrored
|
|
911
986
|
};
|
|
912
987
|
}
|
|
913
|
-
function convertVia(record, index) {
|
|
988
|
+
function convertVia(record, index, netContext) {
|
|
914
989
|
if (!record.position) return void 0;
|
|
915
990
|
const startLayer = mapAltiumCopperLayer(record.startLayer) ?? "top";
|
|
916
991
|
const endLayer = mapAltiumCopperLayer(record.endLayer) ?? "bottom";
|
|
917
992
|
const layers = startLayer === endLayer ? [startLayer] : [startLayer, endLayer];
|
|
918
993
|
const outerDiameter = milsToMillimeters2(record.diameterMils ?? 20);
|
|
994
|
+
const sourceNetId = netContext.getSourceNetId(record);
|
|
995
|
+
const sourceTraceId = netContext.getSourceTraceId(record);
|
|
919
996
|
return {
|
|
920
997
|
type: "pcb_via",
|
|
921
998
|
pcb_via_id: `pcb_via_altium_${index}`,
|
|
999
|
+
...sourceNetId ? { source_net_id: sourceNetId } : {},
|
|
1000
|
+
...sourceTraceId ? { source_trace_id: sourceTraceId } : {},
|
|
922
1001
|
...toMillimeterPoint(record.position),
|
|
923
1002
|
outer_diameter: outerDiameter,
|
|
924
1003
|
hole_diameter: milsToMillimeters2(
|