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 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({ record, recordIndex });
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({ polygonIndex, record });
78
+ return convertCopperPolygon({
79
+ polygonIndex,
80
+ record,
81
+ sourceNetId: getSourceNetId(record)
82
+ });
73
83
  }
74
84
  if (record instanceof AltiumFillRecord) {
75
- return convertCopperFill({ record, recordIndex });
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(...convertAltiumCopperAreas(document));
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 convertTrack(record, index) {
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(