circuit-json-to-kicad 0.0.14 → 0.0.15

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.
Files changed (2) hide show
  1. package/dist/index.js +296 -51
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -109,35 +109,32 @@ import { applyToPoint, scale as createScaleMatrix } from "transformation-matrix"
109
109
  var AddLibrarySymbolsStage = class extends ConverterStage {
110
110
  _step() {
111
111
  const { kicadSch, db } = this.ctx;
112
- const schematicComponents = db.schematic_component.list();
113
- if (schematicComponents.length === 0) {
114
- this.finished = true;
115
- return;
116
- }
117
112
  const libSymbols = new LibSymbols();
118
113
  const librarySymbols = [];
114
+ const schematicComponents = db.schematic_component.list();
119
115
  for (const schematicComponent of schematicComponents) {
120
- const sourceComp = schematicComponent.source_component_id ? db.source_component.get(schematicComponent.source_component_id) : null;
121
- if (!sourceComp) continue;
122
- const symbolName = schematicComponent.symbol_name || (sourceComp.ftype === "simple_chip" ? `generic_chip_${schematicComponent.source_component_id}` : null);
123
- if (!symbolName) {
124
- continue;
116
+ const libSymbol = this.createLibrarySymbolForComponent(schematicComponent);
117
+ if (libSymbol) {
118
+ librarySymbols.push(libSymbol);
125
119
  }
126
- let symbolData;
127
- if (symbolName.startsWith("generic_chip_")) {
128
- symbolData = this.createGenericChipSymbolData(schematicComponent, db);
129
- } else {
130
- symbolData = symbols[symbolName];
131
- if (!symbolData) {
132
- continue;
120
+ }
121
+ const netLabels = db.schematic_net_label?.list?.() || [];
122
+ for (const netLabel of netLabels) {
123
+ if (netLabel.symbol_name) {
124
+ const isPower = netLabel.source_net_id ? db.source_net.get(netLabel.source_net_id)?.is_power : false;
125
+ const isGround = netLabel.source_net_id ? db.source_net.get(netLabel.source_net_id)?.is_ground : false;
126
+ const isPowerOrGround = isPower || isGround;
127
+ if (isPowerOrGround) {
128
+ const libSymbol = this.createLibrarySymbolForNetLabel({
129
+ netLabel,
130
+ isPower: isPower ?? false,
131
+ isGround: isGround ?? false
132
+ });
133
+ if (libSymbol) {
134
+ librarySymbols.push(libSymbol);
135
+ }
133
136
  }
134
137
  }
135
- const libSymbol = this.createLibrarySymbolFromSchematicSymbol({
136
- symbolData,
137
- sourceComp,
138
- schematicComponent
139
- });
140
- librarySymbols.push(libSymbol);
141
138
  }
142
139
  libSymbols.symbols = librarySymbols;
143
140
  if (kicadSch) {
@@ -145,6 +142,61 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
145
142
  }
146
143
  this.finished = true;
147
144
  }
145
+ /**
146
+ * Create library symbol for a schematic component
147
+ */
148
+ createLibrarySymbolForComponent(schematicComponent) {
149
+ const { db } = this.ctx;
150
+ const sourceComp = schematicComponent.source_component_id ? db.source_component.get(schematicComponent.source_component_id) : null;
151
+ if (!sourceComp) return null;
152
+ const symbolName = schematicComponent.symbol_name || (sourceComp.ftype === "simple_chip" ? `generic_chip_${schematicComponent.source_component_id}` : null);
153
+ if (!symbolName) return null;
154
+ const symbolData = this.getSymbolData(symbolName, schematicComponent);
155
+ if (!symbolData) return null;
156
+ const libId = getLibraryId(sourceComp, schematicComponent);
157
+ const isChip = sourceComp.ftype === "simple_chip";
158
+ return this.createLibrarySymbol({
159
+ libId,
160
+ symbolData,
161
+ isChip,
162
+ schematicComponent,
163
+ description: this.getDescription(sourceComp),
164
+ keywords: this.getKeywords(sourceComp),
165
+ fpFilters: this.getFpFilters(sourceComp)
166
+ });
167
+ }
168
+ /**
169
+ * Create library symbol for a schematic net label with symbol_name
170
+ */
171
+ createLibrarySymbolForNetLabel({
172
+ netLabel,
173
+ isPower,
174
+ isGround
175
+ }) {
176
+ const symbolName = netLabel.symbol_name;
177
+ if (!symbolName) return null;
178
+ const symbolData = symbols[symbolName];
179
+ if (!symbolData) return null;
180
+ const libId = `Custom:${symbolName}`;
181
+ return this.createLibrarySymbol({
182
+ libId,
183
+ symbolData,
184
+ isChip: false,
185
+ schematicComponent: void 0,
186
+ description: isPower ? "Power net label" : isGround ? "Ground net label" : "Net symbol",
187
+ keywords: isPower ? "power net" : isGround ? "ground net" : "net",
188
+ fpFilters: ""
189
+ });
190
+ }
191
+ /**
192
+ * Get symbol data from schematic-symbols or generate for generic chips
193
+ */
194
+ getSymbolData(symbolName, schematicComponent) {
195
+ if (symbolName.startsWith("generic_chip_")) {
196
+ return this.createGenericChipSymbolData(schematicComponent, this.ctx.db);
197
+ }
198
+ return symbols[symbolName] || null;
199
+ }
148
200
  /**
149
201
  * Create generic chip symbol data for chips without a symbol_name
150
202
  */
@@ -182,14 +234,18 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
182
234
  };
183
235
  }
184
236
  /**
185
- * Convert schematic-symbols data to KiCad library symbol
237
+ * Create a KiCad library symbol from symbol data
238
+ * This is the core method that handles both components and net labels
186
239
  */
187
- createLibrarySymbolFromSchematicSymbol({
240
+ createLibrarySymbol({
241
+ libId,
188
242
  symbolData,
189
- sourceComp,
190
- schematicComponent
243
+ isChip,
244
+ schematicComponent,
245
+ description,
246
+ keywords,
247
+ fpFilters
191
248
  }) {
192
- const libId = getLibraryId(sourceComp, schematicComponent);
193
249
  const symbol = new SchematicSymbol({
194
250
  libraryId: libId,
195
251
  excludeFromSim: false,
@@ -197,13 +253,18 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
197
253
  onBoard: true
198
254
  });
199
255
  const pinNumbers = new SymbolPinNumbers();
200
- pinNumbers.hide = sourceComp?.ftype !== "simple_chip";
256
+ pinNumbers.hide = !isChip;
201
257
  symbol._sxPinNumbers = pinNumbers;
202
258
  const pinNames = new SymbolPinNames();
203
- pinNames.offset = sourceComp?.ftype === "simple_chip" ? 1.27 : 0;
259
+ pinNames.offset = isChip ? 1.27 : 0;
204
260
  symbol._sxPinNames = pinNames;
205
- this.addSymbolProperties(symbol, libId, sourceComp);
206
- const isChip = sourceComp?.ftype === "simple_chip";
261
+ this.addSymbolProperties({
262
+ symbol,
263
+ libId,
264
+ description,
265
+ keywords,
266
+ fpFilters
267
+ });
207
268
  const drawingSymbol = this.createDrawingSubsymbol({
208
269
  libId,
209
270
  symbolData,
@@ -223,7 +284,13 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
223
284
  /**
224
285
  * Add properties to the library symbol
225
286
  */
226
- addSymbolProperties(symbol, libId, sourceComp) {
287
+ addSymbolProperties({
288
+ symbol,
289
+ libId,
290
+ description,
291
+ keywords,
292
+ fpFilters
293
+ }) {
227
294
  const refPrefix = libId.split(":")[1]?.[0] || "U";
228
295
  const properties = [
229
296
  {
@@ -250,21 +317,21 @@ var AddLibrarySymbolsStage = class extends ConverterStage {
250
317
  },
251
318
  {
252
319
  key: "Description",
253
- value: this.getDescription(sourceComp),
320
+ value: description,
254
321
  id: 4,
255
322
  at: [0, 0, 0],
256
323
  hide: true
257
324
  },
258
325
  {
259
326
  key: "ki_keywords",
260
- value: this.getKeywords(sourceComp),
327
+ value: keywords,
261
328
  id: 5,
262
329
  at: [0, 0, 0],
263
330
  hide: true
264
331
  },
265
332
  {
266
333
  key: "ki_fp_filters",
267
- value: this.getFpFilters(sourceComp),
334
+ value: fpFilters,
268
335
  id: 6,
269
336
  at: [0, 0, 0],
270
337
  hide: true
@@ -745,9 +812,186 @@ var AddSchematicSymbolsStage = class extends ConverterStage {
745
812
  }
746
813
  };
747
814
 
815
+ // lib/schematic/stages/AddSchematicNetLabelsStage.ts
816
+ import {
817
+ SchematicSymbol as SchematicSymbol3,
818
+ SymbolLibId as SymbolLibId2,
819
+ SymbolProperty as SymbolProperty3,
820
+ SymbolPin as SymbolPin3,
821
+ SymbolInstances as SymbolInstances2,
822
+ SymbolInstancesProject as SymbolInstancesProject2,
823
+ SymbolInstancePath as SymbolInstancePath2,
824
+ TextEffects as TextEffects3,
825
+ TextEffectsFont as TextEffectsFont3,
826
+ Label
827
+ } from "kicadts";
828
+ import { applyToPoint as applyToPoint3 } from "transformation-matrix";
829
+ var AddSchematicNetLabelsStage = class extends ConverterStage {
830
+ _step() {
831
+ const { kicadSch, db } = this.ctx;
832
+ const netLabels = db.schematic_net_label?.list?.() || [];
833
+ if (netLabels.length === 0) {
834
+ this.finished = true;
835
+ return;
836
+ }
837
+ if (!this.ctx.c2kMatSch) {
838
+ this.finished = true;
839
+ return;
840
+ }
841
+ const symbols3 = [];
842
+ const labels = [];
843
+ for (const netLabel of netLabels) {
844
+ const labelText = netLabel.text || "";
845
+ const symbolName = netLabel.symbol_name;
846
+ if (symbolName) {
847
+ const symbol = this.createSymbolFromNetLabel(
848
+ netLabel,
849
+ labelText,
850
+ symbolName
851
+ );
852
+ if (symbol) {
853
+ symbols3.push(symbol);
854
+ }
855
+ } else {
856
+ const label = this.createLabel(netLabel, labelText);
857
+ if (label) {
858
+ labels.push(label);
859
+ }
860
+ }
861
+ }
862
+ if (kicadSch && symbols3.length > 0) {
863
+ const existingSymbols = kicadSch.symbols || [];
864
+ kicadSch.symbols = [...existingSymbols, ...symbols3];
865
+ }
866
+ if (kicadSch && labels.length > 0) {
867
+ kicadSch.labels = [...kicadSch.labels || [], ...labels];
868
+ }
869
+ this.finished = true;
870
+ }
871
+ /**
872
+ * Create a KiCad symbol instance from a net label with a symbol_name
873
+ * These are treated like regular components (e.g., rail_up, rail_down, vcc_up, ground_down)
874
+ */
875
+ createSymbolFromNetLabel(netLabel, labelText, symbolName) {
876
+ if (!this.ctx.c2kMatSch) return null;
877
+ const { x, y } = applyToPoint3(this.ctx.c2kMatSch, {
878
+ x: netLabel.center?.x || netLabel.anchor_position?.x || 0,
879
+ y: netLabel.center?.y || netLabel.anchor_position?.y || 0
880
+ });
881
+ const uuid = crypto.randomUUID();
882
+ const symbol = new SchematicSymbol3({
883
+ at: [x, y, 0],
884
+ unit: 1,
885
+ excludeFromSim: false,
886
+ inBom: true,
887
+ onBoard: true,
888
+ dnp: false,
889
+ uuid,
890
+ fieldsAutoplaced: true
891
+ });
892
+ const libId = `Custom:${symbolName}`;
893
+ const symLibId = new SymbolLibId2(libId);
894
+ symbol._sxLibId = symLibId;
895
+ const isUpSymbol = symbolName.includes("_up") || symbolName.toLowerCase().includes("vcc");
896
+ const referenceOffset = isUpSymbol ? -4 : 4;
897
+ const valueOffset = isUpSymbol ? -6 : 6;
898
+ const referenceProperty = new SymbolProperty3({
899
+ key: "Reference",
900
+ value: labelText,
901
+ // Use the label text as the reference
902
+ id: 0,
903
+ at: [x, y + referenceOffset, 0],
904
+ effects: this.createTextEffects(1.27, false)
905
+ });
906
+ const valueProperty = new SymbolProperty3({
907
+ key: "Value",
908
+ value: labelText,
909
+ id: 1,
910
+ at: [x, y + valueOffset, 0],
911
+ effects: this.createTextEffects(1.27, true)
912
+ });
913
+ const footprintProperty = new SymbolProperty3({
914
+ key: "Footprint",
915
+ value: "",
916
+ id: 2,
917
+ at: [x - 1.778, y, 90],
918
+ effects: this.createTextEffects(1.27, true)
919
+ });
920
+ const datasheetProperty = new SymbolProperty3({
921
+ key: "Datasheet",
922
+ value: "~",
923
+ id: 3,
924
+ at: [x, y, 0],
925
+ effects: this.createTextEffects(1.27, true)
926
+ });
927
+ const descriptionProperty = new SymbolProperty3({
928
+ key: "Description",
929
+ value: `Power/Net symbol: ${labelText}`,
930
+ id: 4,
931
+ at: [x, y, 0],
932
+ effects: this.createTextEffects(1.27, true)
933
+ });
934
+ symbol.properties.push(
935
+ referenceProperty,
936
+ valueProperty,
937
+ footprintProperty,
938
+ datasheetProperty,
939
+ descriptionProperty
940
+ );
941
+ const pin = new SymbolPin3();
942
+ pin.numberString = "1";
943
+ pin.uuid = crypto.randomUUID();
944
+ symbol.pins.push(pin);
945
+ const { kicadSch } = this.ctx;
946
+ const instances = new SymbolInstances2();
947
+ const project = new SymbolInstancesProject2("");
948
+ const path = new SymbolInstancePath2(`/${kicadSch?.uuid?.value || ""}`);
949
+ path.reference = labelText;
950
+ path.unit = 1;
951
+ project.paths.push(path);
952
+ instances.projects.push(project);
953
+ symbol._sxInstances = instances;
954
+ return symbol;
955
+ }
956
+ /**
957
+ * Create a KiCad label from a schematic_net_label without a symbol
958
+ */
959
+ createLabel(netLabel, labelText) {
960
+ if (!this.ctx.c2kMatSch) return null;
961
+ const { x, y } = applyToPoint3(this.ctx.c2kMatSch, {
962
+ x: netLabel.center?.x || netLabel.anchor_position?.x || 0,
963
+ y: netLabel.center?.y || netLabel.anchor_position?.y || 0
964
+ });
965
+ const label = new Label({
966
+ value: labelText,
967
+ at: [x, y, 0],
968
+ effects: this.createTextEffects(1.27, false),
969
+ uuid: crypto.randomUUID()
970
+ });
971
+ return label;
972
+ }
973
+ /**
974
+ * Creates text effects for properties and labels
975
+ */
976
+ createTextEffects(size, hide = false) {
977
+ const font = new TextEffectsFont3();
978
+ font.size = { height: size, width: size };
979
+ return new TextEffects3({
980
+ font,
981
+ hiddenText: hide
982
+ });
983
+ }
984
+ getOutput() {
985
+ if (!this.ctx.kicadSch) {
986
+ throw new Error("kicadSch is not initialized");
987
+ }
988
+ return this.ctx.kicadSch;
989
+ }
990
+ };
991
+
748
992
  // lib/schematic/stages/AddSchematicTracesStage.ts
749
993
  import { Wire, Pts as Pts2, Xy as Xy2, Stroke as Stroke2, Junction } from "kicadts";
750
- import { applyToPoint as applyToPoint3 } from "transformation-matrix";
994
+ import { applyToPoint as applyToPoint4 } from "transformation-matrix";
751
995
  var AddSchematicTracesStage = class extends ConverterStage {
752
996
  _step() {
753
997
  const { kicadSch, db } = this.ctx;
@@ -785,11 +1029,11 @@ var AddSchematicTracesStage = class extends ConverterStage {
785
1029
  "Schematic transformation matrix not initialized in context"
786
1030
  );
787
1031
  }
788
- const from = applyToPoint3(this.ctx.c2kMatSch, {
1032
+ const from = applyToPoint4(this.ctx.c2kMatSch, {
789
1033
  x: edge.from.x,
790
1034
  y: edge.from.y
791
1035
  });
792
- const to = applyToPoint3(this.ctx.c2kMatSch, {
1036
+ const to = applyToPoint4(this.ctx.c2kMatSch, {
793
1037
  x: edge.to.x,
794
1038
  y: edge.to.y
795
1039
  });
@@ -815,7 +1059,7 @@ var AddSchematicTracesStage = class extends ConverterStage {
815
1059
  "Schematic transformation matrix not initialized in context"
816
1060
  );
817
1061
  }
818
- const { x, y } = applyToPoint3(this.ctx.c2kMatSch, {
1062
+ const { x, y } = applyToPoint4(this.ctx.c2kMatSch, {
819
1063
  x: junction.x,
820
1064
  y: junction.y
821
1065
  });
@@ -938,6 +1182,7 @@ var CircuitJsonToKicadSchConverter = class {
938
1182
  new InitializeSchematicStage(circuitJson, this.ctx),
939
1183
  new AddLibrarySymbolsStage(circuitJson, this.ctx),
940
1184
  new AddSchematicSymbolsStage(circuitJson, this.ctx),
1185
+ new AddSchematicNetLabelsStage(circuitJson, this.ctx),
941
1186
  new AddSchematicTracesStage(circuitJson, this.ctx),
942
1187
  new AddSheetInstancesStage(circuitJson, this.ctx)
943
1188
  ];
@@ -1071,7 +1316,7 @@ var AddNetsStage = class extends ConverterStage {
1071
1316
 
1072
1317
  // lib/pcb/stages/AddFootprintsStage.ts
1073
1318
  import { Footprint, FpText, FootprintPad } from "kicadts";
1074
- import { applyToPoint as applyToPoint4 } from "transformation-matrix";
1319
+ import { applyToPoint as applyToPoint5 } from "transformation-matrix";
1075
1320
  var AddFootprintsStage = class extends ConverterStage {
1076
1321
  componentsProcessed = 0;
1077
1322
  pcbComponents = [];
@@ -1095,7 +1340,7 @@ var AddFootprintsStage = class extends ConverterStage {
1095
1340
  const sourceComponent = component.source_component_id ? this.ctx.db.source_component.get(component.source_component_id) : null;
1096
1341
  const footprintName = sourceComponent?.ftype || "Unknown";
1097
1342
  const componentName = sourceComponent?.name || `Component_${this.componentsProcessed}`;
1098
- const transformedPos = applyToPoint4(c2kMatPcb, {
1343
+ const transformedPos = applyToPoint5(c2kMatPcb, {
1099
1344
  x: component.center.x,
1100
1345
  y: component.center.y
1101
1346
  });
@@ -1176,7 +1421,7 @@ var AddFootprintsStage = class extends ConverterStage {
1176
1421
 
1177
1422
  // lib/pcb/stages/AddTracesStage.ts
1178
1423
  import { Segment, SegmentNet } from "kicadts";
1179
- import { applyToPoint as applyToPoint5 } from "transformation-matrix";
1424
+ import { applyToPoint as applyToPoint6 } from "transformation-matrix";
1180
1425
  var AddTracesStage = class extends ConverterStage {
1181
1426
  tracesProcessed = 0;
1182
1427
  pcbTraces = [];
@@ -1204,11 +1449,11 @@ var AddTracesStage = class extends ConverterStage {
1204
1449
  for (let i = 0; i < trace.route.length - 1; i++) {
1205
1450
  const startPoint = trace.route[i];
1206
1451
  const endPoint = trace.route[i + 1];
1207
- const transformedStart = applyToPoint5(c2kMatPcb, {
1452
+ const transformedStart = applyToPoint6(c2kMatPcb, {
1208
1453
  x: startPoint.x,
1209
1454
  y: startPoint.y
1210
1455
  });
1211
- const transformedEnd = applyToPoint5(c2kMatPcb, {
1456
+ const transformedEnd = applyToPoint6(c2kMatPcb, {
1212
1457
  x: endPoint.x,
1213
1458
  y: endPoint.y
1214
1459
  });
@@ -1242,7 +1487,7 @@ var AddTracesStage = class extends ConverterStage {
1242
1487
 
1243
1488
  // lib/pcb/stages/AddViasStage.ts
1244
1489
  import { Via, ViaNet } from "kicadts";
1245
- import { applyToPoint as applyToPoint6 } from "transformation-matrix";
1490
+ import { applyToPoint as applyToPoint7 } from "transformation-matrix";
1246
1491
  var AddViasStage = class extends ConverterStage {
1247
1492
  viasProcessed = 0;
1248
1493
  pcbVias = [];
@@ -1263,7 +1508,7 @@ var AddViasStage = class extends ConverterStage {
1263
1508
  return;
1264
1509
  }
1265
1510
  const via = this.pcbVias[this.viasProcessed];
1266
- const transformedPos = applyToPoint6(c2kMatPcb, {
1511
+ const transformedPos = applyToPoint7(c2kMatPcb, {
1267
1512
  x: via.x,
1268
1513
  y: via.y
1269
1514
  });
@@ -1290,7 +1535,7 @@ var AddViasStage = class extends ConverterStage {
1290
1535
 
1291
1536
  // lib/pcb/stages/AddGraphicsStage.ts
1292
1537
  import { GrLine } from "kicadts";
1293
- import { applyToPoint as applyToPoint7 } from "transformation-matrix";
1538
+ import { applyToPoint as applyToPoint8 } from "transformation-matrix";
1294
1539
  var AddGraphicsStage = class extends ConverterStage {
1295
1540
  _step() {
1296
1541
  const { kicadPcb, c2kMatPcb } = this.ctx;
@@ -1307,11 +1552,11 @@ var AddGraphicsStage = class extends ConverterStage {
1307
1552
  const startPoint = path.route[i];
1308
1553
  const endPoint = path.route[i + 1];
1309
1554
  if (!startPoint || !endPoint) continue;
1310
- const transformedStart = applyToPoint7(c2kMatPcb, {
1555
+ const transformedStart = applyToPoint8(c2kMatPcb, {
1311
1556
  x: startPoint.x,
1312
1557
  y: startPoint.y
1313
1558
  });
1314
- const transformedEnd = applyToPoint7(c2kMatPcb, {
1559
+ const transformedEnd = applyToPoint8(c2kMatPcb, {
1315
1560
  x: endPoint.x,
1316
1561
  y: endPoint.y
1317
1562
  });
@@ -1352,7 +1597,7 @@ var AddGraphicsStage = class extends ConverterStage {
1352
1597
  ];
1353
1598
  }
1354
1599
  const transformedCorners = corners.map(
1355
- (corner) => applyToPoint7(c2kMatPcb, corner)
1600
+ (corner) => applyToPoint8(c2kMatPcb, corner)
1356
1601
  );
1357
1602
  for (let i = 0; i < transformedCorners.length; i++) {
1358
1603
  const start = transformedCorners[i];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "circuit-json-to-kicad",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.14",
4
+ "version": "0.0.15",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "dist"