@tscircuit/cli 0.1.2434 → 0.1.2436
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/build/build.worker.js +20 -2
- package/dist/cli/main.js +2 -2
- package/dist/cli/snapshot/snapshot.worker.js +18 -0
- package/dist/lib/index.js +636 -253
- package/package.json +5 -2
package/dist/lib/index.js
CHANGED
|
@@ -3,6 +3,7 @@ var __create3 = Object.create;
|
|
|
3
3
|
var __getProtoOf3 = Object.getPrototypeOf;
|
|
4
4
|
var __defProp3 = Object.defineProperty;
|
|
5
5
|
var __getOwnPropNames3 = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropDesc3 = Object.getOwnPropertyDescriptor;
|
|
6
7
|
var __hasOwnProp3 = Object.prototype.hasOwnProperty;
|
|
7
8
|
function __accessProp(key) {
|
|
8
9
|
return this[key];
|
|
@@ -31,6 +32,23 @@ var __toESM3 = (mod, isNodeMode, target) => {
|
|
|
31
32
|
cache.set(mod, to);
|
|
32
33
|
return to;
|
|
33
34
|
};
|
|
35
|
+
var __toCommonJS3 = (from) => {
|
|
36
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
37
|
+
if (entry)
|
|
38
|
+
return entry;
|
|
39
|
+
entry = __defProp3({}, "__esModule", { value: true });
|
|
40
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
41
|
+
for (var key of __getOwnPropNames3(from))
|
|
42
|
+
if (!__hasOwnProp3.call(entry, key))
|
|
43
|
+
__defProp3(entry, key, {
|
|
44
|
+
get: __accessProp.bind(from, key),
|
|
45
|
+
enumerable: !(desc = __getOwnPropDesc3(from, key)) || desc.enumerable
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
__moduleCache.set(from, entry);
|
|
49
|
+
return entry;
|
|
50
|
+
};
|
|
51
|
+
var __moduleCache;
|
|
34
52
|
var __commonJS2 = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
35
53
|
var __returnValue = (v) => v;
|
|
36
54
|
function __exportSetter(name, newValue) {
|
|
@@ -74334,6 +74352,7 @@ import {
|
|
|
74334
74352
|
} from "kicadts";
|
|
74335
74353
|
import { applyToPoint as applyToPoint6 } from "transformation-matrix";
|
|
74336
74354
|
import { symbols as symbols4 } from "schematic-symbols";
|
|
74355
|
+
import { NoConnect } from "kicadts";
|
|
74337
74356
|
import { formatSiUnit } from "format-si-unit";
|
|
74338
74357
|
import {
|
|
74339
74358
|
EmbeddedFonts as EmbeddedFonts2,
|
|
@@ -74362,11 +74381,11 @@ import {
|
|
|
74362
74381
|
import { Paper, Uuid as Uuid4 } from "kicadts";
|
|
74363
74382
|
import { KicadPcb as KicadPcb2 } from "kicadts";
|
|
74364
74383
|
import { cju as cju2 } from "@tscircuit/circuit-json-util";
|
|
74365
|
-
import { compose as
|
|
74384
|
+
import { compose as compose11, translate as translate11, scale as scale8 } from "transformation-matrix";
|
|
74366
74385
|
import {
|
|
74367
74386
|
Layer,
|
|
74368
|
-
Pts as
|
|
74369
|
-
Xy as
|
|
74387
|
+
Pts as Pts5,
|
|
74388
|
+
Xy as Xy5,
|
|
74370
74389
|
Zone,
|
|
74371
74390
|
ZoneConnectPads,
|
|
74372
74391
|
ZoneFill,
|
|
@@ -74375,13 +74394,16 @@ import {
|
|
|
74375
74394
|
ZonePolygon
|
|
74376
74395
|
} from "kicadts";
|
|
74377
74396
|
import {
|
|
74378
|
-
applyToPoint as
|
|
74379
|
-
compose as
|
|
74397
|
+
applyToPoint as applyToPoint10,
|
|
74398
|
+
compose as compose4,
|
|
74380
74399
|
rotate,
|
|
74381
|
-
translate as
|
|
74400
|
+
translate as translate4
|
|
74382
74401
|
} from "transformation-matrix";
|
|
74383
|
-
import {
|
|
74384
|
-
import { applyToPoint as
|
|
74402
|
+
import { PadPrimitiveGrPoly, PadPrimitives, Pts as Pts4, Xy as Xy4 } from "kicadts";
|
|
74403
|
+
import { applyToPoint as applyToPoint9, compose as compose3, scale as scale2, translate as translate3 } from "transformation-matrix";
|
|
74404
|
+
import { Pts as Pts6, Xy as Xy6, Zone as Zone2, ZoneKeepout, ZonePolygon as ZonePolygon2 } from "kicadts";
|
|
74405
|
+
import { applyToPoint as applyToPoint11 } from "transformation-matrix";
|
|
74406
|
+
var import_polygon_clipping = __toESM3(require_polygon_clipping_cjs(), 1);
|
|
74385
74407
|
import {
|
|
74386
74408
|
Paper as Paper2,
|
|
74387
74409
|
PcbLayers,
|
|
@@ -74389,10 +74411,9 @@ import {
|
|
|
74389
74411
|
PcbGeneral,
|
|
74390
74412
|
Setup
|
|
74391
74413
|
} from "kicadts";
|
|
74392
|
-
import { getElementId } from "@tscircuit/circuit-json-util";
|
|
74414
|
+
import { createBoardOwnerMap, getElementId } from "@tscircuit/circuit-json-util";
|
|
74393
74415
|
import { getFullConnectivityMapFromCircuitJson } from "circuit-json-to-connectivity-map";
|
|
74394
74416
|
import { PcbNet } from "kicadts";
|
|
74395
|
-
var import_polygon_clipping = __toESM3(require_polygon_clipping_cjs(), 1);
|
|
74396
74417
|
import { Footprint as Footprint4, FootprintModel as FootprintModel4, FootprintAttr as FootprintAttr3 } from "kicadts";
|
|
74397
74418
|
import {
|
|
74398
74419
|
parseKicadSexpr,
|
|
@@ -74405,7 +74426,7 @@ import {
|
|
|
74405
74426
|
TextEffectsFont as TextEffectsFont8
|
|
74406
74427
|
} from "kicadts";
|
|
74407
74428
|
import { FootprintAttr } from "kicadts";
|
|
74408
|
-
import { applyToPoint as
|
|
74429
|
+
import { applyToPoint as applyToPoint26 } from "transformation-matrix";
|
|
74409
74430
|
import {
|
|
74410
74431
|
Property as Property2,
|
|
74411
74432
|
TextEffects as TextEffects9,
|
|
@@ -74415,80 +74436,74 @@ import {
|
|
|
74415
74436
|
FootprintAttr as FootprintAttr2
|
|
74416
74437
|
} from "kicadts";
|
|
74417
74438
|
import { FpCircle, Stroke as Stroke5 } from "kicadts";
|
|
74418
|
-
import { applyToPoint as
|
|
74439
|
+
import { applyToPoint as applyToPoint12, identity, rotate as rotate2 } from "transformation-matrix";
|
|
74419
74440
|
import { FpCircle as FpCircle2, Stroke as Stroke6 } from "kicadts";
|
|
74420
|
-
import { applyToPoint as
|
|
74421
|
-
import { compose as
|
|
74441
|
+
import { applyToPoint as applyToPoint13 } from "transformation-matrix";
|
|
74442
|
+
import { compose as compose5, rotateDEG, scale as scale3, translate as translate5 } from "transformation-matrix";
|
|
74422
74443
|
import { FpRect as FpRect2 } from "kicadts";
|
|
74423
74444
|
import { FpPoly, FpRect, Stroke as Stroke7 } from "kicadts";
|
|
74424
|
-
import { applyToPoint as
|
|
74445
|
+
import { applyToPoint as applyToPoint14, compose as compose6, translate as translate6 } from "transformation-matrix";
|
|
74425
74446
|
import { FpRect as FpRect3 } from "kicadts";
|
|
74426
74447
|
import { FpPoly as FpPoly4, FpRect as FpRect4, Stroke as Stroke8 } from "kicadts";
|
|
74427
|
-
import {
|
|
74428
|
-
applyToPoint as applyToPoint14,
|
|
74429
|
-
compose as compose6,
|
|
74430
|
-
rotate as rotate3,
|
|
74431
|
-
scale as scale3,
|
|
74432
|
-
translate as translate6
|
|
74433
|
-
} from "transformation-matrix";
|
|
74434
|
-
import { FpPoly as FpPoly5, Pts as Pts6, Stroke as Stroke9, Xy as Xy6 } from "kicadts";
|
|
74435
74448
|
import {
|
|
74436
74449
|
applyToPoint as applyToPoint15,
|
|
74437
74450
|
compose as compose7,
|
|
74438
|
-
rotate as
|
|
74451
|
+
rotate as rotate3,
|
|
74439
74452
|
scale as scale4,
|
|
74440
74453
|
translate as translate7
|
|
74441
74454
|
} from "transformation-matrix";
|
|
74455
|
+
import { FpPoly as FpPoly5, Pts as Pts7, Stroke as Stroke9, Xy as Xy7 } from "kicadts";
|
|
74456
|
+
import {
|
|
74457
|
+
applyToPoint as applyToPoint16,
|
|
74458
|
+
compose as compose8,
|
|
74459
|
+
rotate as rotate4,
|
|
74460
|
+
scale as scale5,
|
|
74461
|
+
translate as translate8
|
|
74462
|
+
} from "transformation-matrix";
|
|
74442
74463
|
import"kicadts";
|
|
74443
74464
|
import { FpText, TextEffects as TextEffects10, TextEffectsFont as TextEffectsFont10 } from "kicadts";
|
|
74444
|
-
import { applyToPoint as
|
|
74465
|
+
import { applyToPoint as applyToPoint17, rotate as rotate5, identity as identity2 } from "transformation-matrix";
|
|
74445
74466
|
import { TextEffectsJustify as TextEffectsJustify6 } from "kicadts";
|
|
74446
74467
|
import { FpLine, Stroke as Stroke10 } from "kicadts";
|
|
74447
|
-
import { applyToPoint as
|
|
74468
|
+
import { applyToPoint as applyToPoint18, identity as identity3, rotate as rotate6 } from "transformation-matrix";
|
|
74448
74469
|
import { FpPoly as FpPoly6, Stroke as Stroke11 } from "kicadts";
|
|
74449
74470
|
import {
|
|
74450
|
-
applyToPoint as
|
|
74451
|
-
compose as
|
|
74471
|
+
applyToPoint as applyToPoint19,
|
|
74472
|
+
compose as compose9,
|
|
74452
74473
|
rotate as rotate7,
|
|
74453
|
-
scale as
|
|
74454
|
-
translate as
|
|
74474
|
+
scale as scale6,
|
|
74475
|
+
translate as translate9
|
|
74455
74476
|
} from "transformation-matrix";
|
|
74456
74477
|
import { FpText as FpText3, TextEffects as TextEffects11, TextEffectsFont as TextEffectsFont11 } from "kicadts";
|
|
74457
|
-
import { applyToPoint as
|
|
74478
|
+
import { applyToPoint as applyToPoint20, rotate as rotate8, identity as identity4 } from "transformation-matrix";
|
|
74458
74479
|
import { FootprintModel as FootprintModel3 } from "kicadts";
|
|
74480
|
+
import { FootprintPad, PadNet, PadOptions } from "kicadts";
|
|
74459
74481
|
import {
|
|
74460
|
-
|
|
74461
|
-
|
|
74462
|
-
|
|
74463
|
-
|
|
74464
|
-
|
|
74465
|
-
PadOptions,
|
|
74466
|
-
PadNet
|
|
74467
|
-
} from "kicadts";
|
|
74468
|
-
import {
|
|
74469
|
-
applyToPoint as applyToPoint20,
|
|
74470
|
-
compose as compose9,
|
|
74471
|
-
translate as translate9,
|
|
74472
|
-
scale as scale6,
|
|
74473
|
-
rotate as rotate9
|
|
74482
|
+
applyToPoint as applyToPoint21,
|
|
74483
|
+
compose as compose10,
|
|
74484
|
+
rotate as rotate9,
|
|
74485
|
+
scale as scale7,
|
|
74486
|
+
translate as translate10
|
|
74474
74487
|
} from "transformation-matrix";
|
|
74475
74488
|
import { FootprintPad as FootprintPad2, PadDrill, PadNet as PadNet2 } from "kicadts";
|
|
74476
|
-
import { applyToPoint as
|
|
74489
|
+
import { applyToPoint as applyToPoint22, rotate as rotate10, identity as identity5 } from "transformation-matrix";
|
|
74477
74490
|
import { FootprintPad as FootprintPad3, PadDrill as PadDrill2 } from "kicadts";
|
|
74478
|
-
import { applyToPoint as
|
|
74491
|
+
import { applyToPoint as applyToPoint23, rotate as rotate11, identity as identity6 } from "transformation-matrix";
|
|
74479
74492
|
import { FpLine as FpLine2, Stroke as Stroke12 } from "kicadts";
|
|
74480
|
-
import { applyToPoint as
|
|
74481
|
-
import {
|
|
74493
|
+
import { applyToPoint as applyToPoint24, identity as identity7, rotate as rotate12 } from "transformation-matrix";
|
|
74494
|
+
import { FootprintPad as FootprintPad4, PadOptions as PadOptions2 } from "kicadts";
|
|
74482
74495
|
import { applyToPoint as applyToPoint25 } from "transformation-matrix";
|
|
74496
|
+
import { Segment, SegmentNet } from "kicadts";
|
|
74497
|
+
import { applyToPoint as applyToPoint27 } from "transformation-matrix";
|
|
74483
74498
|
import {
|
|
74484
|
-
createBoardOwnerMap,
|
|
74499
|
+
createBoardOwnerMap as createBoardOwnerMap2,
|
|
74485
74500
|
isRouteViaCoveredByPhysicalVia
|
|
74486
74501
|
} from "@tscircuit/circuit-json-util";
|
|
74487
74502
|
import { Via, ViaNet } from "kicadts";
|
|
74488
|
-
import { applyToPoint as
|
|
74503
|
+
import { applyToPoint as applyToPoint28 } from "transformation-matrix";
|
|
74489
74504
|
import { ViaTenting } from "kicadts";
|
|
74490
74505
|
import { Footprint as Footprint5 } from "kicadts";
|
|
74491
|
-
import { applyToPoint as
|
|
74506
|
+
import { applyToPoint as applyToPoint29 } from "transformation-matrix";
|
|
74492
74507
|
import { GrLine } from "kicadts";
|
|
74493
74508
|
import {
|
|
74494
74509
|
At as At3,
|
|
@@ -74497,11 +74512,11 @@ import {
|
|
|
74497
74512
|
TextEffectsFont as TextEffectsFont12,
|
|
74498
74513
|
TextEffectsJustify as TextEffectsJustify7
|
|
74499
74514
|
} from "kicadts";
|
|
74500
|
-
import { applyToPoint as
|
|
74501
|
-
import { applyToPoint as
|
|
74515
|
+
import { applyToPoint as applyToPoint30 } from "transformation-matrix";
|
|
74516
|
+
import { applyToPoint as applyToPoint32, rotate as rotate13 } from "transformation-matrix";
|
|
74502
74517
|
import { GrText as GrText2, TextEffects as TextEffects13, TextEffectsFont as TextEffectsFont13, At as At4 } from "kicadts";
|
|
74503
|
-
import { applyToPoint as
|
|
74504
|
-
import { cju as cju3 } from "@tscircuit/circuit-json-util";
|
|
74518
|
+
import { applyToPoint as applyToPoint31 } from "transformation-matrix";
|
|
74519
|
+
import { cju as cju3, createBoardOwnerMap as createBoardOwnerMap3 } from "@tscircuit/circuit-json-util";
|
|
74505
74520
|
import { cju as cju4 } from "@tscircuit/circuit-json-util";
|
|
74506
74521
|
import { parseKicadSexpr as parseKicadSexpr2, KicadSch as KicadSch2 } from "kicadts";
|
|
74507
74522
|
import { KicadSymbolLib } from "kicadts";
|
|
@@ -75270,7 +75285,7 @@ function transformSchematicPoint(transform, point) {
|
|
|
75270
75285
|
function createArcFromPrimitive({
|
|
75271
75286
|
primitive,
|
|
75272
75287
|
transform,
|
|
75273
|
-
scale:
|
|
75288
|
+
scale: scale9
|
|
75274
75289
|
}) {
|
|
75275
75290
|
const start = transformSchematicPoint(transform, primitive.start);
|
|
75276
75291
|
const mid = transformSchematicPoint(transform, primitive.mid);
|
|
@@ -75283,7 +75298,7 @@ function createArcFromPrimitive({
|
|
|
75283
75298
|
"stroke",
|
|
75284
75299
|
[
|
|
75285
75300
|
"width",
|
|
75286
|
-
roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth *
|
|
75301
|
+
roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth * scale9)
|
|
75287
75302
|
],
|
|
75288
75303
|
["type", primitive.isDashed ? "dash" : "default"]
|
|
75289
75304
|
],
|
|
@@ -75339,7 +75354,7 @@ function createSymbolFillSexprPrimitives({
|
|
|
75339
75354
|
function createCircleFromPrimitive({
|
|
75340
75355
|
primitive,
|
|
75341
75356
|
transform,
|
|
75342
|
-
scale:
|
|
75357
|
+
scale: scale9
|
|
75343
75358
|
}) {
|
|
75344
75359
|
const scaledPos = transformSchematicPoint(transform, {
|
|
75345
75360
|
x: primitive.x,
|
|
@@ -75347,12 +75362,12 @@ function createCircleFromPrimitive({
|
|
|
75347
75362
|
});
|
|
75348
75363
|
return SymbolCircle.fromSexprPrimitives([
|
|
75349
75364
|
["center", scaledPos.x, scaledPos.y],
|
|
75350
|
-
["radius", roundSchematicCoordinate(primitive.radius *
|
|
75365
|
+
["radius", roundSchematicCoordinate(primitive.radius * scale9)],
|
|
75351
75366
|
[
|
|
75352
75367
|
"stroke",
|
|
75353
75368
|
[
|
|
75354
75369
|
"width",
|
|
75355
|
-
roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth *
|
|
75370
|
+
roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth * scale9)
|
|
75356
75371
|
],
|
|
75357
75372
|
["type", "default"]
|
|
75358
75373
|
],
|
|
@@ -75374,7 +75389,7 @@ function createPolylineFromPoints({
|
|
|
75374
75389
|
fallbackFillType,
|
|
75375
75390
|
strokeWidth,
|
|
75376
75391
|
isDashed,
|
|
75377
|
-
scale:
|
|
75392
|
+
scale: scale9
|
|
75378
75393
|
}) {
|
|
75379
75394
|
const polyline = new SymbolPolyline;
|
|
75380
75395
|
const xyPoints = points.map((p) => {
|
|
@@ -75384,7 +75399,7 @@ function createPolylineFromPoints({
|
|
|
75384
75399
|
const pts = new Pts(xyPoints);
|
|
75385
75400
|
polyline.points = pts;
|
|
75386
75401
|
const stroke = new Stroke2;
|
|
75387
|
-
stroke.width = roundSchematicCoordinate(strokeWidth == null ? 0.254 : strokeWidth *
|
|
75402
|
+
stroke.width = roundSchematicCoordinate(strokeWidth == null ? 0.254 : strokeWidth * scale9);
|
|
75388
75403
|
stroke.type = isDashed ? "dash" : "default";
|
|
75389
75404
|
polyline.stroke = stroke;
|
|
75390
75405
|
const fill = SymbolPolylineFill.fromSexprPrimitives(createSymbolFillSexprPrimitives({
|
|
@@ -75398,7 +75413,7 @@ function createPolylineFromPoints({
|
|
|
75398
75413
|
function createRectangleFromPrimitive({
|
|
75399
75414
|
primitive,
|
|
75400
75415
|
transform,
|
|
75401
|
-
scale:
|
|
75416
|
+
scale: scale9
|
|
75402
75417
|
}) {
|
|
75403
75418
|
const start = transformSchematicPoint(transform, primitive.start);
|
|
75404
75419
|
const end = transformSchematicPoint(transform, primitive.end);
|
|
@@ -75409,7 +75424,7 @@ function createRectangleFromPrimitive({
|
|
|
75409
75424
|
"stroke",
|
|
75410
75425
|
[
|
|
75411
75426
|
"width",
|
|
75412
|
-
roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth *
|
|
75427
|
+
roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth * scale9)
|
|
75413
75428
|
],
|
|
75414
75429
|
["type", primitive.isDashed ? "dash" : "default"]
|
|
75415
75430
|
],
|
|
@@ -75425,7 +75440,7 @@ function createRectangleFromPrimitive({
|
|
|
75425
75440
|
function createTextFromPrimitive({
|
|
75426
75441
|
schText,
|
|
75427
75442
|
transform,
|
|
75428
|
-
scale:
|
|
75443
|
+
scale: scale9
|
|
75429
75444
|
}) {
|
|
75430
75445
|
const symbolText = new SymbolText;
|
|
75431
75446
|
const scaledPos = transformSchematicPoint(transform, {
|
|
@@ -75434,7 +75449,7 @@ function createTextFromPrimitive({
|
|
|
75434
75449
|
});
|
|
75435
75450
|
symbolText.value = schText.text;
|
|
75436
75451
|
symbolText.at = [scaledPos.x, scaledPos.y, 0];
|
|
75437
|
-
const scaledFontSize = roundSchematicCoordinate(schText.fontSize *
|
|
75452
|
+
const scaledFontSize = roundSchematicCoordinate(schText.fontSize * scale9);
|
|
75438
75453
|
const font = new TextEffectsFont2;
|
|
75439
75454
|
font.size = { height: scaledFontSize, width: scaledFontSize };
|
|
75440
75455
|
symbolText.effects = new TextEffects2({ font });
|
|
@@ -75700,6 +75715,30 @@ function calculatePinPosition({
|
|
|
75700
75715
|
}
|
|
75701
75716
|
return { x, y, angle };
|
|
75702
75717
|
}
|
|
75718
|
+
function getKicadPinElectricalType(sourcePort) {
|
|
75719
|
+
if (!sourcePort)
|
|
75720
|
+
return "passive";
|
|
75721
|
+
if (sourcePort.provides_power || sourcePort.provides_ground) {
|
|
75722
|
+
return "power_out";
|
|
75723
|
+
}
|
|
75724
|
+
if (sourcePort.requires_power || sourcePort.requires_ground) {
|
|
75725
|
+
return "power_in";
|
|
75726
|
+
}
|
|
75727
|
+
if (sourcePort.is_using_open_collector || sourcePort.is_using_open_drain) {
|
|
75728
|
+
return "open_collector";
|
|
75729
|
+
}
|
|
75730
|
+
if (sourcePort.is_using_open_emitter)
|
|
75731
|
+
return "open_emitter";
|
|
75732
|
+
if (sourcePort.is_using_tri_state)
|
|
75733
|
+
return "tri_state";
|
|
75734
|
+
if (sourcePort.is_bidirectional)
|
|
75735
|
+
return "bidirectional";
|
|
75736
|
+
if (sourcePort.is_output)
|
|
75737
|
+
return "output";
|
|
75738
|
+
if (sourcePort.is_input)
|
|
75739
|
+
return "input";
|
|
75740
|
+
return "passive";
|
|
75741
|
+
}
|
|
75703
75742
|
function getPortSide(x, y) {
|
|
75704
75743
|
if (Math.abs(x) > Math.abs(y))
|
|
75705
75744
|
return x < 0 ? "left" : "right";
|
|
@@ -75716,12 +75755,11 @@ function getCircuitPinNumbers({
|
|
|
75716
75755
|
symbolData,
|
|
75717
75756
|
schematicComponent,
|
|
75718
75757
|
schematicPorts,
|
|
75719
|
-
|
|
75758
|
+
sourcePortsById
|
|
75720
75759
|
}) {
|
|
75721
75760
|
const matches = /* @__PURE__ */ new Map;
|
|
75722
75761
|
if (!schematicComponent)
|
|
75723
75762
|
return matches;
|
|
75724
|
-
const sourcePortsById = new Map(sourcePorts.map((port) => [port.source_port_id, port]));
|
|
75725
75763
|
const symbolCenter = symbolData.center ?? { x: 0, y: 0 };
|
|
75726
75764
|
const componentPorts = schematicPorts.filter((port) => port.schematic_component_id === schematicComponent.schematic_component_id);
|
|
75727
75765
|
for (const side of ["left", "right", "up", "down"]) {
|
|
@@ -75782,17 +75820,17 @@ function createPinSubsymbol({
|
|
|
75782
75820
|
});
|
|
75783
75821
|
const CHIP_PIN_LENGTH = 6;
|
|
75784
75822
|
const CUSTOM_SYMBOL_PIN_LENGTH = 0.01;
|
|
75823
|
+
const sourcePortsById = new Map(sourcePorts.map((port) => [port.source_port_id, port]));
|
|
75785
75824
|
const inferredPinNumbers = isChip ? /* @__PURE__ */ new Map : getCircuitPinNumbers({
|
|
75786
75825
|
symbolData,
|
|
75787
75826
|
schematicComponent,
|
|
75788
75827
|
schematicPorts,
|
|
75789
|
-
|
|
75828
|
+
sourcePortsById
|
|
75790
75829
|
});
|
|
75791
75830
|
const circuitPinNumbers = validateInferredPinNumbers(symbolData, inferredPinNumbers);
|
|
75792
75831
|
const origin = schematicComponent ? applyToPoint3(c2kMatSch, schematicComponent.center) : { x: 0, y: 0 };
|
|
75793
75832
|
for (const [i, port] of symbolData.ports.entries()) {
|
|
75794
75833
|
const pin = new SymbolPin;
|
|
75795
|
-
pin.pinElectricalType = "passive";
|
|
75796
75834
|
pin.pinGraphicStyle = "line";
|
|
75797
75835
|
const { x, y, angle } = calculatePinPosition({
|
|
75798
75836
|
port,
|
|
@@ -75823,8 +75861,15 @@ function createPinSubsymbol({
|
|
|
75823
75861
|
numFont.size = { height: 1.27, width: 1.27 };
|
|
75824
75862
|
const numEffects = new TextEffects4({ font: numFont });
|
|
75825
75863
|
const pinNum = port.pinNumber?.toString() ?? circuitPinNumbers.get(i) ?? `${i + 1}`;
|
|
75826
|
-
const schematicPort = schematicPorts.find((candidate) =>
|
|
75827
|
-
|
|
75864
|
+
const schematicPort = schematicPorts.find((candidate) => {
|
|
75865
|
+
if (candidate.schematic_component_id !== schematicComponent?.schematic_component_id) {
|
|
75866
|
+
return false;
|
|
75867
|
+
}
|
|
75868
|
+
const linkedSourcePort = sourcePortsById.get(candidate.source_port_id);
|
|
75869
|
+
return String(candidate.pin_number ?? linkedSourcePort?.pin_number) === pinNum;
|
|
75870
|
+
});
|
|
75871
|
+
const sourcePort = schematicPort ? sourcePortsById.get(schematicPort.source_port_id) : undefined;
|
|
75872
|
+
pin.pinElectricalType = getKicadPinElectricalType(sourcePort);
|
|
75828
75873
|
pin._sxNumber = new SymbolPinNumber({
|
|
75829
75874
|
value: getPhysicalPinName(sourcePort) ?? pinNum,
|
|
75830
75875
|
effects: numEffects
|
|
@@ -76286,8 +76331,8 @@ var AddSchematicGraphicsStage = class extends ConverterStage {
|
|
|
76286
76331
|
new Xy2(end.x, end.y)
|
|
76287
76332
|
]);
|
|
76288
76333
|
const stroke = new Stroke3;
|
|
76289
|
-
stroke.width = 0;
|
|
76290
|
-
stroke.type = "default";
|
|
76334
|
+
stroke.width = (line.stroke_width ?? 0) * (this.ctx.kicadSchematicScaleFactor ?? 1);
|
|
76335
|
+
stroke.type = line.is_dashed ? "dash" : "default";
|
|
76291
76336
|
stroke.color = preserveStandaloneGraphics ? parseColor(line.color) ?? DEFAULT_SECTION_LINE_COLOR : DEFAULT_SECTION_LINE_COLOR;
|
|
76292
76337
|
polyline.stroke = stroke;
|
|
76293
76338
|
polyline.uuid = new Uuid(crypto.randomUUID());
|
|
@@ -76598,6 +76643,30 @@ var AddSchematicNetLabelsStage = class extends ConverterStage {
|
|
|
76598
76643
|
return this.ctx.kicadSch;
|
|
76599
76644
|
}
|
|
76600
76645
|
};
|
|
76646
|
+
var AddSchematicNoConnectsStage = class extends ConverterStage {
|
|
76647
|
+
_step() {
|
|
76648
|
+
const { db, kicadSch, c2kMatSch } = this.ctx;
|
|
76649
|
+
if (!kicadSch) {
|
|
76650
|
+
throw new Error("KicadSch instance not initialized in context");
|
|
76651
|
+
}
|
|
76652
|
+
if (!c2kMatSch) {
|
|
76653
|
+
throw new Error("Schematic transformation matrix not initialized in context");
|
|
76654
|
+
}
|
|
76655
|
+
const noConnectSourcePortIds = new Set(db.source_port.list().filter((sourcePort) => sourcePort.do_not_connect).map((sourcePort) => sourcePort.source_port_id));
|
|
76656
|
+
const noConnects = db.schematic_port.list().filter((schematicPort) => noConnectSourcePortIds.has(schematicPort.source_port_id) && !schematicPort.is_connected).map((schematicPort) => {
|
|
76657
|
+
const position = transformSchematicPoint(c2kMatSch, schematicPort.center);
|
|
76658
|
+
return new NoConnect({
|
|
76659
|
+
at: [position.x, position.y],
|
|
76660
|
+
uuid: crypto.randomUUID()
|
|
76661
|
+
});
|
|
76662
|
+
});
|
|
76663
|
+
kicadSch.noConnects = [...kicadSch.noConnects, ...noConnects];
|
|
76664
|
+
this.finished = true;
|
|
76665
|
+
}
|
|
76666
|
+
getOutput() {
|
|
76667
|
+
return this.ctx.kicadSch;
|
|
76668
|
+
}
|
|
76669
|
+
};
|
|
76601
76670
|
var DEFAULT_PROPERTY_FONT_SIZE = 1.27;
|
|
76602
76671
|
var AddSchematicSymbolsStage = class extends ConverterStage {
|
|
76603
76672
|
_step() {
|
|
@@ -77226,6 +77295,7 @@ var CircuitJsonToKicadSchConverter = class {
|
|
|
77226
77295
|
new AddLibrarySymbolsStage(circuitJson, this.ctx),
|
|
77227
77296
|
new AddSchematicSymbolsStage(circuitJson, this.ctx),
|
|
77228
77297
|
new AddSchematicNetLabelsStage(circuitJson, this.ctx),
|
|
77298
|
+
new AddSchematicNoConnectsStage(circuitJson, this.ctx),
|
|
77229
77299
|
new AddSchematicTracesStage(circuitJson, this.ctx),
|
|
77230
77300
|
new AddSchematicGraphicsStage(circuitJson, this.ctx),
|
|
77231
77301
|
new AddSheetInstancesStage(circuitJson, this.ctx)
|
|
@@ -77384,6 +77454,7 @@ var CircuitJsonToKicadSchConverter = class {
|
|
|
77384
77454
|
new AddLibrarySymbolsStage(circuitJson, ctx),
|
|
77385
77455
|
new AddSchematicSymbolsStage(circuitJson, ctx),
|
|
77386
77456
|
new AddSchematicNetLabelsStage(circuitJson, ctx),
|
|
77457
|
+
new AddSchematicNoConnectsStage(circuitJson, ctx),
|
|
77387
77458
|
new AddSchematicTracesStage(circuitJson, ctx),
|
|
77388
77459
|
new AddSchematicGraphicsStage(circuitJson, ctx)
|
|
77389
77460
|
];
|
|
@@ -77461,6 +77532,110 @@ function getViaLayerSpan(kicadLayers, numLayers) {
|
|
|
77461
77532
|
}
|
|
77462
77533
|
return top === bottom ? [top] : [top, bottom];
|
|
77463
77534
|
}
|
|
77535
|
+
var getTriangleTwiceArea = (a, b, c) => Math.abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y));
|
|
77536
|
+
var triangulatePolygonWithHoles = (outerContour, holes = []) => {
|
|
77537
|
+
const flattenedPoints = [];
|
|
77538
|
+
const holeIndices = [];
|
|
77539
|
+
let pointCount = 0;
|
|
77540
|
+
const addContour = (contour) => {
|
|
77541
|
+
for (const point of contour) {
|
|
77542
|
+
flattenedPoints.push(point.x, point.y);
|
|
77543
|
+
}
|
|
77544
|
+
pointCount += contour.length;
|
|
77545
|
+
};
|
|
77546
|
+
addContour(outerContour);
|
|
77547
|
+
for (const hole of holes) {
|
|
77548
|
+
holeIndices.push(pointCount);
|
|
77549
|
+
addContour(hole);
|
|
77550
|
+
}
|
|
77551
|
+
const triangleIndices = earcut(flattenedPoints, holeIndices, 2);
|
|
77552
|
+
const triangles = [];
|
|
77553
|
+
for (let index = 0;index < triangleIndices.length; index += 3) {
|
|
77554
|
+
const aIndex = triangleIndices[index];
|
|
77555
|
+
const bIndex = triangleIndices[index + 1];
|
|
77556
|
+
const cIndex = triangleIndices[index + 2];
|
|
77557
|
+
if (aIndex === undefined || bIndex === undefined || cIndex === undefined) {
|
|
77558
|
+
continue;
|
|
77559
|
+
}
|
|
77560
|
+
const getPoint = (pointIndex) => ({
|
|
77561
|
+
x: flattenedPoints[pointIndex * 2],
|
|
77562
|
+
y: flattenedPoints[pointIndex * 2 + 1]
|
|
77563
|
+
});
|
|
77564
|
+
const triangle = [
|
|
77565
|
+
getPoint(aIndex),
|
|
77566
|
+
getPoint(bIndex),
|
|
77567
|
+
getPoint(cIndex)
|
|
77568
|
+
];
|
|
77569
|
+
if (getTriangleTwiceArea(...triangle) === 0)
|
|
77570
|
+
continue;
|
|
77571
|
+
triangles.push(triangle);
|
|
77572
|
+
}
|
|
77573
|
+
return triangles;
|
|
77574
|
+
};
|
|
77575
|
+
var getDistance = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
|
|
77576
|
+
var getSafePolygonAnchor = (outerContour, holes = []) => {
|
|
77577
|
+
const triangles = triangulatePolygonWithHoles(outerContour, holes);
|
|
77578
|
+
let bestTriangle;
|
|
77579
|
+
for (const [a, b, c] of triangles) {
|
|
77580
|
+
const sideA = getDistance(b, c);
|
|
77581
|
+
const sideB = getDistance(c, a);
|
|
77582
|
+
const sideC = getDistance(a, b);
|
|
77583
|
+
const perimeter = sideA + sideB + sideC;
|
|
77584
|
+
if (perimeter === 0)
|
|
77585
|
+
continue;
|
|
77586
|
+
const inradius = getTriangleTwiceArea(a, b, c) / perimeter;
|
|
77587
|
+
const center = {
|
|
77588
|
+
x: (sideA * a.x + sideB * b.x + sideC * c.x) / perimeter,
|
|
77589
|
+
y: (sideA * a.y + sideB * b.y + sideC * c.y) / perimeter
|
|
77590
|
+
};
|
|
77591
|
+
if (!bestTriangle || inradius > bestTriangle.inradius) {
|
|
77592
|
+
bestTriangle = { center, inradius };
|
|
77593
|
+
}
|
|
77594
|
+
}
|
|
77595
|
+
if (!bestTriangle) {
|
|
77596
|
+
throw new Error("Polygon must contain a valid filled area");
|
|
77597
|
+
}
|
|
77598
|
+
return {
|
|
77599
|
+
center: bestTriangle.center,
|
|
77600
|
+
diameter: Math.min(0.001, bestTriangle.inradius),
|
|
77601
|
+
triangles
|
|
77602
|
+
};
|
|
77603
|
+
};
|
|
77604
|
+
var createFilledPolygonPrimitives = ({
|
|
77605
|
+
contours,
|
|
77606
|
+
center
|
|
77607
|
+
}) => {
|
|
77608
|
+
const toLocalContour = (points) => new Pts4(points.map((point) => {
|
|
77609
|
+
const localPoint = applyToPoint9(compose3(scale2(1, -1), translate3(-center.x, -center.y)), point);
|
|
77610
|
+
return new Xy4(localPoint.x, localPoint.y);
|
|
77611
|
+
}));
|
|
77612
|
+
const primitives = new PadPrimitives;
|
|
77613
|
+
for (const contour of contours) {
|
|
77614
|
+
const polygon = new PadPrimitiveGrPoly;
|
|
77615
|
+
polygon.contours = [toLocalContour(contour)];
|
|
77616
|
+
polygon.width = 0;
|
|
77617
|
+
polygon.filled = true;
|
|
77618
|
+
primitives.addGraphic(polygon);
|
|
77619
|
+
}
|
|
77620
|
+
return primitives;
|
|
77621
|
+
};
|
|
77622
|
+
var createEllipseContour = ({
|
|
77623
|
+
center,
|
|
77624
|
+
width,
|
|
77625
|
+
height,
|
|
77626
|
+
segmentCount = 64
|
|
77627
|
+
}) => {
|
|
77628
|
+
if (width <= 0 || height <= 0) {
|
|
77629
|
+
throw new Error("Ellipse must have positive dimensions");
|
|
77630
|
+
}
|
|
77631
|
+
return Array.from({ length: segmentCount }, (_, index) => {
|
|
77632
|
+
const angle = index / segmentCount * Math.PI * 2;
|
|
77633
|
+
return {
|
|
77634
|
+
x: center.x + width / 2 * Math.cos(angle),
|
|
77635
|
+
y: center.y + height / 2 * Math.sin(angle)
|
|
77636
|
+
};
|
|
77637
|
+
});
|
|
77638
|
+
};
|
|
77464
77639
|
function simpleHash(str) {
|
|
77465
77640
|
let hash = 0;
|
|
77466
77641
|
for (let i = 0;i < str.length; i++) {
|
|
@@ -77497,8 +77672,8 @@ var getCopperPourNetInfo = (pour, ctx) => {
|
|
|
77497
77672
|
};
|
|
77498
77673
|
var convertPointsToKicadXy = (points, c2kMatPcb) => {
|
|
77499
77674
|
return (points ?? []).map((point) => {
|
|
77500
|
-
const transformedPoint =
|
|
77501
|
-
return new
|
|
77675
|
+
const transformedPoint = applyToPoint10(c2kMatPcb, point);
|
|
77676
|
+
return new Xy5(transformedPoint.x, transformedPoint.y);
|
|
77502
77677
|
});
|
|
77503
77678
|
};
|
|
77504
77679
|
var rotateRingToStartAtTopRight = (points) => {
|
|
@@ -77538,7 +77713,7 @@ var removeRepeatedClosingPoint = (points) => {
|
|
|
77538
77713
|
};
|
|
77539
77714
|
var getRectRingPoints = (pour, c2kMatPcb) => {
|
|
77540
77715
|
const ccwRotationDegrees = pour.rotation ?? 0;
|
|
77541
|
-
const cornerTransform =
|
|
77716
|
+
const cornerTransform = compose4(translate4(pour.center.x, pour.center.y), rotate(ccwRotationDegrees * Math.PI / 180));
|
|
77542
77717
|
const halfWidth = pour.width / 2;
|
|
77543
77718
|
const halfHeight = pour.height / 2;
|
|
77544
77719
|
const corners = [
|
|
@@ -77546,7 +77721,7 @@ var getRectRingPoints = (pour, c2kMatPcb) => {
|
|
|
77546
77721
|
{ x: halfWidth, y: -halfHeight },
|
|
77547
77722
|
{ x: halfWidth, y: halfHeight },
|
|
77548
77723
|
{ x: -halfWidth, y: halfHeight }
|
|
77549
|
-
].map((corner) =>
|
|
77724
|
+
].map((corner) => applyToPoint10(cornerTransform, corner));
|
|
77550
77725
|
return convertPointsToKicadXy(corners, c2kMatPcb);
|
|
77551
77726
|
};
|
|
77552
77727
|
var getPolygonRingPoints = (pour, c2kMatPcb) => removeRepeatedClosingPoint(removeConsecutiveDuplicatePoints(rotateRingToStartAtTopRight(convertPointsToKicadXy(pour.points, c2kMatPcb))));
|
|
@@ -77570,16 +77745,15 @@ var getCopperPourZoneRings = (pour, c2kMatPcb) => {
|
|
|
77570
77745
|
var createZonePolygons = (outerRing, innerRings) => {
|
|
77571
77746
|
const polygons = [];
|
|
77572
77747
|
if (outerRing.length >= 3) {
|
|
77573
|
-
polygons.push(new ZonePolygon(new
|
|
77748
|
+
polygons.push(new ZonePolygon(new Pts5(outerRing)));
|
|
77574
77749
|
}
|
|
77575
77750
|
for (const innerRing of innerRings) {
|
|
77576
77751
|
if (innerRing.length < 3)
|
|
77577
77752
|
continue;
|
|
77578
|
-
polygons.push(new ZonePolygon(new
|
|
77753
|
+
polygons.push(new ZonePolygon(new Pts5(innerRing)));
|
|
77579
77754
|
}
|
|
77580
77755
|
return polygons;
|
|
77581
77756
|
};
|
|
77582
|
-
var getTriangleArea = (a, b, c) => Math.abs((a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y)) / 2);
|
|
77583
77757
|
var createZoneFilledPolygons = (outerRing, innerRings, kicadLayer) => {
|
|
77584
77758
|
if (outerRing.length < 3) {
|
|
77585
77759
|
return [];
|
|
@@ -77589,45 +77763,14 @@ var createZoneFilledPolygons = (outerRing, innerRings, kicadLayer) => {
|
|
|
77589
77763
|
return [
|
|
77590
77764
|
new ZoneFilledPolygon({
|
|
77591
77765
|
layer,
|
|
77592
|
-
pts: new
|
|
77766
|
+
pts: new Pts5(outerRing)
|
|
77593
77767
|
})
|
|
77594
77768
|
];
|
|
77595
77769
|
}
|
|
77596
|
-
|
|
77597
|
-
|
|
77598
|
-
|
|
77599
|
-
|
|
77600
|
-
for (const point of ring) {
|
|
77601
|
-
flattenedPoints.push(point.x, point.y);
|
|
77602
|
-
}
|
|
77603
|
-
pointIndex += ring.length;
|
|
77604
|
-
};
|
|
77605
|
-
addRing(outerRing);
|
|
77606
|
-
for (const innerRing of innerRings) {
|
|
77607
|
-
holeIndices.push(pointIndex);
|
|
77608
|
-
addRing(innerRing);
|
|
77609
|
-
}
|
|
77610
|
-
const triangleIndices = earcut(flattenedPoints, holeIndices, 2);
|
|
77611
|
-
const filledPolygons = [];
|
|
77612
|
-
for (let i = 0;i < triangleIndices.length; i += 3) {
|
|
77613
|
-
const trianglePoints = [];
|
|
77614
|
-
for (let offset = 0;offset < 3; offset++) {
|
|
77615
|
-
const pointOffset = triangleIndices[i + offset] * 2;
|
|
77616
|
-
const x = flattenedPoints[pointOffset];
|
|
77617
|
-
const y = flattenedPoints[pointOffset + 1];
|
|
77618
|
-
if (x === undefined || y === undefined)
|
|
77619
|
-
continue;
|
|
77620
|
-
trianglePoints.push(new Xy4(x, y));
|
|
77621
|
-
}
|
|
77622
|
-
if (trianglePoints.length !== 3 || getTriangleArea(trianglePoints[0], trianglePoints[1], trianglePoints[2]) === 0) {
|
|
77623
|
-
continue;
|
|
77624
|
-
}
|
|
77625
|
-
filledPolygons.push(new ZoneFilledPolygon({
|
|
77626
|
-
layer,
|
|
77627
|
-
pts: new Pts4(trianglePoints)
|
|
77628
|
-
}));
|
|
77629
|
-
}
|
|
77630
|
-
return filledPolygons;
|
|
77770
|
+
return triangulatePolygonWithHoles(outerRing, innerRings).map((triangle) => new ZoneFilledPolygon({
|
|
77771
|
+
layer,
|
|
77772
|
+
pts: new Pts5(triangle.map((point) => new Xy5(point.x, point.y)))
|
|
77773
|
+
}));
|
|
77631
77774
|
};
|
|
77632
77775
|
var AddCopperPoursStage = class extends ConverterStage {
|
|
77633
77776
|
_step() {
|
|
@@ -77718,8 +77861,8 @@ var AddKeepoutsStage = class extends ConverterStage {
|
|
|
77718
77861
|
rawPoints = keepout.outline;
|
|
77719
77862
|
}
|
|
77720
77863
|
const kicadPoints = rawPoints.map((p) => {
|
|
77721
|
-
const t =
|
|
77722
|
-
return new
|
|
77864
|
+
const t = applyToPoint11(c2kMatPcb, p);
|
|
77865
|
+
return new Xy6(t.x, t.y);
|
|
77723
77866
|
});
|
|
77724
77867
|
const zone = new Zone2({
|
|
77725
77868
|
net: 0,
|
|
@@ -77733,7 +77876,7 @@ var AddKeepoutsStage = class extends ConverterStage {
|
|
|
77733
77876
|
copperpour: "not_allowed",
|
|
77734
77877
|
footprints: "not_allowed"
|
|
77735
77878
|
}),
|
|
77736
|
-
polygons: [new ZonePolygon2(new
|
|
77879
|
+
polygons: [new ZonePolygon2(new Pts6(kicadPoints))]
|
|
77737
77880
|
});
|
|
77738
77881
|
const zones = kicadPcb.zones;
|
|
77739
77882
|
zones.push(zone);
|
|
@@ -77781,6 +77924,14 @@ var InitializePcbStage = class extends ConverterStage {
|
|
|
77781
77924
|
return this.ctx.kicadPcb;
|
|
77782
77925
|
}
|
|
77783
77926
|
};
|
|
77927
|
+
var resolveKicadPcbNetName = ({
|
|
77928
|
+
candidateName,
|
|
77929
|
+
connectivityKey,
|
|
77930
|
+
boardId
|
|
77931
|
+
}) => {
|
|
77932
|
+
const name = candidateName && candidateName.trim().length > 0 ? candidateName : connectivityKey;
|
|
77933
|
+
return boardId ? `${boardId}/${name}` : name;
|
|
77934
|
+
};
|
|
77784
77935
|
var AddNetsStage = class extends ConverterStage {
|
|
77785
77936
|
_step() {
|
|
77786
77937
|
const { kicadPcb } = this.ctx;
|
|
@@ -77789,13 +77940,17 @@ var AddNetsStage = class extends ConverterStage {
|
|
|
77789
77940
|
}
|
|
77790
77941
|
this.ctx.pcbNetMap = /* @__PURE__ */ new Map;
|
|
77791
77942
|
const netNameByKey = /* @__PURE__ */ new Map;
|
|
77943
|
+
const boardOwnerMap = this.ctx.db.pcb_board.list().length > 1 ? createBoardOwnerMap(this.input) : undefined;
|
|
77792
77944
|
const sourceNets = this.ctx.db.source_net?.list() ?? [];
|
|
77793
77945
|
for (const sourceNet of sourceNets) {
|
|
77794
77946
|
const connectivityKey = sourceNet.subcircuit_connectivity_map_key || sourceNet.source_net_id;
|
|
77795
77947
|
if (!connectivityKey)
|
|
77796
77948
|
continue;
|
|
77797
|
-
const
|
|
77798
|
-
|
|
77949
|
+
const netName = resolveKicadPcbNetName({
|
|
77950
|
+
candidateName: sourceNet.name || sourceNet.source_net_id,
|
|
77951
|
+
connectivityKey,
|
|
77952
|
+
boardId: boardOwnerMap?.get(sourceNet.subcircuit_id ?? "")?.pcb_board_id
|
|
77953
|
+
});
|
|
77799
77954
|
netNameByKey.set(connectivityKey, netName);
|
|
77800
77955
|
}
|
|
77801
77956
|
const sourceTraces = this.ctx.db.source_trace?.list() ?? [];
|
|
@@ -77813,8 +77968,11 @@ var AddNetsStage = class extends ConverterStage {
|
|
|
77813
77968
|
if (!connectivityKey)
|
|
77814
77969
|
continue;
|
|
77815
77970
|
if (!netNameByKey.has(connectivityKey)) {
|
|
77816
|
-
const
|
|
77817
|
-
|
|
77971
|
+
const netName = resolveKicadPcbNetName({
|
|
77972
|
+
candidateName: sourceTrace.display_name || sourceTrace.source_trace_id,
|
|
77973
|
+
connectivityKey,
|
|
77974
|
+
boardId: boardOwnerMap?.get(sourceTrace.subcircuit_id ?? "")?.pcb_board_id
|
|
77975
|
+
});
|
|
77818
77976
|
netNameByKey.set(connectivityKey, netName);
|
|
77819
77977
|
}
|
|
77820
77978
|
}
|
|
@@ -78040,7 +78198,8 @@ var ExtractFootprintsStage = class extends ConverterStage {
|
|
|
78040
78198
|
for (let i = 0;i < pads.length; i++) {
|
|
78041
78199
|
const pad = pads[i];
|
|
78042
78200
|
if (pad) {
|
|
78043
|
-
pad.
|
|
78201
|
+
const padIdentity = pad.number === "" ? `unnumbered-${i}` : pad.number ?? i;
|
|
78202
|
+
pad.uuid = generateDeterministicUuid(`${footprintName}-pad-${padIdentity}`);
|
|
78044
78203
|
pad.net = undefined;
|
|
78045
78204
|
}
|
|
78046
78205
|
}
|
|
@@ -78328,7 +78487,7 @@ function convertSilkscreenCircles(silkscreenCircles, { componentCenter, componen
|
|
|
78328
78487
|
const fpCircles = [];
|
|
78329
78488
|
const rotationMatrix = componentRotation !== 0 ? rotate2(componentRotation * Math.PI / 180) : identity();
|
|
78330
78489
|
for (const circle of silkscreenCircles) {
|
|
78331
|
-
const relativeCenter =
|
|
78490
|
+
const relativeCenter = applyToPoint12(rotationMatrix, {
|
|
78332
78491
|
x: circle.center.x - componentCenter.x,
|
|
78333
78492
|
y: -(circle.center.y - componentCenter.y)
|
|
78334
78493
|
});
|
|
@@ -78356,13 +78515,13 @@ function getBoardToFootprintTransform({
|
|
|
78356
78515
|
footprintOrigin,
|
|
78357
78516
|
ccwRotationDegrees = 0
|
|
78358
78517
|
}) {
|
|
78359
|
-
return
|
|
78518
|
+
return compose5(rotateDEG(ccwRotationDegrees), scale3(1, -1), translate5(-footprintOrigin.x, -footprintOrigin.y));
|
|
78360
78519
|
}
|
|
78361
78520
|
function convertCourtyardCircles(courtyardCircles, placement) {
|
|
78362
78521
|
const fpCircles = [];
|
|
78363
78522
|
const boardToFootprintTransform = getBoardToFootprintTransform(placement);
|
|
78364
78523
|
for (const circle of courtyardCircles) {
|
|
78365
|
-
const center =
|
|
78524
|
+
const center = applyToPoint13(boardToFootprintTransform, circle.center);
|
|
78366
78525
|
const layerMap = {
|
|
78367
78526
|
top: "F.CrtYd",
|
|
78368
78527
|
bottom: "B.CrtYd"
|
|
@@ -78389,7 +78548,7 @@ function convertNoteRectToFootprintGraphic({
|
|
|
78389
78548
|
footprintOrigin,
|
|
78390
78549
|
ccwRotationDegrees = 0
|
|
78391
78550
|
}) {
|
|
78392
|
-
const rectToFootprintTransform =
|
|
78551
|
+
const rectToFootprintTransform = compose6(getBoardToFootprintTransform({ footprintOrigin, ccwRotationDegrees }), translate6(rect.center.x, rect.center.y));
|
|
78393
78552
|
const halfWidth = rect.width / 2;
|
|
78394
78553
|
const halfHeight = rect.height / 2;
|
|
78395
78554
|
const corners = [
|
|
@@ -78397,7 +78556,7 @@ function convertNoteRectToFootprintGraphic({
|
|
|
78397
78556
|
{ x: halfWidth, y: -halfHeight },
|
|
78398
78557
|
{ x: halfWidth, y: halfHeight },
|
|
78399
78558
|
{ x: -halfWidth, y: halfHeight }
|
|
78400
|
-
].map((point) =>
|
|
78559
|
+
].map((point) => applyToPoint14(rectToFootprintTransform, point));
|
|
78401
78560
|
const stroke = new Stroke7;
|
|
78402
78561
|
stroke.width = rect.stroke_width || 0.1;
|
|
78403
78562
|
stroke.type = "default";
|
|
@@ -78472,7 +78631,7 @@ function rotateCenter(point, degrees) {
|
|
|
78472
78631
|
case 270:
|
|
78473
78632
|
return { x: point.y, y: -point.x };
|
|
78474
78633
|
default:
|
|
78475
|
-
return
|
|
78634
|
+
return applyToPoint15(rotate3(degrees * Math.PI / 180), point);
|
|
78476
78635
|
}
|
|
78477
78636
|
}
|
|
78478
78637
|
function convertCourtyardRects({
|
|
@@ -78482,7 +78641,7 @@ function convertCourtyardRects({
|
|
|
78482
78641
|
}) {
|
|
78483
78642
|
const fpRects = [];
|
|
78484
78643
|
const fpPolys = [];
|
|
78485
|
-
const toLocal =
|
|
78644
|
+
const toLocal = compose7(rotate3(componentRotation * Math.PI / 180), scale4(1, -1), translate7(-componentCenter.x, -componentCenter.y));
|
|
78486
78645
|
for (const rect of courtyardRects) {
|
|
78487
78646
|
const halfW = rect.width / 2;
|
|
78488
78647
|
const halfH = rect.height / 2;
|
|
@@ -78516,13 +78675,13 @@ function convertCourtyardRects({
|
|
|
78516
78675
|
fill: false
|
|
78517
78676
|
}));
|
|
78518
78677
|
} else {
|
|
78519
|
-
const fromRectCenter =
|
|
78678
|
+
const fromRectCenter = compose7(translate7(rect.center.x, rect.center.y), rotate3(rotation * Math.PI / 180));
|
|
78520
78679
|
const points = [
|
|
78521
78680
|
{ x: -halfW, y: -halfH },
|
|
78522
78681
|
{ x: halfW, y: -halfH },
|
|
78523
78682
|
{ x: halfW, y: halfH },
|
|
78524
78683
|
{ x: -halfW, y: halfH }
|
|
78525
|
-
].map((point) =>
|
|
78684
|
+
].map((point) => applyToPoint15(toLocal, applyToPoint15(fromRectCenter, point)));
|
|
78526
78685
|
fpPolys.push(new FpPoly4({
|
|
78527
78686
|
points,
|
|
78528
78687
|
layer,
|
|
@@ -78537,7 +78696,7 @@ function convertCourtyardRects({
|
|
|
78537
78696
|
function convertCourtyardOutlines(params2) {
|
|
78538
78697
|
const { courtyardOutlines, componentCenter, componentRotation = 0 } = params2;
|
|
78539
78698
|
const fpPolys = [];
|
|
78540
|
-
const cj2kicadMatrix =
|
|
78699
|
+
const cj2kicadMatrix = compose8(componentRotation !== 0 ? rotate4(componentRotation * Math.PI / 180) : { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }, scale5(1, -1), translate8(-componentCenter.x, -componentCenter.y));
|
|
78541
78700
|
for (const outline of courtyardOutlines) {
|
|
78542
78701
|
if (!outline.outline || outline.outline.length < 2)
|
|
78543
78702
|
continue;
|
|
@@ -78547,11 +78706,11 @@ function convertCourtyardOutlines(params2) {
|
|
|
78547
78706
|
};
|
|
78548
78707
|
const kicadLayer = layerMap[outline.layer] || "F.CrtYd";
|
|
78549
78708
|
const xyPoints = outline.outline.map((point) => {
|
|
78550
|
-
const transformedPoint =
|
|
78551
|
-
return new
|
|
78709
|
+
const transformedPoint = applyToPoint16(cj2kicadMatrix, point);
|
|
78710
|
+
return new Xy7(transformedPoint.x, transformedPoint.y);
|
|
78552
78711
|
});
|
|
78553
78712
|
const fpPoly = new FpPoly5;
|
|
78554
|
-
fpPoly.points = new
|
|
78713
|
+
fpPoly.points = new Pts7(xyPoints);
|
|
78555
78714
|
fpPoly.layer = kicadLayer;
|
|
78556
78715
|
fpPoly.fill = false;
|
|
78557
78716
|
fpPoly.uuid = generateDeterministicUuid(outline.pcb_courtyard_outline_id);
|
|
@@ -78621,7 +78780,7 @@ function createFpTextFromCircuitJson({
|
|
|
78621
78780
|
const relativeX = textElement.anchor_position.x - componentCenter.x;
|
|
78622
78781
|
const relativeY = -(textElement.anchor_position.y - componentCenter.y);
|
|
78623
78782
|
const rotationMatrix = componentRotation !== 0 ? rotate5(componentRotation * Math.PI / 180) : identity2();
|
|
78624
|
-
const rotatedPos =
|
|
78783
|
+
const rotatedPos = applyToPoint17(rotationMatrix, {
|
|
78625
78784
|
x: relativeX,
|
|
78626
78785
|
y: relativeY
|
|
78627
78786
|
});
|
|
@@ -78702,11 +78861,11 @@ function convertSilkscreenPaths(silkscreenPaths, { componentCenter, componentRot
|
|
|
78702
78861
|
const endPoint = path.route[i + 1];
|
|
78703
78862
|
if (!startPoint || !endPoint)
|
|
78704
78863
|
continue;
|
|
78705
|
-
const startRelative =
|
|
78864
|
+
const startRelative = applyToPoint18(rotationMatrix, {
|
|
78706
78865
|
x: startPoint.x - componentCenter.x,
|
|
78707
78866
|
y: -(startPoint.y - componentCenter.y)
|
|
78708
78867
|
});
|
|
78709
|
-
const endRelative =
|
|
78868
|
+
const endRelative = applyToPoint18(rotationMatrix, {
|
|
78710
78869
|
x: endPoint.x - componentCenter.x,
|
|
78711
78870
|
y: -(endPoint.y - componentCenter.y)
|
|
78712
78871
|
});
|
|
@@ -78756,13 +78915,13 @@ function convertSilkscreenRects({
|
|
|
78756
78915
|
componentCenter,
|
|
78757
78916
|
componentRotation = 0
|
|
78758
78917
|
}) {
|
|
78759
|
-
const toLocal =
|
|
78918
|
+
const toLocal = compose9(rotate7(componentRotation * Math.PI / 180), scale6(1, -1), translate9(-componentCenter.x, -componentCenter.y));
|
|
78760
78919
|
return silkscreenRects.flatMap((rect) => {
|
|
78761
78920
|
const hasStroke = rect.has_stroke ?? rect.stroke_width > 0;
|
|
78762
78921
|
if (!hasStroke && !rect.is_filled)
|
|
78763
78922
|
return [];
|
|
78764
|
-
const fromRectCenter =
|
|
78765
|
-
const points = getRectanglePoints(rect).map((point) =>
|
|
78923
|
+
const fromRectCenter = compose9(translate9(rect.center.x, rect.center.y), rotate7((rect.ccw_rotation ?? 0) * Math.PI / 180));
|
|
78924
|
+
const points = getRectanglePoints(rect).map((point) => applyToPoint19(toLocal, applyToPoint19(fromRectCenter, point)));
|
|
78766
78925
|
const stroke = hasStroke ? new Stroke11 : undefined;
|
|
78767
78926
|
if (stroke) {
|
|
78768
78927
|
stroke.width = rect.stroke_width;
|
|
@@ -78786,7 +78945,7 @@ function convertNoteTexts(params2) {
|
|
|
78786
78945
|
const relX = textElement.anchor_position.x - componentCenter.x;
|
|
78787
78946
|
const relY = -(textElement.anchor_position.y - componentCenter.y);
|
|
78788
78947
|
const rotationMatrix = componentRotation !== 0 ? rotate8(componentRotation * Math.PI / 180) : identity4();
|
|
78789
|
-
const rotatedPos =
|
|
78948
|
+
const rotatedPos = applyToPoint20(rotationMatrix, { x: relX, y: relY });
|
|
78790
78949
|
const fontSize = textElement.font_size || 1;
|
|
78791
78950
|
const font = new TextEffectsFont11;
|
|
78792
78951
|
font.size = { width: fontSize, height: fontSize };
|
|
@@ -78900,15 +79059,47 @@ function create3DModelsFromCadComponent(cadComponent, componentCenter, options)
|
|
|
78900
79059
|
model.offset = transform.offset;
|
|
78901
79060
|
model.rotate = transform.rotation;
|
|
78902
79061
|
if (cadComponent.model_unit_to_mm_scale_factor) {
|
|
78903
|
-
const
|
|
78904
|
-
model.scale = { x:
|
|
79062
|
+
const scale9 = cadComponent.model_unit_to_mm_scale_factor;
|
|
79063
|
+
model.scale = { x: scale9, y: scale9, z: scale9 };
|
|
78905
79064
|
}
|
|
78906
79065
|
models.push(model);
|
|
78907
79066
|
return models;
|
|
78908
79067
|
}
|
|
79068
|
+
var getResolvedPillRadius = ({
|
|
79069
|
+
width,
|
|
79070
|
+
height,
|
|
79071
|
+
radius
|
|
79072
|
+
}) => typeof radius === "number" && Number.isFinite(radius) ? radius : Math.min(width, height) / 2;
|
|
79073
|
+
var getKicadNativePadGeometry = (pad) => {
|
|
79074
|
+
switch (pad.shape) {
|
|
79075
|
+
case "circle":
|
|
79076
|
+
return {
|
|
79077
|
+
shape: "circle",
|
|
79078
|
+
size: [pad.radius * 2, pad.radius * 2],
|
|
79079
|
+
rotation: 0
|
|
79080
|
+
};
|
|
79081
|
+
case "rect":
|
|
79082
|
+
case "rotated_rect": {
|
|
79083
|
+
const cornerRadius = pad.corner_radius ?? pad.rect_border_radius;
|
|
79084
|
+
return {
|
|
79085
|
+
shape: cornerRadius ? "roundrect" : "rect",
|
|
79086
|
+
size: [pad.width, pad.height],
|
|
79087
|
+
rotation: pad.shape === "rotated_rect" ? pad.ccw_rotation ?? 0 : 0,
|
|
79088
|
+
roundrectRatio: cornerRadius ? cornerRadius / Math.min(pad.width, pad.height) : undefined
|
|
79089
|
+
};
|
|
79090
|
+
}
|
|
79091
|
+
case "pill":
|
|
79092
|
+
case "rotated_pill":
|
|
79093
|
+
return {
|
|
79094
|
+
shape: "roundrect",
|
|
79095
|
+
size: [pad.width, pad.height],
|
|
79096
|
+
rotation: pad.shape === "rotated_pill" ? pad.ccw_rotation ?? 0 : 0,
|
|
79097
|
+
roundrectRatio: getResolvedPillRadius(pad) / Math.min(pad.width, pad.height)
|
|
79098
|
+
};
|
|
79099
|
+
}
|
|
79100
|
+
};
|
|
78909
79101
|
function createSmdPadFromCircuitJson({
|
|
78910
79102
|
pcbPad,
|
|
78911
|
-
hasSolderPaste,
|
|
78912
79103
|
componentCenter,
|
|
78913
79104
|
padNumber,
|
|
78914
79105
|
componentRotation = 0,
|
|
@@ -78927,8 +79118,8 @@ function createSmdPadFromCircuitJson({
|
|
|
78927
79118
|
} else {
|
|
78928
79119
|
throw new Error("Pad must have either x/y coordinates or points array");
|
|
78929
79120
|
}
|
|
78930
|
-
const cj2kicadMatrix =
|
|
78931
|
-
const rotatedPos =
|
|
79121
|
+
const cj2kicadMatrix = compose10(componentRotation !== 0 ? rotate9(componentRotation * Math.PI / 180) : { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 }, scale7(1, -1), translate10(-componentCenter.x, -componentCenter.y));
|
|
79122
|
+
const rotatedPos = applyToPoint21(cj2kicadMatrix, {
|
|
78932
79123
|
x: padX,
|
|
78933
79124
|
y: padY
|
|
78934
79125
|
});
|
|
@@ -78943,57 +79134,21 @@ function createSmdPadFromCircuitJson({
|
|
|
78943
79134
|
let padPrimitives;
|
|
78944
79135
|
let roundrect_rratio;
|
|
78945
79136
|
let rotation = 0;
|
|
78946
|
-
if (pcbPad.shape === "
|
|
78947
|
-
|
|
78948
|
-
|
|
78949
|
-
|
|
78950
|
-
"radius" in pcbPad ? pcbPad.radius * 2 : 0.5
|
|
78951
|
-
];
|
|
78952
|
-
} else if (pcbPad.shape === "polygon" && "points" in pcbPad) {
|
|
78953
|
-
const points = pcbPad.points;
|
|
78954
|
-
const pointTransformMatrix = compose9(scale6(1, -1), translate9(-padX, -padY));
|
|
78955
|
-
const relativePoints = points.map((p) => {
|
|
78956
|
-
const transformed = applyToPoint20(pointTransformMatrix, { x: p.x, y: p.y });
|
|
78957
|
-
return new Xy7(transformed.x, transformed.y);
|
|
79137
|
+
if (pcbPad.shape === "polygon") {
|
|
79138
|
+
padPrimitives = createFilledPolygonPrimitives({
|
|
79139
|
+
contours: [pcbPad.points],
|
|
79140
|
+
center: { x: padX, y: padY }
|
|
78958
79141
|
});
|
|
78959
|
-
const grPoly = new PadPrimitiveGrPoly;
|
|
78960
|
-
grPoly.contours = [new Pts7(relativePoints)];
|
|
78961
|
-
grPoly.width = 0;
|
|
78962
|
-
grPoly.filled = true;
|
|
78963
|
-
padPrimitives = new PadPrimitives;
|
|
78964
|
-
padPrimitives.addGraphic(grPoly);
|
|
78965
79142
|
padShape = "custom";
|
|
78966
79143
|
padOptions = new PadOptions;
|
|
78967
79144
|
padOptions.anchor = "circle";
|
|
78968
79145
|
padSize = [0.2, 0.2];
|
|
78969
|
-
} else
|
|
78970
|
-
const
|
|
78971
|
-
|
|
78972
|
-
|
|
78973
|
-
|
|
78974
|
-
|
|
78975
|
-
padShape = "rect";
|
|
78976
|
-
}
|
|
78977
|
-
padSize = [pcbPad.width, pcbPad.height];
|
|
78978
|
-
rotation = pcbPad.ccw_rotation;
|
|
78979
|
-
} else if (pcbPad.shape === "pill") {
|
|
78980
|
-
padShape = "roundrect";
|
|
78981
|
-
padSize = [pcbPad.width, pcbPad.height];
|
|
78982
|
-
roundrect_rratio = pcbPad.radius / Math.min(pcbPad.width, pcbPad.height);
|
|
78983
|
-
} else if (pcbPad.shape === "rotated_pill") {
|
|
78984
|
-
padShape = "roundrect";
|
|
78985
|
-
padSize = [pcbPad.width, pcbPad.height];
|
|
78986
|
-
roundrect_rratio = pcbPad.radius / Math.min(pcbPad.width, pcbPad.height);
|
|
78987
|
-
rotation = pcbPad.ccw_rotation;
|
|
78988
|
-
} else if (pcbPad.shape === "rect") {
|
|
78989
|
-
const cornerRadius = pcbPad.corner_radius ?? pcbPad.rect_border_radius;
|
|
78990
|
-
if (cornerRadius) {
|
|
78991
|
-
padShape = "roundrect";
|
|
78992
|
-
roundrect_rratio = cornerRadius / Math.min(pcbPad.width, pcbPad.height);
|
|
78993
|
-
} else {
|
|
78994
|
-
padShape = "rect";
|
|
78995
|
-
}
|
|
78996
|
-
padSize = [pcbPad.width, pcbPad.height];
|
|
79146
|
+
} else {
|
|
79147
|
+
const geometry = getKicadNativePadGeometry(pcbPad);
|
|
79148
|
+
padShape = geometry.shape;
|
|
79149
|
+
padSize = geometry.size;
|
|
79150
|
+
rotation = geometry.rotation;
|
|
79151
|
+
roundrect_rratio = geometry.roundrectRatio;
|
|
78997
79152
|
}
|
|
78998
79153
|
const padData = `pad:${componentId}:${padNumber}:${rotatedPos.x},${rotatedPos.y}`;
|
|
78999
79154
|
const pad = new FootprintPad({
|
|
@@ -79004,7 +79159,6 @@ function createSmdPadFromCircuitJson({
|
|
|
79004
79159
|
size: padSize,
|
|
79005
79160
|
layers: [
|
|
79006
79161
|
`${padLayer}`,
|
|
79007
|
-
...hasSolderPaste ? [`${padLayer === "F.Cu" ? "F" : "B"}.Paste`] : [],
|
|
79008
79162
|
...pcbPad.is_covered_with_solder_mask ? [] : [`${padLayer === "F.Cu" ? "F" : "B"}.Mask`]
|
|
79009
79163
|
],
|
|
79010
79164
|
solderMaskMargin: pcbPad.soldermask_margin,
|
|
@@ -79041,7 +79195,6 @@ function convertSmdPads({
|
|
|
79041
79195
|
const resolvedPadNumber = getPhysicalPinName(sourcePort) ?? (sourcePort?.pin_number != null ? String(sourcePort.pin_number) : pinHint ? pinHint.replace(/^pin/i, "") : gridHint ?? String(padNumber));
|
|
79042
79196
|
const pad = createSmdPadFromCircuitJson({
|
|
79043
79197
|
pcbPad,
|
|
79044
|
-
hasSolderPaste: ctx.db.pcb_solder_paste.list().some((paste) => paste.pcb_smtpad_id === pcbPad.pcb_smtpad_id),
|
|
79045
79198
|
componentCenter,
|
|
79046
79199
|
padNumber: resolvedPadNumber,
|
|
79047
79200
|
componentRotation,
|
|
@@ -79067,7 +79220,7 @@ function createThruHolePadFromCircuitJson({
|
|
|
79067
79220
|
const relativeX = platedHole.x - componentCenter.x;
|
|
79068
79221
|
const relativeY = -(platedHole.y - componentCenter.y);
|
|
79069
79222
|
const rotationMatrix = componentRotation !== 0 ? rotate10(componentRotation * Math.PI / 180) : identity5();
|
|
79070
|
-
const rotatedPos =
|
|
79223
|
+
const rotatedPos = applyToPoint22(rotationMatrix, {
|
|
79071
79224
|
x: relativeX,
|
|
79072
79225
|
y: relativeY
|
|
79073
79226
|
});
|
|
@@ -79083,7 +79236,7 @@ function createThruHolePadFromCircuitJson({
|
|
|
79083
79236
|
y: platedHole.hole_offset_y ?? 0
|
|
79084
79237
|
};
|
|
79085
79238
|
if (rawOffset.x !== 0 || rawOffset.y !== 0) {
|
|
79086
|
-
const rotatedOffset =
|
|
79239
|
+
const rotatedOffset = applyToPoint22(rotationMatrix, {
|
|
79087
79240
|
x: -rawOffset.x,
|
|
79088
79241
|
y: rawOffset.y
|
|
79089
79242
|
});
|
|
@@ -79199,7 +79352,7 @@ function createNpthPadFromCircuitJson({
|
|
|
79199
79352
|
const relativeX = pcbHole.x - componentCenter.x;
|
|
79200
79353
|
const relativeY = -(pcbHole.y - componentCenter.y);
|
|
79201
79354
|
const rotationMatrix = componentRotation !== 0 ? rotate11(componentRotation * Math.PI / 180) : identity6();
|
|
79202
|
-
const rotatedPos =
|
|
79355
|
+
const rotatedPos = applyToPoint23(rotationMatrix, {
|
|
79203
79356
|
x: relativeX,
|
|
79204
79357
|
y: relativeY
|
|
79205
79358
|
});
|
|
@@ -79283,11 +79436,11 @@ function convertFabricationNotePaths(fabricationNotePaths, {
|
|
|
79283
79436
|
const endPoint = fabricationNotePath.route[index + 1];
|
|
79284
79437
|
if (!startPoint || !endPoint)
|
|
79285
79438
|
continue;
|
|
79286
|
-
const startRelative =
|
|
79439
|
+
const startRelative = applyToPoint24(rotationMatrix, {
|
|
79287
79440
|
x: startPoint.x - componentCenter.x,
|
|
79288
79441
|
y: -(startPoint.y - componentCenter.y)
|
|
79289
79442
|
});
|
|
79290
|
-
const endRelative =
|
|
79443
|
+
const endRelative = applyToPoint24(rotationMatrix, {
|
|
79291
79444
|
x: endPoint.x - componentCenter.x,
|
|
79292
79445
|
y: -(endPoint.y - componentCenter.y)
|
|
79293
79446
|
});
|
|
@@ -79304,6 +79457,94 @@ function convertFabricationNotePaths(fabricationNotePaths, {
|
|
|
79304
79457
|
}
|
|
79305
79458
|
return fpLines;
|
|
79306
79459
|
}
|
|
79460
|
+
var getSolderPasteCenter = (solderPaste) => {
|
|
79461
|
+
if ("x" in solderPaste && "y" in solderPaste) {
|
|
79462
|
+
return { x: solderPaste.x, y: solderPaste.y };
|
|
79463
|
+
}
|
|
79464
|
+
return {
|
|
79465
|
+
x: solderPaste.points.reduce((sum, point) => sum + point.x, 0) / solderPaste.points.length,
|
|
79466
|
+
y: solderPaste.points.reduce((sum, point) => sum + point.y, 0) / solderPaste.points.length
|
|
79467
|
+
};
|
|
79468
|
+
};
|
|
79469
|
+
var createSolderPastePadFromCircuitJson = ({
|
|
79470
|
+
solderPaste,
|
|
79471
|
+
componentCenter,
|
|
79472
|
+
componentRotation = 0
|
|
79473
|
+
}) => {
|
|
79474
|
+
const polygonAnchor = solderPaste.shape === "polygon" ? getSafePolygonAnchor(solderPaste.points, solderPaste.holes) : undefined;
|
|
79475
|
+
const center = polygonAnchor?.center ?? getSolderPasteCenter(solderPaste);
|
|
79476
|
+
const boardToFootprint = getBoardToFootprintTransform({
|
|
79477
|
+
footprintOrigin: componentCenter,
|
|
79478
|
+
ccwRotationDegrees: componentRotation
|
|
79479
|
+
});
|
|
79480
|
+
const position = applyToPoint25(boardToFootprint, center);
|
|
79481
|
+
let shape;
|
|
79482
|
+
let size;
|
|
79483
|
+
let rotation = 0;
|
|
79484
|
+
let roundrectRatio;
|
|
79485
|
+
let options;
|
|
79486
|
+
let customContours;
|
|
79487
|
+
if (solderPaste.shape === "oval") {
|
|
79488
|
+
shape = "custom";
|
|
79489
|
+
size = [
|
|
79490
|
+
Math.min(0.001, solderPaste.width, solderPaste.height),
|
|
79491
|
+
Math.min(0.001, solderPaste.width, solderPaste.height)
|
|
79492
|
+
];
|
|
79493
|
+
options = new PadOptions2;
|
|
79494
|
+
options.anchor = "circle";
|
|
79495
|
+
customContours = [
|
|
79496
|
+
createEllipseContour({
|
|
79497
|
+
center,
|
|
79498
|
+
width: solderPaste.width,
|
|
79499
|
+
height: solderPaste.height
|
|
79500
|
+
})
|
|
79501
|
+
];
|
|
79502
|
+
} else if (solderPaste.shape === "polygon") {
|
|
79503
|
+
if (!polygonAnchor) {
|
|
79504
|
+
throw new Error("Solder-paste polygon is missing its anchor geometry");
|
|
79505
|
+
}
|
|
79506
|
+
shape = "custom";
|
|
79507
|
+
size = [polygonAnchor.diameter, polygonAnchor.diameter];
|
|
79508
|
+
options = new PadOptions2;
|
|
79509
|
+
options.anchor = "circle";
|
|
79510
|
+
customContours = solderPaste.holes?.length ? polygonAnchor.triangles : [solderPaste.points];
|
|
79511
|
+
} else {
|
|
79512
|
+
const geometry = getKicadNativePadGeometry(solderPaste);
|
|
79513
|
+
shape = geometry.shape;
|
|
79514
|
+
size = geometry.size;
|
|
79515
|
+
rotation = geometry.rotation;
|
|
79516
|
+
roundrectRatio = geometry.roundrectRatio;
|
|
79517
|
+
}
|
|
79518
|
+
const layer = solderPaste.layer === "bottom" ? "B.Paste" : "F.Paste";
|
|
79519
|
+
const pad = new FootprintPad4({
|
|
79520
|
+
number: "",
|
|
79521
|
+
padType: "smd",
|
|
79522
|
+
shape,
|
|
79523
|
+
at: [position.x, position.y, rotation],
|
|
79524
|
+
size,
|
|
79525
|
+
layers: [layer],
|
|
79526
|
+
roundrectRatio,
|
|
79527
|
+
uuid: generateDeterministicUuid(`solder_paste:${solderPaste.pcb_solder_paste_id}`)
|
|
79528
|
+
});
|
|
79529
|
+
if (options)
|
|
79530
|
+
pad.options = options;
|
|
79531
|
+
if (customContours) {
|
|
79532
|
+
pad.primitives = createFilledPolygonPrimitives({
|
|
79533
|
+
contours: customContours,
|
|
79534
|
+
center
|
|
79535
|
+
});
|
|
79536
|
+
}
|
|
79537
|
+
return pad;
|
|
79538
|
+
};
|
|
79539
|
+
var convertSolderPaste = ({
|
|
79540
|
+
solderPaste,
|
|
79541
|
+
componentCenter,
|
|
79542
|
+
componentRotation = 0
|
|
79543
|
+
}) => solderPaste.map((aperture) => createSolderPastePadFromCircuitJson({
|
|
79544
|
+
solderPaste: aperture,
|
|
79545
|
+
componentCenter,
|
|
79546
|
+
componentRotation
|
|
79547
|
+
}));
|
|
79307
79548
|
var AddFootprintsStage = class extends ConverterStage {
|
|
79308
79549
|
componentsProcessed = 0;
|
|
79309
79550
|
pcbComponents = [];
|
|
@@ -79379,7 +79620,7 @@ var AddFootprintsStage = class extends ConverterStage {
|
|
|
79379
79620
|
const cadComponent = this.getCadComponentForPcbComponent(component.pcb_component_id);
|
|
79380
79621
|
const footprintName = sourceComponent ? getKicadCompatibleComponentName(sourceComponent, cadComponent) : "Unknown";
|
|
79381
79622
|
const footprintOrigin = component.footprint_origin ?? component.center;
|
|
79382
|
-
const transformedPos =
|
|
79623
|
+
const transformedPos = applyToPoint26(c2kMatPcb, {
|
|
79383
79624
|
x: footprintOrigin.x,
|
|
79384
79625
|
y: footprintOrigin.y
|
|
79385
79626
|
});
|
|
@@ -79429,6 +79670,18 @@ var AddFootprintsStage = class extends ConverterStage {
|
|
|
79429
79670
|
getNetInfo
|
|
79430
79671
|
}, this.ctx);
|
|
79431
79672
|
fpPads.push(...smdPads);
|
|
79673
|
+
const pcbSolderPaste = this.ctx.db.pcb_solder_paste?.list().filter((paste) => {
|
|
79674
|
+
if (paste.pcb_component_id === component.pcb_component_id) {
|
|
79675
|
+
return true;
|
|
79676
|
+
}
|
|
79677
|
+
const linkedPad = paste.pcb_smtpad_id ? this.ctx.db.pcb_smtpad.get(paste.pcb_smtpad_id) : undefined;
|
|
79678
|
+
return !paste.pcb_component_id && linkedPad?.pcb_component_id === component.pcb_component_id;
|
|
79679
|
+
}) || [];
|
|
79680
|
+
fpPads.push(...convertSolderPaste({
|
|
79681
|
+
solderPaste: pcbSolderPaste,
|
|
79682
|
+
componentCenter: footprintOrigin,
|
|
79683
|
+
componentRotation: component.rotation || 0
|
|
79684
|
+
}));
|
|
79432
79685
|
const pcbPlatedHoles = this.ctx.db.pcb_plated_hole?.list().filter((hole) => hole.pcb_component_id === component.pcb_component_id) || [];
|
|
79433
79686
|
const { pads: thruHolePads } = convertPlatedHoles({
|
|
79434
79687
|
platedHoles: pcbPlatedHoles,
|
|
@@ -79628,8 +79881,8 @@ var AddTracesStage = class extends ConverterStage {
|
|
|
79628
79881
|
if (!startPosition || !endPosition) {
|
|
79629
79882
|
throw new Error(`Unable to convert pcb_trace route segment ${trace.pcb_trace_id ?? this.tracesProcessed}:${i} to KiCad segment`);
|
|
79630
79883
|
}
|
|
79631
|
-
const transformedStart =
|
|
79632
|
-
const transformedEnd =
|
|
79884
|
+
const transformedStart = applyToPoint27(c2kMatPcb, startPosition);
|
|
79885
|
+
const transformedEnd = applyToPoint27(c2kMatPcb, endPosition);
|
|
79633
79886
|
if (transformedStart.x === transformedEnd.x && transformedStart.y === transformedEnd.y) {
|
|
79634
79887
|
continue;
|
|
79635
79888
|
}
|
|
@@ -79712,6 +79965,11 @@ var createViaTenting = (via, board) => {
|
|
|
79712
79965
|
};
|
|
79713
79966
|
var DEFAULT_VIA_OUTER_DIAMETER = 0.8;
|
|
79714
79967
|
var DEFAULT_VIA_HOLE_DIAMETER = 0.4;
|
|
79968
|
+
var VIA_POSITION_TOLERANCE = 0.000001;
|
|
79969
|
+
var getViaPositionCell = (via) => ({
|
|
79970
|
+
x: Math.floor(via.x / VIA_POSITION_TOLERANCE),
|
|
79971
|
+
y: Math.floor(via.y / VIA_POSITION_TOLERANCE)
|
|
79972
|
+
});
|
|
79715
79973
|
var AddViasStage = class extends ConverterStage {
|
|
79716
79974
|
boardOwnerMap;
|
|
79717
79975
|
viasProcessed = 0;
|
|
@@ -79725,7 +79983,8 @@ var AddViasStage = class extends ConverterStage {
|
|
|
79725
79983
|
const seenRouteViaKeys = /* @__PURE__ */ new Set;
|
|
79726
79984
|
const standaloneViasByPosition = /* @__PURE__ */ new Map;
|
|
79727
79985
|
for (const via of standaloneVias) {
|
|
79728
|
-
const
|
|
79986
|
+
const { x, y } = getViaPositionCell(via);
|
|
79987
|
+
const positionKey = `${x}:${y}`;
|
|
79729
79988
|
const viasAtPosition = standaloneViasByPosition.get(positionKey) ?? [];
|
|
79730
79989
|
viasAtPosition.push(via);
|
|
79731
79990
|
standaloneViasByPosition.set(positionKey, viasAtPosition);
|
|
@@ -79744,8 +80003,14 @@ var AddViasStage = class extends ConverterStage {
|
|
|
79744
80003
|
tented_on_top: point.tented_on_top,
|
|
79745
80004
|
tented_on_bottom: point.tented_on_bottom
|
|
79746
80005
|
})).filter((via) => {
|
|
79747
|
-
const
|
|
79748
|
-
|
|
80006
|
+
const { x, y } = getViaPositionCell(via);
|
|
80007
|
+
const physicalVias = [];
|
|
80008
|
+
for (let dx = -1;dx <= 1; dx++) {
|
|
80009
|
+
for (let dy = -1;dy <= 1; dy++) {
|
|
80010
|
+
physicalVias.push(...standaloneViasByPosition.get(`${x + dx}:${y + dy}`) ?? []);
|
|
80011
|
+
}
|
|
80012
|
+
}
|
|
80013
|
+
if (physicalVias.some((physicalVia) => {
|
|
79749
80014
|
const sameTrace = physicalVia.pcb_trace_id !== undefined && physicalVia.pcb_trace_id === via.pcb_trace_id;
|
|
79750
80015
|
const physicalConnection = physicalVia.net?.id ?? physicalVia.subcircuit_connectivity_map_key;
|
|
79751
80016
|
const routeConnection = via.net?.id ?? via.subcircuit_connectivity_map_key;
|
|
@@ -79755,7 +80020,11 @@ var AddViasStage = class extends ConverterStage {
|
|
|
79755
80020
|
} else if (!sameTrace) {
|
|
79756
80021
|
return false;
|
|
79757
80022
|
}
|
|
79758
|
-
return isRouteViaCoveredByPhysicalVia(
|
|
80023
|
+
return isRouteViaCoveredByPhysicalVia({
|
|
80024
|
+
viaWithLayers: physicalVia,
|
|
80025
|
+
routeVia: via,
|
|
80026
|
+
positionTolerance: VIA_POSITION_TOLERANCE
|
|
80027
|
+
});
|
|
79759
80028
|
})) {
|
|
79760
80029
|
return false;
|
|
79761
80030
|
}
|
|
@@ -79814,10 +80083,10 @@ var AddViasStage = class extends ConverterStage {
|
|
|
79814
80083
|
this.finished = true;
|
|
79815
80084
|
return;
|
|
79816
80085
|
}
|
|
79817
|
-
this.boardOwnerMap ??=
|
|
80086
|
+
this.boardOwnerMap ??= createBoardOwnerMap2(this.input);
|
|
79818
80087
|
const boardOwnerId = via.pcb_via_id ?? via.pcb_trace_id;
|
|
79819
80088
|
const board = boardOwnerId ? this.boardOwnerMap.get(boardOwnerId) : undefined;
|
|
79820
|
-
const transformedPos =
|
|
80089
|
+
const transformedPos = applyToPoint28(c2kMatPcb, {
|
|
79821
80090
|
x: via.x,
|
|
79822
80091
|
y: via.y
|
|
79823
80092
|
});
|
|
@@ -79843,6 +80112,34 @@ var AddViasStage = class extends ConverterStage {
|
|
|
79843
80112
|
return this.ctx.kicadPcb;
|
|
79844
80113
|
}
|
|
79845
80114
|
};
|
|
80115
|
+
var normalizePolygonPoints = (points, origin) => points.map((point) => ({
|
|
80116
|
+
x: point.x - origin.x,
|
|
80117
|
+
y: point.y - origin.y
|
|
80118
|
+
}));
|
|
80119
|
+
var getSolderPasteLibraryLink = (paste) => {
|
|
80120
|
+
const prefix = `tscircuit:solderpaste_${paste.layer}_${paste.shape}`;
|
|
80121
|
+
switch (paste.shape) {
|
|
80122
|
+
case "circle":
|
|
80123
|
+
return `${prefix}_diameter${paste.radius * 2}mm`;
|
|
80124
|
+
case "rect":
|
|
80125
|
+
case "oval":
|
|
80126
|
+
return `${prefix}_width${paste.width}mm_height${paste.height}mm`;
|
|
80127
|
+
case "rotated_rect":
|
|
80128
|
+
return `${prefix}_width${paste.width}mm_height${paste.height}mm_ccwRotation${paste.ccw_rotation}deg`;
|
|
80129
|
+
case "pill":
|
|
80130
|
+
return `${prefix}_width${paste.width}mm_height${paste.height}mm_radius${getResolvedPillRadius(paste)}mm`;
|
|
80131
|
+
case "rotated_pill":
|
|
80132
|
+
return `${prefix}_width${paste.width}mm_height${paste.height}mm_radius${getResolvedPillRadius(paste)}mm_ccwRotation${paste.ccw_rotation}deg`;
|
|
80133
|
+
case "polygon": {
|
|
80134
|
+
const origin = paste.points[0] ?? { x: 0, y: 0 };
|
|
80135
|
+
const geometry = JSON.stringify({
|
|
80136
|
+
points: normalizePolygonPoints(paste.points, origin),
|
|
80137
|
+
holes: paste.holes?.map((hole) => normalizePolygonPoints(hole, origin))
|
|
80138
|
+
});
|
|
80139
|
+
return `${prefix}_${generateDeterministicUuid(geometry)}`;
|
|
80140
|
+
}
|
|
80141
|
+
}
|
|
80142
|
+
};
|
|
79846
80143
|
var AddStandalonePcbElements = class extends ConverterStage {
|
|
79847
80144
|
unprocessedElements = [];
|
|
79848
80145
|
constructor(input, ctx) {
|
|
@@ -79850,7 +80147,8 @@ var AddStandalonePcbElements = class extends ConverterStage {
|
|
|
79850
80147
|
this.unprocessedElements = [
|
|
79851
80148
|
...this.ctx.db.pcb_hole.list().filter((hole) => !hole.pcb_component_id),
|
|
79852
80149
|
...this.ctx.db.pcb_plated_hole.list().filter((hole) => !hole.pcb_component_id),
|
|
79853
|
-
...this.ctx.db.pcb_smtpad.list().filter((pad) => !pad.pcb_component_id)
|
|
80150
|
+
...this.ctx.db.pcb_smtpad.list().filter((pad) => !pad.pcb_component_id),
|
|
80151
|
+
...this.ctx.db.pcb_solder_paste.list().filter((paste) => !paste.pcb_component_id && !paste.pcb_smtpad_id)
|
|
79854
80152
|
];
|
|
79855
80153
|
}
|
|
79856
80154
|
_step() {
|
|
@@ -79870,21 +80168,45 @@ var AddStandalonePcbElements = class extends ConverterStage {
|
|
|
79870
80168
|
const pcbPad = elm;
|
|
79871
80169
|
const padCenter = this.getPcbSmtPadCenter(pcbPad);
|
|
79872
80170
|
const footprintSeed = `standalone_smtpad:${pcbPad.pcb_smtpad_id}:${padCenter.x},${padCenter.y}`;
|
|
79873
|
-
const kicadPos =
|
|
80171
|
+
const kicadPos = applyToPoint29(c2kMatPcb, padCenter);
|
|
79874
80172
|
const footprint = new Footprint5({
|
|
79875
80173
|
libraryLink: this.getSmtPadLibraryLink(pcbPad),
|
|
79876
80174
|
layer: "F.Cu",
|
|
79877
80175
|
at: [kicadPos.x, kicadPos.y, 0],
|
|
79878
80176
|
uuid: generateDeterministicUuid(footprintSeed)
|
|
79879
80177
|
});
|
|
80178
|
+
const linkedSolderPaste = this.ctx.db.pcb_solder_paste.list().filter((paste) => paste.pcb_smtpad_id === pcbPad.pcb_smtpad_id);
|
|
79880
80179
|
footprint.fpPads = [
|
|
79881
80180
|
createSmdPadFromCircuitJson({
|
|
79882
80181
|
pcbPad,
|
|
79883
|
-
hasSolderPaste: this.ctx.db.pcb_solder_paste.list().some((paste) => paste.pcb_smtpad_id === pcbPad.pcb_smtpad_id),
|
|
79884
80182
|
componentCenter: padCenter,
|
|
79885
80183
|
padNumber: 1,
|
|
79886
80184
|
componentRotation: 0,
|
|
79887
80185
|
componentId: pcbPad.pcb_smtpad_id
|
|
80186
|
+
}),
|
|
80187
|
+
...linkedSolderPaste.map((solderPaste) => createSolderPastePadFromCircuitJson({
|
|
80188
|
+
solderPaste,
|
|
80189
|
+
componentCenter: padCenter
|
|
80190
|
+
}))
|
|
80191
|
+
];
|
|
80192
|
+
applyInferredFootprintType(footprint);
|
|
80193
|
+
const footprints = kicadPcb.footprints;
|
|
80194
|
+
footprints.push(footprint);
|
|
80195
|
+
kicadPcb.footprints = footprints;
|
|
80196
|
+
} else if (elm.type === "pcb_solder_paste") {
|
|
80197
|
+
const center = getSolderPasteCenter(elm);
|
|
80198
|
+
const footprintSeed = `standalone_solder_paste:${elm.pcb_solder_paste_id}`;
|
|
80199
|
+
const kicadPos = applyToPoint29(c2kMatPcb, center);
|
|
80200
|
+
const footprint = new Footprint5({
|
|
80201
|
+
libraryLink: getSolderPasteLibraryLink(elm),
|
|
80202
|
+
layer: elm.layer === "bottom" ? "B.Cu" : "F.Cu",
|
|
80203
|
+
at: [kicadPos.x, kicadPos.y, 0],
|
|
80204
|
+
uuid: generateDeterministicUuid(footprintSeed)
|
|
80205
|
+
});
|
|
80206
|
+
footprint.fpPads = [
|
|
80207
|
+
createSolderPastePadFromCircuitJson({
|
|
80208
|
+
solderPaste: elm,
|
|
80209
|
+
componentCenter: center
|
|
79888
80210
|
})
|
|
79889
80211
|
];
|
|
79890
80212
|
applyInferredFootprintType(footprint);
|
|
@@ -79894,7 +80216,7 @@ var AddStandalonePcbElements = class extends ConverterStage {
|
|
|
79894
80216
|
} else if (elm.type === "pcb_hole") {
|
|
79895
80217
|
const hole = elm;
|
|
79896
80218
|
const footprintSeed = `standalone_hole:${hole.pcb_hole_id}:${hole.x},${hole.y}`;
|
|
79897
|
-
const kicadPos =
|
|
80219
|
+
const kicadPos = applyToPoint29(c2kMatPcb, { x: hole.x, y: hole.y });
|
|
79898
80220
|
const libraryLink = this.getHoleLibraryLink(hole);
|
|
79899
80221
|
const footprint = new Footprint5({
|
|
79900
80222
|
libraryLink,
|
|
@@ -79917,7 +80239,7 @@ var AddStandalonePcbElements = class extends ConverterStage {
|
|
|
79917
80239
|
} else if (elm.type === "pcb_plated_hole") {
|
|
79918
80240
|
const hole = elm;
|
|
79919
80241
|
const footprintSeed = `standalone_plated_hole:${hole.pcb_plated_hole_id}:${hole.x},${hole.y}`;
|
|
79920
|
-
const kicadPos =
|
|
80242
|
+
const kicadPos = applyToPoint29(c2kMatPcb, { x: hole.x, y: hole.y });
|
|
79921
80243
|
const libraryLink = this.getPlatedHoleLibraryLink(hole);
|
|
79922
80244
|
const footprint = new Footprint5({
|
|
79923
80245
|
libraryLink,
|
|
@@ -80015,7 +80337,7 @@ function createFabricationNoteTextFromCircuitJson({
|
|
|
80015
80337
|
if (!textElement.text || !textElement.anchor_position) {
|
|
80016
80338
|
return null;
|
|
80017
80339
|
}
|
|
80018
|
-
const transformedPos =
|
|
80340
|
+
const transformedPos = applyToPoint30(c2kMatPcb, {
|
|
80019
80341
|
x: textElement.anchor_position.x,
|
|
80020
80342
|
y: textElement.anchor_position.y
|
|
80021
80343
|
});
|
|
@@ -80056,7 +80378,8 @@ function createFabricationNoteTextFromCircuitJson({
|
|
|
80056
80378
|
if (anchorAlignment !== "center") {
|
|
80057
80379
|
textEffects.justify = justify;
|
|
80058
80380
|
}
|
|
80059
|
-
const
|
|
80381
|
+
const rotation = textElement.type === "pcb_fabrication_note_text" ? textElement.ccw_rotation ?? 0 : 0;
|
|
80382
|
+
const position = new At3([transformedPos.x, transformedPos.y, rotation]);
|
|
80060
80383
|
const grText = new GrText({
|
|
80061
80384
|
text: textElement.text,
|
|
80062
80385
|
layer: kicadLayer,
|
|
@@ -80073,7 +80396,7 @@ function createGrTextFromCircuitJson({
|
|
|
80073
80396
|
if (!textElement.text || !textElement.anchor_position) {
|
|
80074
80397
|
return null;
|
|
80075
80398
|
}
|
|
80076
|
-
const transformedPos =
|
|
80399
|
+
const transformedPos = applyToPoint31(c2kMatPcb, {
|
|
80077
80400
|
x: textElement.anchor_position.x,
|
|
80078
80401
|
y: textElement.anchor_position.y
|
|
80079
80402
|
});
|
|
@@ -80110,6 +80433,9 @@ function createGrTextFromCircuitJson({
|
|
|
80110
80433
|
grText.position = position;
|
|
80111
80434
|
return grText;
|
|
80112
80435
|
}
|
|
80436
|
+
var KICAD_PCB_UNITS_PER_MM = 1e6;
|
|
80437
|
+
var roundBoardCoordinate = (coordinateMm) => Math.round(coordinateMm * KICAD_PCB_UNITS_PER_MM) / KICAD_PCB_UNITS_PER_MM;
|
|
80438
|
+
var roundPolygonToKicadPrecision = (geometry) => geometry.map((polygon) => polygon.map((ring) => ring.map(([x, y]) => [roundBoardCoordinate(x), roundBoardCoordinate(y)])));
|
|
80113
80439
|
var pointsAreEqual = (a, b) => !!a && !!b && a.x === b.x && a.y === b.y;
|
|
80114
80440
|
var normalizeOutlineCorners = (corners) => {
|
|
80115
80441
|
const dedupedCorners = [];
|
|
@@ -80125,6 +80451,13 @@ var normalizeOutlineCorners = (corners) => {
|
|
|
80125
80451
|
return dedupedCorners;
|
|
80126
80452
|
};
|
|
80127
80453
|
var DEFAULT_EDGE_CUTS_WIDTH = 0.1;
|
|
80454
|
+
var toKicadPoint = (point, c2kMatPcb) => {
|
|
80455
|
+
const transformed = applyToPoint32(c2kMatPcb, point);
|
|
80456
|
+
return [
|
|
80457
|
+
roundBoardCoordinate(transformed.x),
|
|
80458
|
+
roundBoardCoordinate(transformed.y)
|
|
80459
|
+
];
|
|
80460
|
+
};
|
|
80128
80461
|
var appendGraphicLine = (kicadPcb, grLine) => {
|
|
80129
80462
|
const graphicLines = kicadPcb.graphicLines;
|
|
80130
80463
|
graphicLines.push(grLine);
|
|
@@ -80133,18 +80466,10 @@ var appendGraphicLine = (kicadPcb, grLine) => {
|
|
|
80133
80466
|
var rotatePointAroundOrigin = (point, rotationDegrees = 0) => {
|
|
80134
80467
|
if (!rotationDegrees)
|
|
80135
80468
|
return point;
|
|
80136
|
-
return
|
|
80469
|
+
return applyToPoint32(rotate13(rotationDegrees * Math.PI / 180), point);
|
|
80137
80470
|
};
|
|
80138
80471
|
var getRectCutoutCorners = (cutout) => {
|
|
80139
|
-
|
|
80140
|
-
const halfHeight = cutout.height / 2;
|
|
80141
|
-
const localCorners = [
|
|
80142
|
-
{ x: -halfWidth, y: -halfHeight },
|
|
80143
|
-
{ x: halfWidth, y: -halfHeight },
|
|
80144
|
-
{ x: halfWidth, y: halfHeight },
|
|
80145
|
-
{ x: -halfWidth, y: halfHeight }
|
|
80146
|
-
];
|
|
80147
|
-
return localCorners.map((point) => {
|
|
80472
|
+
return getRectanglePoints(cutout).map((point) => {
|
|
80148
80473
|
const rotatedPoint = rotatePointAroundOrigin(point, cutout.rotation);
|
|
80149
80474
|
return {
|
|
80150
80475
|
x: rotatedPoint.x + cutout.center.x,
|
|
@@ -80171,11 +80496,11 @@ var AddGraphicsStage = class extends ConverterStage {
|
|
|
80171
80496
|
const endPoint = path.route[i + 1];
|
|
80172
80497
|
if (!startPoint || !endPoint)
|
|
80173
80498
|
continue;
|
|
80174
|
-
const transformedStart =
|
|
80499
|
+
const transformedStart = applyToPoint32(c2kMatPcb, {
|
|
80175
80500
|
x: startPoint.x,
|
|
80176
80501
|
y: startPoint.y
|
|
80177
80502
|
});
|
|
80178
|
-
const transformedEnd =
|
|
80503
|
+
const transformedEnd = applyToPoint32(c2kMatPcb, {
|
|
80179
80504
|
x: endPoint.x,
|
|
80180
80505
|
y: endPoint.y
|
|
80181
80506
|
});
|
|
@@ -80221,15 +80546,14 @@ var AddGraphicsStage = class extends ConverterStage {
|
|
|
80221
80546
|
kicadPcb.graphicTexts = graphicTexts;
|
|
80222
80547
|
}
|
|
80223
80548
|
}
|
|
80224
|
-
const
|
|
80225
|
-
|
|
80226
|
-
|
|
80227
|
-
|
|
80228
|
-
|
|
80229
|
-
|
|
80230
|
-
}
|
|
80549
|
+
const outlineElements = [
|
|
80550
|
+
...this.ctx.db.pcb_panel.list(),
|
|
80551
|
+
...this.ctx.db.pcb_board.list()
|
|
80552
|
+
];
|
|
80553
|
+
const outlinePolys = [];
|
|
80554
|
+
for (const board of outlineElements) {
|
|
80231
80555
|
let corners;
|
|
80232
|
-
if (board.outline && board.outline.length > 0) {
|
|
80556
|
+
if (board.type === "pcb_board" && board.outline && board.outline.length > 0) {
|
|
80233
80557
|
corners = normalizeOutlineCorners(board.outline);
|
|
80234
80558
|
} else {
|
|
80235
80559
|
const halfWidth = board.width ? board.width / 2 : 0;
|
|
@@ -80241,25 +80565,43 @@ var AddGraphicsStage = class extends ConverterStage {
|
|
|
80241
80565
|
{ x: board.center.x - halfWidth, y: board.center.y + halfHeight }
|
|
80242
80566
|
];
|
|
80243
80567
|
}
|
|
80568
|
+
outlinePolys.push([
|
|
80569
|
+
[corners.map((point) => toKicadPoint(point, c2kMatPcb))]
|
|
80570
|
+
]);
|
|
80571
|
+
}
|
|
80572
|
+
const [firstOutline, ...otherOutlines] = outlinePolys;
|
|
80573
|
+
if (firstOutline) {
|
|
80244
80574
|
const pcbCutouts2 = this.ctx.db.pcb_cutout?.list() || [];
|
|
80245
80575
|
const cutoutPolys = [];
|
|
80246
80576
|
for (const cutout of pcbCutouts2) {
|
|
80247
80577
|
if (cutout.shape === "rect") {
|
|
80248
80578
|
const cutoutCorners = getRectCutoutCorners(cutout);
|
|
80249
|
-
cutoutPolys.push([
|
|
80579
|
+
cutoutPolys.push([
|
|
80580
|
+
[cutoutCorners.map((point) => toKicadPoint(point, c2kMatPcb))]
|
|
80581
|
+
]);
|
|
80250
80582
|
} else if (cutout.shape === "circle") {
|
|
80251
|
-
cutoutPolys.push([
|
|
80583
|
+
cutoutPolys.push([
|
|
80584
|
+
[
|
|
80585
|
+
circleToPolygon(cutout.center, cutout.radius).map(([x, y]) => toKicadPoint({ x, y }, c2kMatPcb))
|
|
80586
|
+
]
|
|
80587
|
+
]);
|
|
80252
80588
|
} else if (cutout.shape === "polygon") {
|
|
80253
|
-
cutoutPolys.push([
|
|
80589
|
+
cutoutPolys.push([
|
|
80590
|
+
[cutout.points.map((point) => toKicadPoint(point, c2kMatPcb))]
|
|
80591
|
+
]);
|
|
80254
80592
|
}
|
|
80255
80593
|
}
|
|
80256
|
-
let boardGeom =
|
|
80594
|
+
let boardGeom = otherOutlines.length > 0 ? import_polygon_clipping.default.union(firstOutline, ...otherOutlines) : firstOutline;
|
|
80257
80595
|
if (cutoutPolys.length > 0) {
|
|
80258
|
-
boardGeom = import_polygon_clipping.default.difference(boardGeom, ...cutoutPolys);
|
|
80596
|
+
boardGeom = import_polygon_clipping.default.difference(roundPolygonToKicadPrecision(boardGeom), ...cutoutPolys);
|
|
80259
80597
|
}
|
|
80598
|
+
boardGeom = roundPolygonToKicadPrecision(boardGeom);
|
|
80260
80599
|
for (const poly of boardGeom) {
|
|
80261
80600
|
for (const ring of poly) {
|
|
80262
|
-
const transformedRing = ring.map((
|
|
80601
|
+
const transformedRing = ring.map(([x, y]) => ({
|
|
80602
|
+
x,
|
|
80603
|
+
y
|
|
80604
|
+
}));
|
|
80263
80605
|
for (let i = 0;i < transformedRing.length; i++) {
|
|
80264
80606
|
const start = transformedRing[i];
|
|
80265
80607
|
const end = transformedRing[(i + 1) % transformedRing.length];
|
|
@@ -80288,8 +80630,8 @@ var AddGraphicsStage = class extends ConverterStage {
|
|
|
80288
80630
|
const endPoint = cutout.route[i + 1];
|
|
80289
80631
|
if (!startPoint || !endPoint)
|
|
80290
80632
|
continue;
|
|
80291
|
-
const transformedStart =
|
|
80292
|
-
const transformedEnd =
|
|
80633
|
+
const transformedStart = applyToPoint32(c2kMatPcb, startPoint);
|
|
80634
|
+
const transformedEnd = applyToPoint32(c2kMatPcb, endPoint);
|
|
80293
80635
|
appendGraphicLine(kicadPcb, new GrLine({
|
|
80294
80636
|
start: transformedStart,
|
|
80295
80637
|
end: transformedEnd,
|
|
@@ -80324,7 +80666,7 @@ var CircuitJsonToKicadPcbConverter = class {
|
|
|
80324
80666
|
generator: "circuit-json-to-kicad",
|
|
80325
80667
|
generatorVersion: "0.0.1"
|
|
80326
80668
|
}),
|
|
80327
|
-
c2kMatPcb:
|
|
80669
|
+
c2kMatPcb: compose11(translate11(KICAD_PCB_CENTER_X, KICAD_PCB_CENTER_Y), scale8(CIRCUIT_JSON_TO_MM_SCALE, -CIRCUIT_JSON_TO_MM_SCALE)),
|
|
80328
80670
|
projectName: options?.projectName,
|
|
80329
80671
|
edgeCutsWidth: options?.edgeCutsWidth,
|
|
80330
80672
|
pcbModel3dSourcePaths: []
|
|
@@ -80410,6 +80752,46 @@ var CircuitJsonToKicadProConverter = class {
|
|
|
80410
80752
|
trackWidth: minTrackWidth
|
|
80411
80753
|
})
|
|
80412
80754
|
];
|
|
80755
|
+
const sourceNets = this.ctx.db.source_net?.list() ?? [];
|
|
80756
|
+
const netClassNameByTraceWidth = /* @__PURE__ */ new Map([
|
|
80757
|
+
[minTrackWidth, "Default"]
|
|
80758
|
+
]);
|
|
80759
|
+
const explicitTraceWidths = Array.from(new Set(sourceNets.flatMap((sourceNet) => sourceNet.trace_width === undefined ? [] : [sourceNet.trace_width]))).sort((a, b) => a - b);
|
|
80760
|
+
for (const traceWidth of explicitTraceWidths) {
|
|
80761
|
+
if (netClassNameByTraceWidth.has(traceWidth))
|
|
80762
|
+
continue;
|
|
80763
|
+
const netClassName = `Trace Width ${traceWidth} mm`;
|
|
80764
|
+
netClasses.push(this.createBaseNetClass({
|
|
80765
|
+
name: netClassName,
|
|
80766
|
+
viaDiameter: minViaDiameter,
|
|
80767
|
+
viaDrill: minViaDrill,
|
|
80768
|
+
clearance: minTraceToPadClearance,
|
|
80769
|
+
trackWidth: traceWidth
|
|
80770
|
+
}));
|
|
80771
|
+
netClassNameByTraceWidth.set(traceWidth, netClassName);
|
|
80772
|
+
}
|
|
80773
|
+
const netClassByNetName = /* @__PURE__ */ new Map;
|
|
80774
|
+
const boardOwnerMap = this.ctx.db.pcb_board.list().length > 1 ? createBoardOwnerMap3(this.ctx.circuitJson) : undefined;
|
|
80775
|
+
const sourceNetsWithTraceWidths = sourceNets.filter((sourceNet) => sourceNet.trace_width !== undefined).map((sourceNet) => {
|
|
80776
|
+
const connectivityKey = sourceNet.subcircuit_connectivity_map_key || sourceNet.source_net_id;
|
|
80777
|
+
return {
|
|
80778
|
+
sourceNet,
|
|
80779
|
+
netName: resolveKicadPcbNetName({
|
|
80780
|
+
candidateName: sourceNet.name || sourceNet.source_net_id,
|
|
80781
|
+
connectivityKey,
|
|
80782
|
+
boardId: boardOwnerMap?.get(sourceNet.subcircuit_id ?? "")?.pcb_board_id
|
|
80783
|
+
})
|
|
80784
|
+
};
|
|
80785
|
+
}).sort((a, b) => a.netName.localeCompare(b.netName) || a.sourceNet.source_net_id.localeCompare(b.sourceNet.source_net_id));
|
|
80786
|
+
for (const { sourceNet, netName } of sourceNetsWithTraceWidths) {
|
|
80787
|
+
const netClassName = netClassNameByTraceWidth.get(sourceNet.trace_width);
|
|
80788
|
+
const existingNetClassName = netClassByNetName.get(netName);
|
|
80789
|
+
if (existingNetClassName !== undefined && existingNetClassName !== netClassName) {
|
|
80790
|
+
throw new Error(`Cannot preserve conflicting trace widths for KiCad net "${netName}": ${existingNetClassName} and ${netClassName}`);
|
|
80791
|
+
}
|
|
80792
|
+
netClassByNetName.set(netName, netClassName);
|
|
80793
|
+
}
|
|
80794
|
+
const netclassPatterns = Array.from(netClassByNetName, ([pattern, netclass]) => ({ pattern, netclass }));
|
|
80413
80795
|
this.project = {
|
|
80414
80796
|
version: 1,
|
|
80415
80797
|
head: {
|
|
@@ -80441,10 +80823,11 @@ var CircuitJsonToKicadProConverter = class {
|
|
|
80441
80823
|
},
|
|
80442
80824
|
net_settings: {
|
|
80443
80825
|
meta: {
|
|
80444
|
-
version:
|
|
80826
|
+
version: 3
|
|
80445
80827
|
},
|
|
80446
|
-
last_net_id:
|
|
80447
|
-
classes: netClasses
|
|
80828
|
+
last_net_id: 0,
|
|
80829
|
+
classes: netClasses,
|
|
80830
|
+
netclass_patterns: netclassPatterns
|
|
80448
80831
|
},
|
|
80449
80832
|
pcbnew: {
|
|
80450
80833
|
page_layout_descr_file: "",
|