@tscircuit/cli 0.1.1135 → 0.1.1136
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/cli/main.js +344 -280
- package/dist/lib/index.js +317 -279
- package/package.json +2 -2
package/dist/cli/main.js
CHANGED
|
@@ -97682,7 +97682,7 @@ var import_perfect_cli = __toESM2(require_dist2(), 1);
|
|
|
97682
97682
|
// lib/getVersion.ts
|
|
97683
97683
|
import { createRequire as createRequire2 } from "node:module";
|
|
97684
97684
|
// package.json
|
|
97685
|
-
var version = "0.1.
|
|
97685
|
+
var version = "0.1.1135";
|
|
97686
97686
|
var package_default = {
|
|
97687
97687
|
name: "@tscircuit/cli",
|
|
97688
97688
|
version,
|
|
@@ -97712,7 +97712,7 @@ var package_default = {
|
|
|
97712
97712
|
"bun-match-svg": "^0.0.12",
|
|
97713
97713
|
chokidar: "4.0.1",
|
|
97714
97714
|
"circuit-json": "^0.0.403",
|
|
97715
|
-
"circuit-json-to-kicad": "^0.0.
|
|
97715
|
+
"circuit-json-to-kicad": "^0.0.85",
|
|
97716
97716
|
"circuit-json-to-readable-netlist": "^0.0.15",
|
|
97717
97717
|
"circuit-json-to-spice": "^0.0.10",
|
|
97718
97718
|
"circuit-json-to-tscircuit": "^0.0.9",
|
|
@@ -101621,7 +101621,7 @@ import {
|
|
|
101621
101621
|
SheetInstancesRootPage,
|
|
101622
101622
|
EmbeddedFonts as EmbeddedFonts3
|
|
101623
101623
|
} from "kicadts";
|
|
101624
|
-
import { KicadPcb } from "kicadts";
|
|
101624
|
+
import { KicadPcb as KicadPcb2 } from "kicadts";
|
|
101625
101625
|
import { cju as cju2 } from "@tscircuit/circuit-json-util";
|
|
101626
101626
|
import { compose as compose4, translate as translate4, scale as scale3 } from "transformation-matrix";
|
|
101627
101627
|
import {
|
|
@@ -101632,15 +101632,26 @@ import {
|
|
|
101632
101632
|
Setup
|
|
101633
101633
|
} from "kicadts";
|
|
101634
101634
|
import { PcbNet } from "kicadts";
|
|
101635
|
-
import { Footprint as
|
|
101636
|
-
import { applyToPoint as applyToPoint13 } from "transformation-matrix";
|
|
101635
|
+
import { Footprint as Footprint3, FootprintModel as FootprintModel4 } from "kicadts";
|
|
101637
101636
|
import {
|
|
101637
|
+
parseKicadSexpr,
|
|
101638
|
+
KicadPcb,
|
|
101639
|
+
FootprintModel,
|
|
101640
|
+
At,
|
|
101641
|
+
EmbeddedFonts as EmbeddedFonts4,
|
|
101642
|
+
FootprintAttr,
|
|
101638
101643
|
Property,
|
|
101639
101644
|
TextEffects as TextEffects6,
|
|
101640
|
-
TextEffectsFont as TextEffectsFont6
|
|
101641
|
-
|
|
101642
|
-
|
|
101643
|
-
|
|
101645
|
+
TextEffectsFont as TextEffectsFont6
|
|
101646
|
+
} from "kicadts";
|
|
101647
|
+
import { applyToPoint as applyToPoint13 } from "transformation-matrix";
|
|
101648
|
+
import {
|
|
101649
|
+
Property as Property2,
|
|
101650
|
+
TextEffects as TextEffects7,
|
|
101651
|
+
TextEffectsFont as TextEffectsFont7,
|
|
101652
|
+
EmbeddedFonts as EmbeddedFonts5,
|
|
101653
|
+
FootprintModel as FootprintModel2,
|
|
101654
|
+
FootprintAttr as FootprintAttr2
|
|
101644
101655
|
} from "kicadts";
|
|
101645
101656
|
import { FpCircle, Stroke as Stroke4 } from "kicadts";
|
|
101646
101657
|
import { FpCircle as FpCircle2, Stroke as Stroke5 } from "kicadts";
|
|
@@ -101649,11 +101660,11 @@ import { FpRect as FpRect2, Stroke as Stroke7 } from "kicadts";
|
|
|
101649
101660
|
import { FpRect as FpRect3, Stroke as Stroke8 } from "kicadts";
|
|
101650
101661
|
import { FpPoly, Pts as Pts3, Xy as Xy3, Stroke as Stroke9 } from "kicadts";
|
|
101651
101662
|
import"kicadts";
|
|
101652
|
-
import { FpText, TextEffects as
|
|
101663
|
+
import { FpText, TextEffects as TextEffects8, TextEffectsFont as TextEffectsFont8 } from "kicadts";
|
|
101653
101664
|
import { applyToPoint as applyToPoint8, rotate, identity } from "transformation-matrix";
|
|
101654
|
-
import { FpText as FpText3, TextEffects as
|
|
101665
|
+
import { FpText as FpText3, TextEffects as TextEffects9, TextEffectsFont as TextEffectsFont9 } from "kicadts";
|
|
101655
101666
|
import { applyToPoint as applyToPoint9, rotate as rotate2, identity as identity2 } from "transformation-matrix";
|
|
101656
|
-
import { FootprintModel as
|
|
101667
|
+
import { FootprintModel as FootprintModel3 } from "kicadts";
|
|
101657
101668
|
import {
|
|
101658
101669
|
FootprintPad,
|
|
101659
101670
|
PadPrimitives,
|
|
@@ -101680,36 +101691,25 @@ import { Via, ViaNet } from "kicadts";
|
|
|
101680
101691
|
import { applyToPoint as applyToPoint15 } from "transformation-matrix";
|
|
101681
101692
|
import { GrLine } from "kicadts";
|
|
101682
101693
|
import {
|
|
101683
|
-
At,
|
|
101694
|
+
At as At2,
|
|
101684
101695
|
GrText,
|
|
101685
|
-
TextEffects as
|
|
101686
|
-
TextEffectsFont as
|
|
101696
|
+
TextEffects as TextEffects10,
|
|
101697
|
+
TextEffectsFont as TextEffectsFont10,
|
|
101687
101698
|
TextEffectsJustify as TextEffectsJustify3
|
|
101688
101699
|
} from "kicadts";
|
|
101689
101700
|
import { applyToPoint as applyToPoint16 } from "transformation-matrix";
|
|
101690
101701
|
import { applyToPoint as applyToPoint18 } from "transformation-matrix";
|
|
101691
101702
|
import {
|
|
101692
101703
|
GrText as GrText2,
|
|
101693
|
-
TextEffects as
|
|
101694
|
-
TextEffectsFont as
|
|
101704
|
+
TextEffects as TextEffects11,
|
|
101705
|
+
TextEffectsFont as TextEffectsFont11,
|
|
101695
101706
|
TextEffectsJustify as TextEffectsJustify4,
|
|
101696
|
-
At as
|
|
101707
|
+
At as At3
|
|
101697
101708
|
} from "kicadts";
|
|
101698
101709
|
import { applyToPoint as applyToPoint17 } from "transformation-matrix";
|
|
101699
101710
|
import { cju as cju3 } from "@tscircuit/circuit-json-util";
|
|
101700
101711
|
import { cju as cju4 } from "@tscircuit/circuit-json-util";
|
|
101701
|
-
import { parseKicadSexpr, KicadSch as KicadSch2 } from "kicadts";
|
|
101702
|
-
import {
|
|
101703
|
-
parseKicadSexpr as parseKicadSexpr2,
|
|
101704
|
-
KicadPcb as KicadPcb2,
|
|
101705
|
-
FootprintModel as FootprintModel3,
|
|
101706
|
-
At as At3,
|
|
101707
|
-
EmbeddedFonts as EmbeddedFonts5,
|
|
101708
|
-
FootprintAttr as FootprintAttr2,
|
|
101709
|
-
Property as Property2,
|
|
101710
|
-
TextEffects as TextEffects11,
|
|
101711
|
-
TextEffectsFont as TextEffectsFont11
|
|
101712
|
-
} from "kicadts";
|
|
101712
|
+
import { parseKicadSexpr as parseKicadSexpr2, KicadSch as KicadSch2 } from "kicadts";
|
|
101713
101713
|
import { KicadSymbolLib } from "kicadts";
|
|
101714
101714
|
import { parseKicadMod } from "kicadts";
|
|
101715
101715
|
import {
|
|
@@ -103346,8 +103346,229 @@ function generateDeterministicUuid(data) {
|
|
|
103346
103346
|
const hash = simpleHash(data);
|
|
103347
103347
|
return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-${hash.slice(12, 16)}-${hash.slice(16, 20)}-${hash.slice(20, 32)}`;
|
|
103348
103348
|
}
|
|
103349
|
+
var MODEL_CDN_BASE_URL = "https://modelcdn.tscircuit.com/jscad_models";
|
|
103350
|
+
var KICAD_FP_VERSION = 20240108;
|
|
103351
|
+
var KICAD_FP_GENERATOR = "pcbnew";
|
|
103352
|
+
var KICAD_FP_GENERATOR_VERSION = "8.0";
|
|
103353
|
+
function getBasename(filePath) {
|
|
103354
|
+
const parts = filePath.split(/[/\\]/);
|
|
103355
|
+
return parts[parts.length - 1] || filePath;
|
|
103356
|
+
}
|
|
103357
|
+
var ExtractFootprintsStage = class extends ConverterStage {
|
|
103358
|
+
classifyFootprints() {
|
|
103359
|
+
const customFootprintNames = /* @__PURE__ */ new Set;
|
|
103360
|
+
const footprinterStrings = /* @__PURE__ */ new Map;
|
|
103361
|
+
const cadComponents = this.ctx.db.cad_component?.list() ?? [];
|
|
103362
|
+
const sourceComponents = this.ctx.db.source_component;
|
|
103363
|
+
for (const cadComponent of cadComponents) {
|
|
103364
|
+
const sourceComp = cadComponent.source_component_id ? sourceComponents?.get(cadComponent.source_component_id) : null;
|
|
103365
|
+
if (!sourceComp)
|
|
103366
|
+
continue;
|
|
103367
|
+
const footprintName = getKicadCompatibleComponentName(sourceComp, cadComponent);
|
|
103368
|
+
if (cadComponent.footprinter_string) {
|
|
103369
|
+
footprinterStrings.set(footprintName, cadComponent.footprinter_string);
|
|
103370
|
+
} else {
|
|
103371
|
+
customFootprintNames.add(footprintName);
|
|
103372
|
+
const pcbComp = this.ctx.circuitJson.find((el) => el.type === "pcb_component" && el.source_component_id === cadComponent.source_component_id);
|
|
103373
|
+
if (pcbComp && pcbComp.type === "pcb_component" && pcbComp.metadata?.kicad_footprint?.footprintName) {
|
|
103374
|
+
customFootprintNames.add(pcbComp.metadata.kicad_footprint.footprintName);
|
|
103375
|
+
}
|
|
103376
|
+
}
|
|
103377
|
+
}
|
|
103378
|
+
return { customFootprintNames, footprinterStrings };
|
|
103379
|
+
}
|
|
103380
|
+
_step() {
|
|
103381
|
+
const kicadPcbString = this.ctx.kicadPcbString;
|
|
103382
|
+
const fpLibraryName = this.ctx.fpLibraryName ?? "tscircuit";
|
|
103383
|
+
if (!kicadPcbString) {
|
|
103384
|
+
throw new Error("PCB content not available. Run GenerateKicadSchAndPcbStage first.");
|
|
103385
|
+
}
|
|
103386
|
+
const { customFootprintNames, footprinterStrings } = this.classifyFootprints();
|
|
103387
|
+
const uniqueFootprints = /* @__PURE__ */ new Map;
|
|
103388
|
+
try {
|
|
103389
|
+
const parsed = parseKicadSexpr(kicadPcbString);
|
|
103390
|
+
const pcb = parsed.find((node) => node instanceof KicadPcb);
|
|
103391
|
+
if (!pcb) {
|
|
103392
|
+
this.ctx.footprintEntries = [];
|
|
103393
|
+
this.finished = true;
|
|
103394
|
+
return;
|
|
103395
|
+
}
|
|
103396
|
+
const footprints = pcb.footprints ?? [];
|
|
103397
|
+
for (const footprint of footprints) {
|
|
103398
|
+
const footprintEntry = this.sanitizeFootprint({
|
|
103399
|
+
footprint,
|
|
103400
|
+
fpLibraryName,
|
|
103401
|
+
customFootprintNames,
|
|
103402
|
+
footprinterStrings
|
|
103403
|
+
});
|
|
103404
|
+
if (!uniqueFootprints.has(footprintEntry.footprintName)) {
|
|
103405
|
+
uniqueFootprints.set(footprintEntry.footprintName, footprintEntry);
|
|
103406
|
+
}
|
|
103407
|
+
}
|
|
103408
|
+
} catch (error) {
|
|
103409
|
+
console.warn("Failed to parse PCB for footprint extraction:", error);
|
|
103410
|
+
}
|
|
103411
|
+
this.ctx.footprintEntries = Array.from(uniqueFootprints.values());
|
|
103412
|
+
this.finished = true;
|
|
103413
|
+
}
|
|
103414
|
+
sanitizeFootprint({
|
|
103415
|
+
footprint,
|
|
103416
|
+
fpLibraryName,
|
|
103417
|
+
customFootprintNames,
|
|
103418
|
+
footprinterStrings
|
|
103419
|
+
}) {
|
|
103420
|
+
const libraryLink = footprint.libraryLink ?? "footprint";
|
|
103421
|
+
const parts = libraryLink.split(":");
|
|
103422
|
+
const footprintName = (parts.length > 1 ? parts[1] : parts[0])?.replace(/[\\\/]/g, "-").trim() || "footprint";
|
|
103423
|
+
const isBuiltin = !customFootprintNames.has(footprintName);
|
|
103424
|
+
footprint.libraryLink = footprintName;
|
|
103425
|
+
footprint.position = At.from([0, 0, 0]);
|
|
103426
|
+
footprint.locked = false;
|
|
103427
|
+
footprint.placed = false;
|
|
103428
|
+
footprint.version = KICAD_FP_VERSION;
|
|
103429
|
+
footprint.generator = KICAD_FP_GENERATOR;
|
|
103430
|
+
footprint.generatorVersion = KICAD_FP_GENERATOR_VERSION;
|
|
103431
|
+
if (!footprint.descr) {
|
|
103432
|
+
footprint.descr = "";
|
|
103433
|
+
}
|
|
103434
|
+
if (!footprint.tags) {
|
|
103435
|
+
footprint.tags = "";
|
|
103436
|
+
}
|
|
103437
|
+
if (!footprint.embeddedFonts) {
|
|
103438
|
+
footprint.embeddedFonts = new EmbeddedFonts4(false);
|
|
103439
|
+
}
|
|
103440
|
+
if (!footprint.attr) {
|
|
103441
|
+
const attr = new FootprintAttr;
|
|
103442
|
+
const padTypes = (footprint.fpPads ?? []).map((pad) => pad.padType);
|
|
103443
|
+
if (padTypes.some((padType) => padType.includes("thru_hole"))) {
|
|
103444
|
+
attr.type = "through_hole";
|
|
103445
|
+
} else if (padTypes.some((padType) => padType.includes("smd"))) {
|
|
103446
|
+
attr.type = "smd";
|
|
103447
|
+
}
|
|
103448
|
+
footprint.attr = attr;
|
|
103449
|
+
}
|
|
103450
|
+
footprint.uuid = undefined;
|
|
103451
|
+
footprint.path = undefined;
|
|
103452
|
+
footprint.sheetfile = undefined;
|
|
103453
|
+
footprint.sheetname = undefined;
|
|
103454
|
+
const defaultFont = new TextEffectsFont6;
|
|
103455
|
+
defaultFont.size = { width: 1.27, height: 1.27 };
|
|
103456
|
+
defaultFont.thickness = 0.15;
|
|
103457
|
+
const defaultEffects = new TextEffects6({ font: defaultFont });
|
|
103458
|
+
const fpPads = footprint.fpPads ?? [];
|
|
103459
|
+
let minY = 0;
|
|
103460
|
+
let maxY = 0;
|
|
103461
|
+
for (const pad of fpPads) {
|
|
103462
|
+
const at = pad.at;
|
|
103463
|
+
const size = pad.size;
|
|
103464
|
+
if (at && size) {
|
|
103465
|
+
const padY = at.y ?? 0;
|
|
103466
|
+
const padHeight = size.height ?? 0;
|
|
103467
|
+
const padTop = padY - padHeight / 2;
|
|
103468
|
+
const padBottom = padY + padHeight / 2;
|
|
103469
|
+
minY = Math.min(minY, padTop);
|
|
103470
|
+
maxY = Math.max(maxY, padBottom);
|
|
103471
|
+
}
|
|
103472
|
+
}
|
|
103473
|
+
const refY = minY - 0.5;
|
|
103474
|
+
const valY = maxY + 0.5;
|
|
103475
|
+
footprint.properties = [
|
|
103476
|
+
new Property({
|
|
103477
|
+
key: "Reference",
|
|
103478
|
+
value: "REF**",
|
|
103479
|
+
position: [0, refY, 0],
|
|
103480
|
+
layer: "F.SilkS",
|
|
103481
|
+
uuid: generateDeterministicUuid(`${footprintName}-property-Reference`),
|
|
103482
|
+
effects: defaultEffects
|
|
103483
|
+
}),
|
|
103484
|
+
new Property({
|
|
103485
|
+
key: "Value",
|
|
103486
|
+
value: "Val**",
|
|
103487
|
+
position: [0, valY, 0],
|
|
103488
|
+
layer: "F.Fab",
|
|
103489
|
+
uuid: generateDeterministicUuid(`${footprintName}-property-Value`),
|
|
103490
|
+
effects: defaultEffects
|
|
103491
|
+
}),
|
|
103492
|
+
new Property({
|
|
103493
|
+
key: "Datasheet",
|
|
103494
|
+
value: "",
|
|
103495
|
+
position: [0, 0, 0],
|
|
103496
|
+
layer: "F.Fab",
|
|
103497
|
+
hidden: true,
|
|
103498
|
+
uuid: generateDeterministicUuid(`${footprintName}-property-Datasheet`),
|
|
103499
|
+
effects: defaultEffects
|
|
103500
|
+
}),
|
|
103501
|
+
new Property({
|
|
103502
|
+
key: "Description",
|
|
103503
|
+
value: "",
|
|
103504
|
+
position: [0, 0, 0],
|
|
103505
|
+
layer: "F.Fab",
|
|
103506
|
+
hidden: true,
|
|
103507
|
+
uuid: generateDeterministicUuid(`${footprintName}-property-Description`),
|
|
103508
|
+
effects: defaultEffects
|
|
103509
|
+
})
|
|
103510
|
+
];
|
|
103511
|
+
const texts = footprint.fpTexts ?? [];
|
|
103512
|
+
for (const text of texts) {
|
|
103513
|
+
text.uuid = undefined;
|
|
103514
|
+
if (text.type === "reference") {
|
|
103515
|
+
text.text = "REF**";
|
|
103516
|
+
} else if (text.type === "value" && text.text.trim().length === 0) {
|
|
103517
|
+
text.text = footprintName;
|
|
103518
|
+
}
|
|
103519
|
+
}
|
|
103520
|
+
footprint.fpTexts = texts;
|
|
103521
|
+
const pads = footprint.fpPads ?? [];
|
|
103522
|
+
for (let i = 0;i < pads.length; i++) {
|
|
103523
|
+
const pad = pads[i];
|
|
103524
|
+
if (pad) {
|
|
103525
|
+
pad.uuid = generateDeterministicUuid(`${footprintName}-pad-${pad.number ?? i}`);
|
|
103526
|
+
pad.net = undefined;
|
|
103527
|
+
}
|
|
103528
|
+
}
|
|
103529
|
+
footprint.fpPads = pads;
|
|
103530
|
+
const models = footprint.models ?? [];
|
|
103531
|
+
const updatedModels = [];
|
|
103532
|
+
const modelFiles = [];
|
|
103533
|
+
for (const model of models) {
|
|
103534
|
+
if (model.path) {
|
|
103535
|
+
const modelFilename = getBasename(model.path);
|
|
103536
|
+
const newPath = `../../3dmodels/${fpLibraryName}.3dshapes/${modelFilename}`;
|
|
103537
|
+
const newModel = new FootprintModel(newPath);
|
|
103538
|
+
if (model.offset)
|
|
103539
|
+
newModel.offset = model.offset;
|
|
103540
|
+
if (model.scale)
|
|
103541
|
+
newModel.scale = model.scale;
|
|
103542
|
+
if (model.rotate)
|
|
103543
|
+
newModel.rotate = model.rotate;
|
|
103544
|
+
updatedModels.push(newModel);
|
|
103545
|
+
modelFiles.push(model.path);
|
|
103546
|
+
}
|
|
103547
|
+
}
|
|
103548
|
+
if (updatedModels.length === 0) {
|
|
103549
|
+
const footprinterString = footprinterStrings.get(footprintName);
|
|
103550
|
+
if (footprinterString) {
|
|
103551
|
+
const cdnUrl = `${MODEL_CDN_BASE_URL}/${footprinterString}.step`;
|
|
103552
|
+
const cdnModelFilename = getBasename(cdnUrl);
|
|
103553
|
+
const newPath = `../../3dmodels/tscircuit_builtin.3dshapes/${cdnModelFilename}`;
|
|
103554
|
+
updatedModels.push(new FootprintModel(newPath));
|
|
103555
|
+
modelFiles.push(cdnUrl);
|
|
103556
|
+
}
|
|
103557
|
+
}
|
|
103558
|
+
footprint.models = updatedModels;
|
|
103559
|
+
return {
|
|
103560
|
+
footprintName,
|
|
103561
|
+
kicadModString: footprint.getString(),
|
|
103562
|
+
model3dSourcePaths: modelFiles,
|
|
103563
|
+
isBuiltin
|
|
103564
|
+
};
|
|
103565
|
+
}
|
|
103566
|
+
getOutput() {
|
|
103567
|
+
return this.ctx.libraryOutput;
|
|
103568
|
+
}
|
|
103569
|
+
};
|
|
103349
103570
|
function createTextEffects2(metadataEffects) {
|
|
103350
|
-
const font = new
|
|
103571
|
+
const font = new TextEffectsFont7;
|
|
103351
103572
|
if (metadataEffects?.font?.size) {
|
|
103352
103573
|
font.size = {
|
|
103353
103574
|
width: Number(metadataEffects.font.size.x),
|
|
@@ -103361,13 +103582,13 @@ function createTextEffects2(metadataEffects) {
|
|
|
103361
103582
|
} else {
|
|
103362
103583
|
font.thickness = 0.15;
|
|
103363
103584
|
}
|
|
103364
|
-
return new
|
|
103585
|
+
return new TextEffects7({ font });
|
|
103365
103586
|
}
|
|
103366
103587
|
function applyMetadataToFootprint(footprint, metadata, componentName) {
|
|
103367
103588
|
if (metadata.properties) {
|
|
103368
103589
|
const newProperties = [];
|
|
103369
103590
|
const refMeta = metadata.properties.Reference;
|
|
103370
|
-
newProperties.push(new
|
|
103591
|
+
newProperties.push(new Property2({
|
|
103371
103592
|
key: "Reference",
|
|
103372
103593
|
value: refMeta?.value ?? componentName,
|
|
103373
103594
|
position: refMeta?.at ? [
|
|
@@ -103382,7 +103603,7 @@ function applyMetadataToFootprint(footprint, metadata, componentName) {
|
|
|
103382
103603
|
}));
|
|
103383
103604
|
const valMeta = metadata.properties.Value;
|
|
103384
103605
|
const valueText = valMeta?.value ?? metadata.footprintName ?? "";
|
|
103385
|
-
newProperties.push(new
|
|
103606
|
+
newProperties.push(new Property2({
|
|
103386
103607
|
key: "Value",
|
|
103387
103608
|
value: valueText,
|
|
103388
103609
|
position: valMeta?.at ? [
|
|
@@ -103396,7 +103617,7 @@ function applyMetadataToFootprint(footprint, metadata, componentName) {
|
|
|
103396
103617
|
hidden: valMeta?.hide
|
|
103397
103618
|
}));
|
|
103398
103619
|
const dsMeta = metadata.properties.Datasheet;
|
|
103399
|
-
newProperties.push(new
|
|
103620
|
+
newProperties.push(new Property2({
|
|
103400
103621
|
key: "Datasheet",
|
|
103401
103622
|
value: dsMeta?.value ?? "",
|
|
103402
103623
|
position: dsMeta?.at ? [
|
|
@@ -103410,7 +103631,7 @@ function applyMetadataToFootprint(footprint, metadata, componentName) {
|
|
|
103410
103631
|
hidden: dsMeta?.hide ?? true
|
|
103411
103632
|
}));
|
|
103412
103633
|
const descMeta = metadata.properties.Description;
|
|
103413
|
-
newProperties.push(new
|
|
103634
|
+
newProperties.push(new Property2({
|
|
103414
103635
|
key: "Description",
|
|
103415
103636
|
value: descMeta?.value ?? "",
|
|
103416
103637
|
position: descMeta?.at ? [
|
|
@@ -103427,7 +103648,7 @@ function applyMetadataToFootprint(footprint, metadata, componentName) {
|
|
|
103427
103648
|
}
|
|
103428
103649
|
if (metadata.attributes) {
|
|
103429
103650
|
if (!footprint.attr) {
|
|
103430
|
-
footprint.attr = new
|
|
103651
|
+
footprint.attr = new FootprintAttr2;
|
|
103431
103652
|
}
|
|
103432
103653
|
if (metadata.attributes.through_hole) {
|
|
103433
103654
|
footprint.attr.type = "through_hole";
|
|
@@ -103448,10 +103669,10 @@ function applyMetadataToFootprint(footprint, metadata, componentName) {
|
|
|
103448
103669
|
footprint.layer = metadata.layer;
|
|
103449
103670
|
}
|
|
103450
103671
|
if (metadata.embeddedFonts !== undefined) {
|
|
103451
|
-
footprint.embeddedFonts = new
|
|
103672
|
+
footprint.embeddedFonts = new EmbeddedFonts5(metadata.embeddedFonts);
|
|
103452
103673
|
}
|
|
103453
103674
|
if (metadata.model) {
|
|
103454
|
-
const model = new
|
|
103675
|
+
const model = new FootprintModel2(metadata.model.path);
|
|
103455
103676
|
if (metadata.model.offset) {
|
|
103456
103677
|
model.offset = {
|
|
103457
103678
|
x: Number(metadata.model.offset.x),
|
|
@@ -103656,9 +103877,9 @@ function createFpTextFromCircuitJson({
|
|
|
103656
103877
|
};
|
|
103657
103878
|
const kicadLayer = layerMap[textElement.layer] || textElement.layer || "F.SilkS";
|
|
103658
103879
|
const fontSize = (textElement.font_size || 1) / 1.5;
|
|
103659
|
-
const font = new
|
|
103880
|
+
const font = new TextEffectsFont8;
|
|
103660
103881
|
font.size = { width: fontSize, height: fontSize };
|
|
103661
|
-
const textEffects = new
|
|
103882
|
+
const textEffects = new TextEffects8({
|
|
103662
103883
|
font
|
|
103663
103884
|
});
|
|
103664
103885
|
const rotation = textElement.ccw_rotation || 0;
|
|
@@ -103699,9 +103920,9 @@ function convertNoteTexts(noteTexts, componentCenter, componentRotation) {
|
|
|
103699
103920
|
const rotationMatrix = componentRotation !== 0 ? rotate2(componentRotation * Math.PI / 180) : identity2();
|
|
103700
103921
|
const rotatedPos = applyToPoint9(rotationMatrix, { x: relX, y: relY });
|
|
103701
103922
|
const fontSize = textElement.font_size || 1;
|
|
103702
|
-
const font = new
|
|
103923
|
+
const font = new TextEffectsFont9;
|
|
103703
103924
|
font.size = { width: fontSize, height: fontSize };
|
|
103704
|
-
const textEffects = new
|
|
103925
|
+
const textEffects = new TextEffects9({ font });
|
|
103705
103926
|
const fpText = new FpText3({
|
|
103706
103927
|
type: "user",
|
|
103707
103928
|
text: textElement.text,
|
|
@@ -103718,7 +103939,7 @@ function create3DModelsFromCadComponent(cadComponent, componentCenter) {
|
|
|
103718
103939
|
const modelUrl = cadComponent.model_step_url || cadComponent.model_wrl_url;
|
|
103719
103940
|
if (!modelUrl)
|
|
103720
103941
|
return models;
|
|
103721
|
-
const model = new
|
|
103942
|
+
const model = new FootprintModel3(modelUrl);
|
|
103722
103943
|
if (cadComponent.position) {
|
|
103723
103944
|
model.offset = {
|
|
103724
103945
|
x: (cadComponent.position.x || 0) - componentCenter.x,
|
|
@@ -104050,6 +104271,7 @@ function convertNpthHoles(pcbHoles, componentCenter, componentRotation) {
|
|
|
104050
104271
|
var AddFootprintsStage = class extends ConverterStage {
|
|
104051
104272
|
componentsProcessed = 0;
|
|
104052
104273
|
pcbComponents = [];
|
|
104274
|
+
includeBuiltin3dModels;
|
|
104053
104275
|
getNetInfoForPcbPort(pcbPortId) {
|
|
104054
104276
|
if (!pcbPortId)
|
|
104055
104277
|
return;
|
|
@@ -104071,9 +104293,10 @@ var AddFootprintsStage = class extends ConverterStage {
|
|
|
104071
104293
|
const cadComponents = this.ctx.db.cad_component?.list() || [];
|
|
104072
104294
|
return cadComponents.find((cad) => cad.pcb_component_id === pcbComponentId);
|
|
104073
104295
|
}
|
|
104074
|
-
constructor(input, ctx) {
|
|
104296
|
+
constructor(input, ctx, options) {
|
|
104075
104297
|
super(input, ctx);
|
|
104076
104298
|
this.pcbComponents = this.ctx.db.pcb_component.list();
|
|
104299
|
+
this.includeBuiltin3dModels = options?.includeBuiltin3dModels ?? false;
|
|
104077
104300
|
}
|
|
104078
104301
|
_step() {
|
|
104079
104302
|
const { kicadPcb, c2kMatPcb } = this.ctx;
|
|
@@ -104096,7 +104319,7 @@ var AddFootprintsStage = class extends ConverterStage {
|
|
|
104096
104319
|
y: component.center.y
|
|
104097
104320
|
});
|
|
104098
104321
|
const footprintData = `footprint:${component.pcb_component_id}:${transformedPos.x},${transformedPos.y}`;
|
|
104099
|
-
const footprint = new
|
|
104322
|
+
const footprint = new Footprint3({
|
|
104100
104323
|
libraryLink: `tscircuit:${footprintName}`,
|
|
104101
104324
|
layer: "F.Cu",
|
|
104102
104325
|
at: [transformedPos.x, transformedPos.y, component.rotation || 0],
|
|
@@ -104141,8 +104364,37 @@ var AddFootprintsStage = class extends ConverterStage {
|
|
|
104141
104364
|
}
|
|
104142
104365
|
if (cadComponent) {
|
|
104143
104366
|
const models = create3DModelsFromCadComponent(cadComponent, component.center);
|
|
104367
|
+
const KICAD_3D_BASE = "${KIPRJMOD}/3dmodels";
|
|
104144
104368
|
if (models.length > 0) {
|
|
104145
|
-
|
|
104369
|
+
if (this.includeBuiltin3dModels) {
|
|
104370
|
+
footprint.models = models.map((model) => {
|
|
104371
|
+
if (!model.path)
|
|
104372
|
+
return model;
|
|
104373
|
+
const filename = getBasename(model.path);
|
|
104374
|
+
const folderName = this.ctx.projectName ?? filename.replace(/\.[^.]+$/, "");
|
|
104375
|
+
const newModel = new FootprintModel4(`${KICAD_3D_BASE}/${folderName}.3dshapes/${filename}`);
|
|
104376
|
+
if (model.offset)
|
|
104377
|
+
newModel.offset = model.offset;
|
|
104378
|
+
if (model.scale)
|
|
104379
|
+
newModel.scale = model.scale;
|
|
104380
|
+
if (model.rotate)
|
|
104381
|
+
newModel.rotate = model.rotate;
|
|
104382
|
+
if (!this.ctx.pcbModel3dSourcePaths?.includes(model.path)) {
|
|
104383
|
+
this.ctx.pcbModel3dSourcePaths?.push(model.path);
|
|
104384
|
+
}
|
|
104385
|
+
return newModel;
|
|
104386
|
+
});
|
|
104387
|
+
} else {
|
|
104388
|
+
footprint.models = models;
|
|
104389
|
+
}
|
|
104390
|
+
} else if (cadComponent.footprinter_string && this.includeBuiltin3dModels) {
|
|
104391
|
+
const { footprinter_string } = cadComponent;
|
|
104392
|
+
const modelPath = `${KICAD_3D_BASE}/tscircuit_builtin.3dshapes/${footprinter_string}.step`;
|
|
104393
|
+
footprint.models = [new FootprintModel4(modelPath)];
|
|
104394
|
+
const cdnUrl = `${MODEL_CDN_BASE_URL}/${footprinter_string}.step`;
|
|
104395
|
+
if (!this.ctx.pcbModel3dSourcePaths?.includes(cdnUrl)) {
|
|
104396
|
+
this.ctx.pcbModel3dSourcePaths?.push(cdnUrl);
|
|
104397
|
+
}
|
|
104146
104398
|
}
|
|
104147
104399
|
}
|
|
104148
104400
|
const footprintMetadata = component.metadata?.kicad_footprint;
|
|
@@ -104371,7 +104623,7 @@ function createFabricationNoteTextFromCircuitJson({
|
|
|
104371
104623
|
};
|
|
104372
104624
|
const kicadLayer = layerMap[textElement.layer] || textElement.layer || "F.Fab";
|
|
104373
104625
|
const fontSize = (textElement.font_size || 1) / 1.5;
|
|
104374
|
-
const font = new
|
|
104626
|
+
const font = new TextEffectsFont10;
|
|
104375
104627
|
font.size = { width: fontSize, height: fontSize };
|
|
104376
104628
|
const justify = new TextEffectsJustify3;
|
|
104377
104629
|
const anchorAlignment = textElement.anchor_alignment || "center";
|
|
@@ -104395,13 +104647,13 @@ function createFabricationNoteTextFromCircuitJson({
|
|
|
104395
104647
|
case "center":
|
|
104396
104648
|
break;
|
|
104397
104649
|
}
|
|
104398
|
-
const textEffects = new
|
|
104650
|
+
const textEffects = new TextEffects10({
|
|
104399
104651
|
font
|
|
104400
104652
|
});
|
|
104401
104653
|
if (anchorAlignment !== "center") {
|
|
104402
104654
|
textEffects.justify = justify;
|
|
104403
104655
|
}
|
|
104404
|
-
const position = new
|
|
104656
|
+
const position = new At2([transformedPos.x, transformedPos.y, 0]);
|
|
104405
104657
|
const grText = new GrText({
|
|
104406
104658
|
text: textElement.text,
|
|
104407
104659
|
layer: kicadLayer,
|
|
@@ -104427,7 +104679,7 @@ function createGrTextFromCircuitJson({
|
|
|
104427
104679
|
};
|
|
104428
104680
|
const kicadLayer = layerMap[textElement.layer] || textElement.layer || "F.SilkS";
|
|
104429
104681
|
const fontSize = (textElement.font_size || 1) / 1.5;
|
|
104430
|
-
const font = new
|
|
104682
|
+
const font = new TextEffectsFont11;
|
|
104431
104683
|
font.size = { width: fontSize, height: fontSize };
|
|
104432
104684
|
const justify = new TextEffectsJustify4;
|
|
104433
104685
|
const anchorAlignment = textElement.anchor_alignment || "center";
|
|
@@ -104451,14 +104703,14 @@ function createGrTextFromCircuitJson({
|
|
|
104451
104703
|
case "center":
|
|
104452
104704
|
break;
|
|
104453
104705
|
}
|
|
104454
|
-
const textEffects = new
|
|
104706
|
+
const textEffects = new TextEffects11({
|
|
104455
104707
|
font
|
|
104456
104708
|
});
|
|
104457
104709
|
if (anchorAlignment !== "center") {
|
|
104458
104710
|
textEffects.justify = justify;
|
|
104459
104711
|
}
|
|
104460
104712
|
const rotation = textElement.ccw_rotation || 0;
|
|
104461
|
-
const position = new
|
|
104713
|
+
const position = new At3([transformedPos.x, transformedPos.y, rotation]);
|
|
104462
104714
|
const grText = new GrText2({
|
|
104463
104715
|
text: textElement.text,
|
|
104464
104716
|
layer: kicadLayer,
|
|
@@ -104584,23 +104836,27 @@ var CircuitJsonToKicadPcbConverter = class {
|
|
|
104584
104836
|
get currentStage() {
|
|
104585
104837
|
return this.pipeline[this.currentStageIndex];
|
|
104586
104838
|
}
|
|
104587
|
-
constructor(circuitJson) {
|
|
104839
|
+
constructor(circuitJson, options) {
|
|
104588
104840
|
const CIRCUIT_JSON_TO_MM_SCALE = 1;
|
|
104589
104841
|
const KICAD_PCB_CENTER_X = 100;
|
|
104590
104842
|
const KICAD_PCB_CENTER_Y = 100;
|
|
104591
104843
|
this.ctx = {
|
|
104592
104844
|
db: cju2(circuitJson),
|
|
104593
104845
|
circuitJson,
|
|
104594
|
-
kicadPcb: new
|
|
104846
|
+
kicadPcb: new KicadPcb2({
|
|
104595
104847
|
generator: "circuit-json-to-kicad",
|
|
104596
104848
|
generatorVersion: "0.0.1"
|
|
104597
104849
|
}),
|
|
104598
|
-
c2kMatPcb: compose4(translate4(KICAD_PCB_CENTER_X, KICAD_PCB_CENTER_Y), scale3(CIRCUIT_JSON_TO_MM_SCALE, -CIRCUIT_JSON_TO_MM_SCALE))
|
|
104850
|
+
c2kMatPcb: compose4(translate4(KICAD_PCB_CENTER_X, KICAD_PCB_CENTER_Y), scale3(CIRCUIT_JSON_TO_MM_SCALE, -CIRCUIT_JSON_TO_MM_SCALE)),
|
|
104851
|
+
projectName: options?.projectName,
|
|
104852
|
+
pcbModel3dSourcePaths: []
|
|
104599
104853
|
};
|
|
104600
104854
|
this.pipeline = [
|
|
104601
104855
|
new InitializePcbStage(circuitJson, this.ctx),
|
|
104602
104856
|
new AddNetsStage(circuitJson, this.ctx),
|
|
104603
|
-
new AddFootprintsStage(circuitJson, this.ctx
|
|
104857
|
+
new AddFootprintsStage(circuitJson, this.ctx, {
|
|
104858
|
+
includeBuiltin3dModels: options?.includeBuiltin3dModels
|
|
104859
|
+
}),
|
|
104604
104860
|
new AddTracesStage(circuitJson, this.ctx),
|
|
104605
104861
|
new AddViasStage(circuitJson, this.ctx),
|
|
104606
104862
|
new AddGraphicsStage(circuitJson, this.ctx)
|
|
@@ -104627,6 +104883,9 @@ var CircuitJsonToKicadPcbConverter = class {
|
|
|
104627
104883
|
getOutputString() {
|
|
104628
104884
|
return this.ctx.kicadPcb.getString();
|
|
104629
104885
|
}
|
|
104886
|
+
getModel3dSourcePaths() {
|
|
104887
|
+
return this.ctx.pcbModel3dSourcePaths ?? [];
|
|
104888
|
+
}
|
|
104630
104889
|
};
|
|
104631
104890
|
var CircuitJsonToKicadProConverter = class {
|
|
104632
104891
|
ctx;
|
|
@@ -104731,7 +104990,7 @@ var ExtractSymbolsStage = class extends ConverterStage {
|
|
|
104731
104990
|
}
|
|
104732
104991
|
const uniqueSymbols = /* @__PURE__ */ new Map;
|
|
104733
104992
|
try {
|
|
104734
|
-
const parsed =
|
|
104993
|
+
const parsed = parseKicadSexpr2(schContent);
|
|
104735
104994
|
const sch = parsed.find((node) => node instanceof KicadSch2);
|
|
104736
104995
|
if (!sch) {
|
|
104737
104996
|
this.ctx.symbolEntries = [];
|
|
@@ -104812,227 +105071,6 @@ var ExtractSymbolsStage = class extends ConverterStage {
|
|
|
104812
105071
|
return this.ctx.libraryOutput;
|
|
104813
105072
|
}
|
|
104814
105073
|
};
|
|
104815
|
-
var MODEL_CDN_BASE_URL = "https://modelcdn.tscircuit.com/jscad_models";
|
|
104816
|
-
var KICAD_FP_VERSION = 20240108;
|
|
104817
|
-
var KICAD_FP_GENERATOR = "pcbnew";
|
|
104818
|
-
var KICAD_FP_GENERATOR_VERSION = "8.0";
|
|
104819
|
-
function getBasename(filePath) {
|
|
104820
|
-
const parts = filePath.split(/[/\\]/);
|
|
104821
|
-
return parts[parts.length - 1] || filePath;
|
|
104822
|
-
}
|
|
104823
|
-
var ExtractFootprintsStage = class extends ConverterStage {
|
|
104824
|
-
classifyFootprints() {
|
|
104825
|
-
const customFootprintNames = /* @__PURE__ */ new Set;
|
|
104826
|
-
const footprinterStrings = /* @__PURE__ */ new Map;
|
|
104827
|
-
const cadComponents = this.ctx.db.cad_component?.list() ?? [];
|
|
104828
|
-
const sourceComponents = this.ctx.db.source_component;
|
|
104829
|
-
for (const cadComponent of cadComponents) {
|
|
104830
|
-
const sourceComp = cadComponent.source_component_id ? sourceComponents?.get(cadComponent.source_component_id) : null;
|
|
104831
|
-
if (!sourceComp)
|
|
104832
|
-
continue;
|
|
104833
|
-
const footprintName = getKicadCompatibleComponentName(sourceComp, cadComponent);
|
|
104834
|
-
if (cadComponent.footprinter_string) {
|
|
104835
|
-
footprinterStrings.set(footprintName, cadComponent.footprinter_string);
|
|
104836
|
-
} else {
|
|
104837
|
-
customFootprintNames.add(footprintName);
|
|
104838
|
-
const pcbComp = this.ctx.circuitJson.find((el) => el.type === "pcb_component" && el.source_component_id === cadComponent.source_component_id);
|
|
104839
|
-
if (pcbComp && pcbComp.type === "pcb_component" && pcbComp.metadata?.kicad_footprint?.footprintName) {
|
|
104840
|
-
customFootprintNames.add(pcbComp.metadata.kicad_footprint.footprintName);
|
|
104841
|
-
}
|
|
104842
|
-
}
|
|
104843
|
-
}
|
|
104844
|
-
return { customFootprintNames, footprinterStrings };
|
|
104845
|
-
}
|
|
104846
|
-
_step() {
|
|
104847
|
-
const kicadPcbString = this.ctx.kicadPcbString;
|
|
104848
|
-
const fpLibraryName = this.ctx.fpLibraryName ?? "tscircuit";
|
|
104849
|
-
if (!kicadPcbString) {
|
|
104850
|
-
throw new Error("PCB content not available. Run GenerateKicadSchAndPcbStage first.");
|
|
104851
|
-
}
|
|
104852
|
-
const { customFootprintNames, footprinterStrings } = this.classifyFootprints();
|
|
104853
|
-
const uniqueFootprints = /* @__PURE__ */ new Map;
|
|
104854
|
-
try {
|
|
104855
|
-
const parsed = parseKicadSexpr2(kicadPcbString);
|
|
104856
|
-
const pcb = parsed.find((node) => node instanceof KicadPcb2);
|
|
104857
|
-
if (!pcb) {
|
|
104858
|
-
this.ctx.footprintEntries = [];
|
|
104859
|
-
this.finished = true;
|
|
104860
|
-
return;
|
|
104861
|
-
}
|
|
104862
|
-
const footprints = pcb.footprints ?? [];
|
|
104863
|
-
for (const footprint of footprints) {
|
|
104864
|
-
const footprintEntry = this.sanitizeFootprint({
|
|
104865
|
-
footprint,
|
|
104866
|
-
fpLibraryName,
|
|
104867
|
-
customFootprintNames,
|
|
104868
|
-
footprinterStrings
|
|
104869
|
-
});
|
|
104870
|
-
if (!uniqueFootprints.has(footprintEntry.footprintName)) {
|
|
104871
|
-
uniqueFootprints.set(footprintEntry.footprintName, footprintEntry);
|
|
104872
|
-
}
|
|
104873
|
-
}
|
|
104874
|
-
} catch (error) {
|
|
104875
|
-
console.warn("Failed to parse PCB for footprint extraction:", error);
|
|
104876
|
-
}
|
|
104877
|
-
this.ctx.footprintEntries = Array.from(uniqueFootprints.values());
|
|
104878
|
-
this.finished = true;
|
|
104879
|
-
}
|
|
104880
|
-
sanitizeFootprint({
|
|
104881
|
-
footprint,
|
|
104882
|
-
fpLibraryName,
|
|
104883
|
-
customFootprintNames,
|
|
104884
|
-
footprinterStrings
|
|
104885
|
-
}) {
|
|
104886
|
-
const libraryLink = footprint.libraryLink ?? "footprint";
|
|
104887
|
-
const parts = libraryLink.split(":");
|
|
104888
|
-
const footprintName = (parts.length > 1 ? parts[1] : parts[0])?.replace(/[\\\/]/g, "-").trim() || "footprint";
|
|
104889
|
-
const isBuiltin = !customFootprintNames.has(footprintName);
|
|
104890
|
-
footprint.libraryLink = footprintName;
|
|
104891
|
-
footprint.position = At3.from([0, 0, 0]);
|
|
104892
|
-
footprint.locked = false;
|
|
104893
|
-
footprint.placed = false;
|
|
104894
|
-
footprint.version = KICAD_FP_VERSION;
|
|
104895
|
-
footprint.generator = KICAD_FP_GENERATOR;
|
|
104896
|
-
footprint.generatorVersion = KICAD_FP_GENERATOR_VERSION;
|
|
104897
|
-
if (!footprint.descr) {
|
|
104898
|
-
footprint.descr = "";
|
|
104899
|
-
}
|
|
104900
|
-
if (!footprint.tags) {
|
|
104901
|
-
footprint.tags = "";
|
|
104902
|
-
}
|
|
104903
|
-
if (!footprint.embeddedFonts) {
|
|
104904
|
-
footprint.embeddedFonts = new EmbeddedFonts5(false);
|
|
104905
|
-
}
|
|
104906
|
-
if (!footprint.attr) {
|
|
104907
|
-
const attr = new FootprintAttr2;
|
|
104908
|
-
const padTypes = (footprint.fpPads ?? []).map((pad) => pad.padType);
|
|
104909
|
-
if (padTypes.some((padType) => padType.includes("thru_hole"))) {
|
|
104910
|
-
attr.type = "through_hole";
|
|
104911
|
-
} else if (padTypes.some((padType) => padType.includes("smd"))) {
|
|
104912
|
-
attr.type = "smd";
|
|
104913
|
-
}
|
|
104914
|
-
footprint.attr = attr;
|
|
104915
|
-
}
|
|
104916
|
-
footprint.uuid = undefined;
|
|
104917
|
-
footprint.path = undefined;
|
|
104918
|
-
footprint.sheetfile = undefined;
|
|
104919
|
-
footprint.sheetname = undefined;
|
|
104920
|
-
const defaultFont = new TextEffectsFont11;
|
|
104921
|
-
defaultFont.size = { width: 1.27, height: 1.27 };
|
|
104922
|
-
defaultFont.thickness = 0.15;
|
|
104923
|
-
const defaultEffects = new TextEffects11({ font: defaultFont });
|
|
104924
|
-
const fpPads = footprint.fpPads ?? [];
|
|
104925
|
-
let minY = 0;
|
|
104926
|
-
let maxY = 0;
|
|
104927
|
-
for (const pad of fpPads) {
|
|
104928
|
-
const at = pad.at;
|
|
104929
|
-
const size = pad.size;
|
|
104930
|
-
if (at && size) {
|
|
104931
|
-
const padY = at.y ?? 0;
|
|
104932
|
-
const padHeight = size.height ?? 0;
|
|
104933
|
-
const padTop = padY - padHeight / 2;
|
|
104934
|
-
const padBottom = padY + padHeight / 2;
|
|
104935
|
-
minY = Math.min(minY, padTop);
|
|
104936
|
-
maxY = Math.max(maxY, padBottom);
|
|
104937
|
-
}
|
|
104938
|
-
}
|
|
104939
|
-
const refY = minY - 0.5;
|
|
104940
|
-
const valY = maxY + 0.5;
|
|
104941
|
-
footprint.properties = [
|
|
104942
|
-
new Property2({
|
|
104943
|
-
key: "Reference",
|
|
104944
|
-
value: "REF**",
|
|
104945
|
-
position: [0, refY, 0],
|
|
104946
|
-
layer: "F.SilkS",
|
|
104947
|
-
uuid: generateDeterministicUuid(`${footprintName}-property-Reference`),
|
|
104948
|
-
effects: defaultEffects
|
|
104949
|
-
}),
|
|
104950
|
-
new Property2({
|
|
104951
|
-
key: "Value",
|
|
104952
|
-
value: "Val**",
|
|
104953
|
-
position: [0, valY, 0],
|
|
104954
|
-
layer: "F.Fab",
|
|
104955
|
-
uuid: generateDeterministicUuid(`${footprintName}-property-Value`),
|
|
104956
|
-
effects: defaultEffects
|
|
104957
|
-
}),
|
|
104958
|
-
new Property2({
|
|
104959
|
-
key: "Datasheet",
|
|
104960
|
-
value: "",
|
|
104961
|
-
position: [0, 0, 0],
|
|
104962
|
-
layer: "F.Fab",
|
|
104963
|
-
hidden: true,
|
|
104964
|
-
uuid: generateDeterministicUuid(`${footprintName}-property-Datasheet`),
|
|
104965
|
-
effects: defaultEffects
|
|
104966
|
-
}),
|
|
104967
|
-
new Property2({
|
|
104968
|
-
key: "Description",
|
|
104969
|
-
value: "",
|
|
104970
|
-
position: [0, 0, 0],
|
|
104971
|
-
layer: "F.Fab",
|
|
104972
|
-
hidden: true,
|
|
104973
|
-
uuid: generateDeterministicUuid(`${footprintName}-property-Description`),
|
|
104974
|
-
effects: defaultEffects
|
|
104975
|
-
})
|
|
104976
|
-
];
|
|
104977
|
-
const texts = footprint.fpTexts ?? [];
|
|
104978
|
-
for (const text of texts) {
|
|
104979
|
-
text.uuid = undefined;
|
|
104980
|
-
if (text.type === "reference") {
|
|
104981
|
-
text.text = "REF**";
|
|
104982
|
-
} else if (text.type === "value" && text.text.trim().length === 0) {
|
|
104983
|
-
text.text = footprintName;
|
|
104984
|
-
}
|
|
104985
|
-
}
|
|
104986
|
-
footprint.fpTexts = texts;
|
|
104987
|
-
const pads = footprint.fpPads ?? [];
|
|
104988
|
-
for (let i = 0;i < pads.length; i++) {
|
|
104989
|
-
const pad = pads[i];
|
|
104990
|
-
if (pad) {
|
|
104991
|
-
pad.uuid = generateDeterministicUuid(`${footprintName}-pad-${pad.number ?? i}`);
|
|
104992
|
-
pad.net = undefined;
|
|
104993
|
-
}
|
|
104994
|
-
}
|
|
104995
|
-
footprint.fpPads = pads;
|
|
104996
|
-
const models = footprint.models ?? [];
|
|
104997
|
-
const updatedModels = [];
|
|
104998
|
-
const modelFiles = [];
|
|
104999
|
-
for (const model of models) {
|
|
105000
|
-
if (model.path) {
|
|
105001
|
-
const modelFilename = getBasename(model.path);
|
|
105002
|
-
const newPath = `../../3dmodels/${fpLibraryName}.3dshapes/${modelFilename}`;
|
|
105003
|
-
const newModel = new FootprintModel3(newPath);
|
|
105004
|
-
if (model.offset)
|
|
105005
|
-
newModel.offset = model.offset;
|
|
105006
|
-
if (model.scale)
|
|
105007
|
-
newModel.scale = model.scale;
|
|
105008
|
-
if (model.rotate)
|
|
105009
|
-
newModel.rotate = model.rotate;
|
|
105010
|
-
updatedModels.push(newModel);
|
|
105011
|
-
modelFiles.push(model.path);
|
|
105012
|
-
}
|
|
105013
|
-
}
|
|
105014
|
-
if (updatedModels.length === 0) {
|
|
105015
|
-
const footprinterString = footprinterStrings.get(footprintName);
|
|
105016
|
-
if (footprinterString) {
|
|
105017
|
-
const cdnUrl = `${MODEL_CDN_BASE_URL}/${footprinterString}.step`;
|
|
105018
|
-
const cdnModelFilename = getBasename(cdnUrl);
|
|
105019
|
-
const newPath = `../../3dmodels/tscircuit_builtin.3dshapes/${cdnModelFilename}`;
|
|
105020
|
-
updatedModels.push(new FootprintModel3(newPath));
|
|
105021
|
-
modelFiles.push(cdnUrl);
|
|
105022
|
-
}
|
|
105023
|
-
}
|
|
105024
|
-
footprint.models = updatedModels;
|
|
105025
|
-
return {
|
|
105026
|
-
footprintName,
|
|
105027
|
-
kicadModString: footprint.getString(),
|
|
105028
|
-
model3dSourcePaths: modelFiles,
|
|
105029
|
-
isBuiltin
|
|
105030
|
-
};
|
|
105031
|
-
}
|
|
105032
|
-
getOutput() {
|
|
105033
|
-
return this.ctx.libraryOutput;
|
|
105034
|
-
}
|
|
105035
|
-
};
|
|
105036
105074
|
var KICAD_SYM_LIB_VERSION = 20211014;
|
|
105037
105075
|
var GENERATOR = "circuit-json-to-kicad";
|
|
105038
105076
|
var GenerateSymbolLibraryStage = class extends ConverterStage {
|
|
@@ -116291,7 +116329,10 @@ var exportSnippet = async ({
|
|
|
116291
116329
|
case "kicad_zip": {
|
|
116292
116330
|
const schConverter = new CircuitJsonToKicadSchConverter(circuitJson);
|
|
116293
116331
|
schConverter.runUntilFinished();
|
|
116294
|
-
const pcbConverter = new CircuitJsonToKicadPcbConverter(circuitJson
|
|
116332
|
+
const pcbConverter = new CircuitJsonToKicadPcbConverter(circuitJson, {
|
|
116333
|
+
includeBuiltin3dModels: true,
|
|
116334
|
+
projectName: outputBaseName
|
|
116335
|
+
});
|
|
116295
116336
|
pcbConverter.runUntilFinished();
|
|
116296
116337
|
const proConverter = new CircuitJsonToKicadProConverter(circuitJson, {
|
|
116297
116338
|
projectName: outputBaseName,
|
|
@@ -116303,6 +116344,29 @@ var exportSnippet = async ({
|
|
|
116303
116344
|
zip.file(`${outputBaseName}.kicad_sch`, schConverter.getOutputString());
|
|
116304
116345
|
zip.file(`${outputBaseName}.kicad_pcb`, pcbConverter.getOutputString());
|
|
116305
116346
|
zip.file(`${outputBaseName}.kicad_pro`, proConverter.getOutputString());
|
|
116347
|
+
const platformFetch = platformConfig?.platformFetch ?? globalThis.fetch;
|
|
116348
|
+
for (const modelPath of pcbConverter.getModel3dSourcePaths()) {
|
|
116349
|
+
const fileName = path56.basename(modelPath);
|
|
116350
|
+
const isRemote = modelPath.startsWith("http://") || modelPath.startsWith("https://");
|
|
116351
|
+
const shapesDir = isRemote ? "tscircuit_builtin.3dshapes" : `${outputBaseName}.3dshapes`;
|
|
116352
|
+
const zipPath = `3dmodels/${shapesDir}/${fileName}`;
|
|
116353
|
+
if (isRemote) {
|
|
116354
|
+
try {
|
|
116355
|
+
const response = await platformFetch(modelPath);
|
|
116356
|
+
if (response.ok) {
|
|
116357
|
+
const buffer = Buffer.from(await response.arrayBuffer());
|
|
116358
|
+
zip.file(zipPath, buffer);
|
|
116359
|
+
}
|
|
116360
|
+
} catch (error) {
|
|
116361
|
+
console.log(`Failed to fetch 3D model from ${modelPath}`);
|
|
116362
|
+
}
|
|
116363
|
+
} else {
|
|
116364
|
+
const resolvedPath = path56.resolve(projectDir, modelPath);
|
|
116365
|
+
if (fs52.existsSync(resolvedPath)) {
|
|
116366
|
+
zip.file(zipPath, await fs52.promises.readFile(resolvedPath));
|
|
116367
|
+
}
|
|
116368
|
+
}
|
|
116369
|
+
}
|
|
116306
116370
|
outputContent = await zip.generateAsync({ type: "nodebuffer" });
|
|
116307
116371
|
break;
|
|
116308
116372
|
}
|