@tscircuit/cli 0.1.2433 → 0.1.2435
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 +2 -2
- package/dist/lib/index.js +618 -253
- package/package.json +3 -3
package/dist/lib/index.js
CHANGED
|
@@ -74334,6 +74334,7 @@ import {
|
|
|
74334
74334
|
} from "kicadts";
|
|
74335
74335
|
import { applyToPoint as applyToPoint6 } from "transformation-matrix";
|
|
74336
74336
|
import { symbols as symbols4 } from "schematic-symbols";
|
|
74337
|
+
import { NoConnect } from "kicadts";
|
|
74337
74338
|
import { formatSiUnit } from "format-si-unit";
|
|
74338
74339
|
import {
|
|
74339
74340
|
EmbeddedFonts as EmbeddedFonts2,
|
|
@@ -74362,11 +74363,11 @@ import {
|
|
|
74362
74363
|
import { Paper, Uuid as Uuid4 } from "kicadts";
|
|
74363
74364
|
import { KicadPcb as KicadPcb2 } from "kicadts";
|
|
74364
74365
|
import { cju as cju2 } from "@tscircuit/circuit-json-util";
|
|
74365
|
-
import { compose as
|
|
74366
|
+
import { compose as compose11, translate as translate11, scale as scale8 } from "transformation-matrix";
|
|
74366
74367
|
import {
|
|
74367
74368
|
Layer,
|
|
74368
|
-
Pts as
|
|
74369
|
-
Xy as
|
|
74369
|
+
Pts as Pts5,
|
|
74370
|
+
Xy as Xy5,
|
|
74370
74371
|
Zone,
|
|
74371
74372
|
ZoneConnectPads,
|
|
74372
74373
|
ZoneFill,
|
|
@@ -74375,13 +74376,16 @@ import {
|
|
|
74375
74376
|
ZonePolygon
|
|
74376
74377
|
} from "kicadts";
|
|
74377
74378
|
import {
|
|
74378
|
-
applyToPoint as
|
|
74379
|
-
compose as
|
|
74379
|
+
applyToPoint as applyToPoint10,
|
|
74380
|
+
compose as compose4,
|
|
74380
74381
|
rotate,
|
|
74381
|
-
translate as
|
|
74382
|
+
translate as translate4
|
|
74382
74383
|
} from "transformation-matrix";
|
|
74383
|
-
import {
|
|
74384
|
-
import { applyToPoint as
|
|
74384
|
+
import { PadPrimitiveGrPoly, PadPrimitives, Pts as Pts4, Xy as Xy4 } from "kicadts";
|
|
74385
|
+
import { applyToPoint as applyToPoint9, compose as compose3, scale as scale2, translate as translate3 } from "transformation-matrix";
|
|
74386
|
+
import { Pts as Pts6, Xy as Xy6, Zone as Zone2, ZoneKeepout, ZonePolygon as ZonePolygon2 } from "kicadts";
|
|
74387
|
+
import { applyToPoint as applyToPoint11 } from "transformation-matrix";
|
|
74388
|
+
var import_polygon_clipping = __toESM3(require_polygon_clipping_cjs(), 1);
|
|
74385
74389
|
import {
|
|
74386
74390
|
Paper as Paper2,
|
|
74387
74391
|
PcbLayers,
|
|
@@ -74389,10 +74393,9 @@ import {
|
|
|
74389
74393
|
PcbGeneral,
|
|
74390
74394
|
Setup
|
|
74391
74395
|
} from "kicadts";
|
|
74392
|
-
import { getElementId } from "@tscircuit/circuit-json-util";
|
|
74396
|
+
import { createBoardOwnerMap, getElementId } from "@tscircuit/circuit-json-util";
|
|
74393
74397
|
import { getFullConnectivityMapFromCircuitJson } from "circuit-json-to-connectivity-map";
|
|
74394
74398
|
import { PcbNet } from "kicadts";
|
|
74395
|
-
var import_polygon_clipping = __toESM3(require_polygon_clipping_cjs(), 1);
|
|
74396
74399
|
import { Footprint as Footprint4, FootprintModel as FootprintModel4, FootprintAttr as FootprintAttr3 } from "kicadts";
|
|
74397
74400
|
import {
|
|
74398
74401
|
parseKicadSexpr,
|
|
@@ -74405,7 +74408,7 @@ import {
|
|
|
74405
74408
|
TextEffectsFont as TextEffectsFont8
|
|
74406
74409
|
} from "kicadts";
|
|
74407
74410
|
import { FootprintAttr } from "kicadts";
|
|
74408
|
-
import { applyToPoint as
|
|
74411
|
+
import { applyToPoint as applyToPoint26 } from "transformation-matrix";
|
|
74409
74412
|
import {
|
|
74410
74413
|
Property as Property2,
|
|
74411
74414
|
TextEffects as TextEffects9,
|
|
@@ -74415,80 +74418,74 @@ import {
|
|
|
74415
74418
|
FootprintAttr as FootprintAttr2
|
|
74416
74419
|
} from "kicadts";
|
|
74417
74420
|
import { FpCircle, Stroke as Stroke5 } from "kicadts";
|
|
74418
|
-
import { applyToPoint as
|
|
74421
|
+
import { applyToPoint as applyToPoint12, identity, rotate as rotate2 } from "transformation-matrix";
|
|
74419
74422
|
import { FpCircle as FpCircle2, Stroke as Stroke6 } from "kicadts";
|
|
74420
|
-
import { applyToPoint as
|
|
74421
|
-
import { compose as
|
|
74423
|
+
import { applyToPoint as applyToPoint13 } from "transformation-matrix";
|
|
74424
|
+
import { compose as compose5, rotateDEG, scale as scale3, translate as translate5 } from "transformation-matrix";
|
|
74422
74425
|
import { FpRect as FpRect2 } from "kicadts";
|
|
74423
74426
|
import { FpPoly, FpRect, Stroke as Stroke7 } from "kicadts";
|
|
74424
|
-
import { applyToPoint as
|
|
74427
|
+
import { applyToPoint as applyToPoint14, compose as compose6, translate as translate6 } from "transformation-matrix";
|
|
74425
74428
|
import { FpRect as FpRect3 } from "kicadts";
|
|
74426
74429
|
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
74430
|
import {
|
|
74436
74431
|
applyToPoint as applyToPoint15,
|
|
74437
74432
|
compose as compose7,
|
|
74438
|
-
rotate as
|
|
74433
|
+
rotate as rotate3,
|
|
74439
74434
|
scale as scale4,
|
|
74440
74435
|
translate as translate7
|
|
74441
74436
|
} from "transformation-matrix";
|
|
74437
|
+
import { FpPoly as FpPoly5, Pts as Pts7, Stroke as Stroke9, Xy as Xy7 } from "kicadts";
|
|
74438
|
+
import {
|
|
74439
|
+
applyToPoint as applyToPoint16,
|
|
74440
|
+
compose as compose8,
|
|
74441
|
+
rotate as rotate4,
|
|
74442
|
+
scale as scale5,
|
|
74443
|
+
translate as translate8
|
|
74444
|
+
} from "transformation-matrix";
|
|
74442
74445
|
import"kicadts";
|
|
74443
74446
|
import { FpText, TextEffects as TextEffects10, TextEffectsFont as TextEffectsFont10 } from "kicadts";
|
|
74444
|
-
import { applyToPoint as
|
|
74447
|
+
import { applyToPoint as applyToPoint17, rotate as rotate5, identity as identity2 } from "transformation-matrix";
|
|
74445
74448
|
import { TextEffectsJustify as TextEffectsJustify6 } from "kicadts";
|
|
74446
74449
|
import { FpLine, Stroke as Stroke10 } from "kicadts";
|
|
74447
|
-
import { applyToPoint as
|
|
74450
|
+
import { applyToPoint as applyToPoint18, identity as identity3, rotate as rotate6 } from "transformation-matrix";
|
|
74448
74451
|
import { FpPoly as FpPoly6, Stroke as Stroke11 } from "kicadts";
|
|
74449
74452
|
import {
|
|
74450
|
-
applyToPoint as
|
|
74451
|
-
compose as
|
|
74453
|
+
applyToPoint as applyToPoint19,
|
|
74454
|
+
compose as compose9,
|
|
74452
74455
|
rotate as rotate7,
|
|
74453
|
-
scale as
|
|
74454
|
-
translate as
|
|
74456
|
+
scale as scale6,
|
|
74457
|
+
translate as translate9
|
|
74455
74458
|
} from "transformation-matrix";
|
|
74456
74459
|
import { FpText as FpText3, TextEffects as TextEffects11, TextEffectsFont as TextEffectsFont11 } from "kicadts";
|
|
74457
|
-
import { applyToPoint as
|
|
74460
|
+
import { applyToPoint as applyToPoint20, rotate as rotate8, identity as identity4 } from "transformation-matrix";
|
|
74458
74461
|
import { FootprintModel as FootprintModel3 } from "kicadts";
|
|
74462
|
+
import { FootprintPad, PadNet, PadOptions } from "kicadts";
|
|
74459
74463
|
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
|
|
74464
|
+
applyToPoint as applyToPoint21,
|
|
74465
|
+
compose as compose10,
|
|
74466
|
+
rotate as rotate9,
|
|
74467
|
+
scale as scale7,
|
|
74468
|
+
translate as translate10
|
|
74474
74469
|
} from "transformation-matrix";
|
|
74475
74470
|
import { FootprintPad as FootprintPad2, PadDrill, PadNet as PadNet2 } from "kicadts";
|
|
74476
|
-
import { applyToPoint as
|
|
74471
|
+
import { applyToPoint as applyToPoint22, rotate as rotate10, identity as identity5 } from "transformation-matrix";
|
|
74477
74472
|
import { FootprintPad as FootprintPad3, PadDrill as PadDrill2 } from "kicadts";
|
|
74478
|
-
import { applyToPoint as
|
|
74473
|
+
import { applyToPoint as applyToPoint23, rotate as rotate11, identity as identity6 } from "transformation-matrix";
|
|
74479
74474
|
import { FpLine as FpLine2, Stroke as Stroke12 } from "kicadts";
|
|
74480
|
-
import { applyToPoint as
|
|
74481
|
-
import {
|
|
74475
|
+
import { applyToPoint as applyToPoint24, identity as identity7, rotate as rotate12 } from "transformation-matrix";
|
|
74476
|
+
import { FootprintPad as FootprintPad4, PadOptions as PadOptions2 } from "kicadts";
|
|
74482
74477
|
import { applyToPoint as applyToPoint25 } from "transformation-matrix";
|
|
74478
|
+
import { Segment, SegmentNet } from "kicadts";
|
|
74479
|
+
import { applyToPoint as applyToPoint27 } from "transformation-matrix";
|
|
74483
74480
|
import {
|
|
74484
|
-
createBoardOwnerMap,
|
|
74481
|
+
createBoardOwnerMap as createBoardOwnerMap2,
|
|
74485
74482
|
isRouteViaCoveredByPhysicalVia
|
|
74486
74483
|
} from "@tscircuit/circuit-json-util";
|
|
74487
74484
|
import { Via, ViaNet } from "kicadts";
|
|
74488
|
-
import { applyToPoint as
|
|
74485
|
+
import { applyToPoint as applyToPoint28 } from "transformation-matrix";
|
|
74489
74486
|
import { ViaTenting } from "kicadts";
|
|
74490
74487
|
import { Footprint as Footprint5 } from "kicadts";
|
|
74491
|
-
import { applyToPoint as
|
|
74488
|
+
import { applyToPoint as applyToPoint29 } from "transformation-matrix";
|
|
74492
74489
|
import { GrLine } from "kicadts";
|
|
74493
74490
|
import {
|
|
74494
74491
|
At as At3,
|
|
@@ -74497,11 +74494,11 @@ import {
|
|
|
74497
74494
|
TextEffectsFont as TextEffectsFont12,
|
|
74498
74495
|
TextEffectsJustify as TextEffectsJustify7
|
|
74499
74496
|
} from "kicadts";
|
|
74500
|
-
import { applyToPoint as
|
|
74501
|
-
import { applyToPoint as
|
|
74497
|
+
import { applyToPoint as applyToPoint30 } from "transformation-matrix";
|
|
74498
|
+
import { applyToPoint as applyToPoint32, rotate as rotate13 } from "transformation-matrix";
|
|
74502
74499
|
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";
|
|
74500
|
+
import { applyToPoint as applyToPoint31 } from "transformation-matrix";
|
|
74501
|
+
import { cju as cju3, createBoardOwnerMap as createBoardOwnerMap3 } from "@tscircuit/circuit-json-util";
|
|
74505
74502
|
import { cju as cju4 } from "@tscircuit/circuit-json-util";
|
|
74506
74503
|
import { parseKicadSexpr as parseKicadSexpr2, KicadSch as KicadSch2 } from "kicadts";
|
|
74507
74504
|
import { KicadSymbolLib } from "kicadts";
|
|
@@ -75270,7 +75267,7 @@ function transformSchematicPoint(transform, point) {
|
|
|
75270
75267
|
function createArcFromPrimitive({
|
|
75271
75268
|
primitive,
|
|
75272
75269
|
transform,
|
|
75273
|
-
scale:
|
|
75270
|
+
scale: scale9
|
|
75274
75271
|
}) {
|
|
75275
75272
|
const start = transformSchematicPoint(transform, primitive.start);
|
|
75276
75273
|
const mid = transformSchematicPoint(transform, primitive.mid);
|
|
@@ -75283,7 +75280,7 @@ function createArcFromPrimitive({
|
|
|
75283
75280
|
"stroke",
|
|
75284
75281
|
[
|
|
75285
75282
|
"width",
|
|
75286
|
-
roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth *
|
|
75283
|
+
roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth * scale9)
|
|
75287
75284
|
],
|
|
75288
75285
|
["type", primitive.isDashed ? "dash" : "default"]
|
|
75289
75286
|
],
|
|
@@ -75339,7 +75336,7 @@ function createSymbolFillSexprPrimitives({
|
|
|
75339
75336
|
function createCircleFromPrimitive({
|
|
75340
75337
|
primitive,
|
|
75341
75338
|
transform,
|
|
75342
|
-
scale:
|
|
75339
|
+
scale: scale9
|
|
75343
75340
|
}) {
|
|
75344
75341
|
const scaledPos = transformSchematicPoint(transform, {
|
|
75345
75342
|
x: primitive.x,
|
|
@@ -75347,12 +75344,12 @@ function createCircleFromPrimitive({
|
|
|
75347
75344
|
});
|
|
75348
75345
|
return SymbolCircle.fromSexprPrimitives([
|
|
75349
75346
|
["center", scaledPos.x, scaledPos.y],
|
|
75350
|
-
["radius", roundSchematicCoordinate(primitive.radius *
|
|
75347
|
+
["radius", roundSchematicCoordinate(primitive.radius * scale9)],
|
|
75351
75348
|
[
|
|
75352
75349
|
"stroke",
|
|
75353
75350
|
[
|
|
75354
75351
|
"width",
|
|
75355
|
-
roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth *
|
|
75352
|
+
roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth * scale9)
|
|
75356
75353
|
],
|
|
75357
75354
|
["type", "default"]
|
|
75358
75355
|
],
|
|
@@ -75374,7 +75371,7 @@ function createPolylineFromPoints({
|
|
|
75374
75371
|
fallbackFillType,
|
|
75375
75372
|
strokeWidth,
|
|
75376
75373
|
isDashed,
|
|
75377
|
-
scale:
|
|
75374
|
+
scale: scale9
|
|
75378
75375
|
}) {
|
|
75379
75376
|
const polyline = new SymbolPolyline;
|
|
75380
75377
|
const xyPoints = points.map((p) => {
|
|
@@ -75384,7 +75381,7 @@ function createPolylineFromPoints({
|
|
|
75384
75381
|
const pts = new Pts(xyPoints);
|
|
75385
75382
|
polyline.points = pts;
|
|
75386
75383
|
const stroke = new Stroke2;
|
|
75387
|
-
stroke.width = roundSchematicCoordinate(strokeWidth == null ? 0.254 : strokeWidth *
|
|
75384
|
+
stroke.width = roundSchematicCoordinate(strokeWidth == null ? 0.254 : strokeWidth * scale9);
|
|
75388
75385
|
stroke.type = isDashed ? "dash" : "default";
|
|
75389
75386
|
polyline.stroke = stroke;
|
|
75390
75387
|
const fill = SymbolPolylineFill.fromSexprPrimitives(createSymbolFillSexprPrimitives({
|
|
@@ -75398,7 +75395,7 @@ function createPolylineFromPoints({
|
|
|
75398
75395
|
function createRectangleFromPrimitive({
|
|
75399
75396
|
primitive,
|
|
75400
75397
|
transform,
|
|
75401
|
-
scale:
|
|
75398
|
+
scale: scale9
|
|
75402
75399
|
}) {
|
|
75403
75400
|
const start = transformSchematicPoint(transform, primitive.start);
|
|
75404
75401
|
const end = transformSchematicPoint(transform, primitive.end);
|
|
@@ -75409,7 +75406,7 @@ function createRectangleFromPrimitive({
|
|
|
75409
75406
|
"stroke",
|
|
75410
75407
|
[
|
|
75411
75408
|
"width",
|
|
75412
|
-
roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth *
|
|
75409
|
+
roundSchematicCoordinate(primitive.strokeWidth == null ? 0.254 : primitive.strokeWidth * scale9)
|
|
75413
75410
|
],
|
|
75414
75411
|
["type", primitive.isDashed ? "dash" : "default"]
|
|
75415
75412
|
],
|
|
@@ -75425,7 +75422,7 @@ function createRectangleFromPrimitive({
|
|
|
75425
75422
|
function createTextFromPrimitive({
|
|
75426
75423
|
schText,
|
|
75427
75424
|
transform,
|
|
75428
|
-
scale:
|
|
75425
|
+
scale: scale9
|
|
75429
75426
|
}) {
|
|
75430
75427
|
const symbolText = new SymbolText;
|
|
75431
75428
|
const scaledPos = transformSchematicPoint(transform, {
|
|
@@ -75434,7 +75431,7 @@ function createTextFromPrimitive({
|
|
|
75434
75431
|
});
|
|
75435
75432
|
symbolText.value = schText.text;
|
|
75436
75433
|
symbolText.at = [scaledPos.x, scaledPos.y, 0];
|
|
75437
|
-
const scaledFontSize = roundSchematicCoordinate(schText.fontSize *
|
|
75434
|
+
const scaledFontSize = roundSchematicCoordinate(schText.fontSize * scale9);
|
|
75438
75435
|
const font = new TextEffectsFont2;
|
|
75439
75436
|
font.size = { height: scaledFontSize, width: scaledFontSize };
|
|
75440
75437
|
symbolText.effects = new TextEffects2({ font });
|
|
@@ -75700,6 +75697,30 @@ function calculatePinPosition({
|
|
|
75700
75697
|
}
|
|
75701
75698
|
return { x, y, angle };
|
|
75702
75699
|
}
|
|
75700
|
+
function getKicadPinElectricalType(sourcePort) {
|
|
75701
|
+
if (!sourcePort)
|
|
75702
|
+
return "passive";
|
|
75703
|
+
if (sourcePort.provides_power || sourcePort.provides_ground) {
|
|
75704
|
+
return "power_out";
|
|
75705
|
+
}
|
|
75706
|
+
if (sourcePort.requires_power || sourcePort.requires_ground) {
|
|
75707
|
+
return "power_in";
|
|
75708
|
+
}
|
|
75709
|
+
if (sourcePort.is_using_open_collector || sourcePort.is_using_open_drain) {
|
|
75710
|
+
return "open_collector";
|
|
75711
|
+
}
|
|
75712
|
+
if (sourcePort.is_using_open_emitter)
|
|
75713
|
+
return "open_emitter";
|
|
75714
|
+
if (sourcePort.is_using_tri_state)
|
|
75715
|
+
return "tri_state";
|
|
75716
|
+
if (sourcePort.is_bidirectional)
|
|
75717
|
+
return "bidirectional";
|
|
75718
|
+
if (sourcePort.is_output)
|
|
75719
|
+
return "output";
|
|
75720
|
+
if (sourcePort.is_input)
|
|
75721
|
+
return "input";
|
|
75722
|
+
return "passive";
|
|
75723
|
+
}
|
|
75703
75724
|
function getPortSide(x, y) {
|
|
75704
75725
|
if (Math.abs(x) > Math.abs(y))
|
|
75705
75726
|
return x < 0 ? "left" : "right";
|
|
@@ -75716,12 +75737,11 @@ function getCircuitPinNumbers({
|
|
|
75716
75737
|
symbolData,
|
|
75717
75738
|
schematicComponent,
|
|
75718
75739
|
schematicPorts,
|
|
75719
|
-
|
|
75740
|
+
sourcePortsById
|
|
75720
75741
|
}) {
|
|
75721
75742
|
const matches = /* @__PURE__ */ new Map;
|
|
75722
75743
|
if (!schematicComponent)
|
|
75723
75744
|
return matches;
|
|
75724
|
-
const sourcePortsById = new Map(sourcePorts.map((port) => [port.source_port_id, port]));
|
|
75725
75745
|
const symbolCenter = symbolData.center ?? { x: 0, y: 0 };
|
|
75726
75746
|
const componentPorts = schematicPorts.filter((port) => port.schematic_component_id === schematicComponent.schematic_component_id);
|
|
75727
75747
|
for (const side of ["left", "right", "up", "down"]) {
|
|
@@ -75782,17 +75802,17 @@ function createPinSubsymbol({
|
|
|
75782
75802
|
});
|
|
75783
75803
|
const CHIP_PIN_LENGTH = 6;
|
|
75784
75804
|
const CUSTOM_SYMBOL_PIN_LENGTH = 0.01;
|
|
75805
|
+
const sourcePortsById = new Map(sourcePorts.map((port) => [port.source_port_id, port]));
|
|
75785
75806
|
const inferredPinNumbers = isChip ? /* @__PURE__ */ new Map : getCircuitPinNumbers({
|
|
75786
75807
|
symbolData,
|
|
75787
75808
|
schematicComponent,
|
|
75788
75809
|
schematicPorts,
|
|
75789
|
-
|
|
75810
|
+
sourcePortsById
|
|
75790
75811
|
});
|
|
75791
75812
|
const circuitPinNumbers = validateInferredPinNumbers(symbolData, inferredPinNumbers);
|
|
75792
75813
|
const origin = schematicComponent ? applyToPoint3(c2kMatSch, schematicComponent.center) : { x: 0, y: 0 };
|
|
75793
75814
|
for (const [i, port] of symbolData.ports.entries()) {
|
|
75794
75815
|
const pin = new SymbolPin;
|
|
75795
|
-
pin.pinElectricalType = "passive";
|
|
75796
75816
|
pin.pinGraphicStyle = "line";
|
|
75797
75817
|
const { x, y, angle } = calculatePinPosition({
|
|
75798
75818
|
port,
|
|
@@ -75823,8 +75843,15 @@ function createPinSubsymbol({
|
|
|
75823
75843
|
numFont.size = { height: 1.27, width: 1.27 };
|
|
75824
75844
|
const numEffects = new TextEffects4({ font: numFont });
|
|
75825
75845
|
const pinNum = port.pinNumber?.toString() ?? circuitPinNumbers.get(i) ?? `${i + 1}`;
|
|
75826
|
-
const schematicPort = schematicPorts.find((candidate) =>
|
|
75827
|
-
|
|
75846
|
+
const schematicPort = schematicPorts.find((candidate) => {
|
|
75847
|
+
if (candidate.schematic_component_id !== schematicComponent?.schematic_component_id) {
|
|
75848
|
+
return false;
|
|
75849
|
+
}
|
|
75850
|
+
const linkedSourcePort = sourcePortsById.get(candidate.source_port_id);
|
|
75851
|
+
return String(candidate.pin_number ?? linkedSourcePort?.pin_number) === pinNum;
|
|
75852
|
+
});
|
|
75853
|
+
const sourcePort = schematicPort ? sourcePortsById.get(schematicPort.source_port_id) : undefined;
|
|
75854
|
+
pin.pinElectricalType = getKicadPinElectricalType(sourcePort);
|
|
75828
75855
|
pin._sxNumber = new SymbolPinNumber({
|
|
75829
75856
|
value: getPhysicalPinName(sourcePort) ?? pinNum,
|
|
75830
75857
|
effects: numEffects
|
|
@@ -76286,8 +76313,8 @@ var AddSchematicGraphicsStage = class extends ConverterStage {
|
|
|
76286
76313
|
new Xy2(end.x, end.y)
|
|
76287
76314
|
]);
|
|
76288
76315
|
const stroke = new Stroke3;
|
|
76289
|
-
stroke.width = 0;
|
|
76290
|
-
stroke.type = "default";
|
|
76316
|
+
stroke.width = (line.stroke_width ?? 0) * (this.ctx.kicadSchematicScaleFactor ?? 1);
|
|
76317
|
+
stroke.type = line.is_dashed ? "dash" : "default";
|
|
76291
76318
|
stroke.color = preserveStandaloneGraphics ? parseColor(line.color) ?? DEFAULT_SECTION_LINE_COLOR : DEFAULT_SECTION_LINE_COLOR;
|
|
76292
76319
|
polyline.stroke = stroke;
|
|
76293
76320
|
polyline.uuid = new Uuid(crypto.randomUUID());
|
|
@@ -76598,6 +76625,30 @@ var AddSchematicNetLabelsStage = class extends ConverterStage {
|
|
|
76598
76625
|
return this.ctx.kicadSch;
|
|
76599
76626
|
}
|
|
76600
76627
|
};
|
|
76628
|
+
var AddSchematicNoConnectsStage = class extends ConverterStage {
|
|
76629
|
+
_step() {
|
|
76630
|
+
const { db, kicadSch, c2kMatSch } = this.ctx;
|
|
76631
|
+
if (!kicadSch) {
|
|
76632
|
+
throw new Error("KicadSch instance not initialized in context");
|
|
76633
|
+
}
|
|
76634
|
+
if (!c2kMatSch) {
|
|
76635
|
+
throw new Error("Schematic transformation matrix not initialized in context");
|
|
76636
|
+
}
|
|
76637
|
+
const noConnectSourcePortIds = new Set(db.source_port.list().filter((sourcePort) => sourcePort.do_not_connect).map((sourcePort) => sourcePort.source_port_id));
|
|
76638
|
+
const noConnects = db.schematic_port.list().filter((schematicPort) => noConnectSourcePortIds.has(schematicPort.source_port_id) && !schematicPort.is_connected).map((schematicPort) => {
|
|
76639
|
+
const position = transformSchematicPoint(c2kMatSch, schematicPort.center);
|
|
76640
|
+
return new NoConnect({
|
|
76641
|
+
at: [position.x, position.y],
|
|
76642
|
+
uuid: crypto.randomUUID()
|
|
76643
|
+
});
|
|
76644
|
+
});
|
|
76645
|
+
kicadSch.noConnects = [...kicadSch.noConnects, ...noConnects];
|
|
76646
|
+
this.finished = true;
|
|
76647
|
+
}
|
|
76648
|
+
getOutput() {
|
|
76649
|
+
return this.ctx.kicadSch;
|
|
76650
|
+
}
|
|
76651
|
+
};
|
|
76601
76652
|
var DEFAULT_PROPERTY_FONT_SIZE = 1.27;
|
|
76602
76653
|
var AddSchematicSymbolsStage = class extends ConverterStage {
|
|
76603
76654
|
_step() {
|
|
@@ -77226,6 +77277,7 @@ var CircuitJsonToKicadSchConverter = class {
|
|
|
77226
77277
|
new AddLibrarySymbolsStage(circuitJson, this.ctx),
|
|
77227
77278
|
new AddSchematicSymbolsStage(circuitJson, this.ctx),
|
|
77228
77279
|
new AddSchematicNetLabelsStage(circuitJson, this.ctx),
|
|
77280
|
+
new AddSchematicNoConnectsStage(circuitJson, this.ctx),
|
|
77229
77281
|
new AddSchematicTracesStage(circuitJson, this.ctx),
|
|
77230
77282
|
new AddSchematicGraphicsStage(circuitJson, this.ctx),
|
|
77231
77283
|
new AddSheetInstancesStage(circuitJson, this.ctx)
|
|
@@ -77384,6 +77436,7 @@ var CircuitJsonToKicadSchConverter = class {
|
|
|
77384
77436
|
new AddLibrarySymbolsStage(circuitJson, ctx),
|
|
77385
77437
|
new AddSchematicSymbolsStage(circuitJson, ctx),
|
|
77386
77438
|
new AddSchematicNetLabelsStage(circuitJson, ctx),
|
|
77439
|
+
new AddSchematicNoConnectsStage(circuitJson, ctx),
|
|
77387
77440
|
new AddSchematicTracesStage(circuitJson, ctx),
|
|
77388
77441
|
new AddSchematicGraphicsStage(circuitJson, ctx)
|
|
77389
77442
|
];
|
|
@@ -77461,6 +77514,110 @@ function getViaLayerSpan(kicadLayers, numLayers) {
|
|
|
77461
77514
|
}
|
|
77462
77515
|
return top === bottom ? [top] : [top, bottom];
|
|
77463
77516
|
}
|
|
77517
|
+
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));
|
|
77518
|
+
var triangulatePolygonWithHoles = (outerContour, holes = []) => {
|
|
77519
|
+
const flattenedPoints = [];
|
|
77520
|
+
const holeIndices = [];
|
|
77521
|
+
let pointCount = 0;
|
|
77522
|
+
const addContour = (contour) => {
|
|
77523
|
+
for (const point of contour) {
|
|
77524
|
+
flattenedPoints.push(point.x, point.y);
|
|
77525
|
+
}
|
|
77526
|
+
pointCount += contour.length;
|
|
77527
|
+
};
|
|
77528
|
+
addContour(outerContour);
|
|
77529
|
+
for (const hole of holes) {
|
|
77530
|
+
holeIndices.push(pointCount);
|
|
77531
|
+
addContour(hole);
|
|
77532
|
+
}
|
|
77533
|
+
const triangleIndices = earcut(flattenedPoints, holeIndices, 2);
|
|
77534
|
+
const triangles = [];
|
|
77535
|
+
for (let index = 0;index < triangleIndices.length; index += 3) {
|
|
77536
|
+
const aIndex = triangleIndices[index];
|
|
77537
|
+
const bIndex = triangleIndices[index + 1];
|
|
77538
|
+
const cIndex = triangleIndices[index + 2];
|
|
77539
|
+
if (aIndex === undefined || bIndex === undefined || cIndex === undefined) {
|
|
77540
|
+
continue;
|
|
77541
|
+
}
|
|
77542
|
+
const getPoint = (pointIndex) => ({
|
|
77543
|
+
x: flattenedPoints[pointIndex * 2],
|
|
77544
|
+
y: flattenedPoints[pointIndex * 2 + 1]
|
|
77545
|
+
});
|
|
77546
|
+
const triangle = [
|
|
77547
|
+
getPoint(aIndex),
|
|
77548
|
+
getPoint(bIndex),
|
|
77549
|
+
getPoint(cIndex)
|
|
77550
|
+
];
|
|
77551
|
+
if (getTriangleTwiceArea(...triangle) === 0)
|
|
77552
|
+
continue;
|
|
77553
|
+
triangles.push(triangle);
|
|
77554
|
+
}
|
|
77555
|
+
return triangles;
|
|
77556
|
+
};
|
|
77557
|
+
var getDistance = (a, b) => Math.hypot(a.x - b.x, a.y - b.y);
|
|
77558
|
+
var getSafePolygonAnchor = (outerContour, holes = []) => {
|
|
77559
|
+
const triangles = triangulatePolygonWithHoles(outerContour, holes);
|
|
77560
|
+
let bestTriangle;
|
|
77561
|
+
for (const [a, b, c] of triangles) {
|
|
77562
|
+
const sideA = getDistance(b, c);
|
|
77563
|
+
const sideB = getDistance(c, a);
|
|
77564
|
+
const sideC = getDistance(a, b);
|
|
77565
|
+
const perimeter = sideA + sideB + sideC;
|
|
77566
|
+
if (perimeter === 0)
|
|
77567
|
+
continue;
|
|
77568
|
+
const inradius = getTriangleTwiceArea(a, b, c) / perimeter;
|
|
77569
|
+
const center = {
|
|
77570
|
+
x: (sideA * a.x + sideB * b.x + sideC * c.x) / perimeter,
|
|
77571
|
+
y: (sideA * a.y + sideB * b.y + sideC * c.y) / perimeter
|
|
77572
|
+
};
|
|
77573
|
+
if (!bestTriangle || inradius > bestTriangle.inradius) {
|
|
77574
|
+
bestTriangle = { center, inradius };
|
|
77575
|
+
}
|
|
77576
|
+
}
|
|
77577
|
+
if (!bestTriangle) {
|
|
77578
|
+
throw new Error("Polygon must contain a valid filled area");
|
|
77579
|
+
}
|
|
77580
|
+
return {
|
|
77581
|
+
center: bestTriangle.center,
|
|
77582
|
+
diameter: Math.min(0.001, bestTriangle.inradius),
|
|
77583
|
+
triangles
|
|
77584
|
+
};
|
|
77585
|
+
};
|
|
77586
|
+
var createFilledPolygonPrimitives = ({
|
|
77587
|
+
contours,
|
|
77588
|
+
center
|
|
77589
|
+
}) => {
|
|
77590
|
+
const toLocalContour = (points) => new Pts4(points.map((point) => {
|
|
77591
|
+
const localPoint = applyToPoint9(compose3(scale2(1, -1), translate3(-center.x, -center.y)), point);
|
|
77592
|
+
return new Xy4(localPoint.x, localPoint.y);
|
|
77593
|
+
}));
|
|
77594
|
+
const primitives = new PadPrimitives;
|
|
77595
|
+
for (const contour of contours) {
|
|
77596
|
+
const polygon = new PadPrimitiveGrPoly;
|
|
77597
|
+
polygon.contours = [toLocalContour(contour)];
|
|
77598
|
+
polygon.width = 0;
|
|
77599
|
+
polygon.filled = true;
|
|
77600
|
+
primitives.addGraphic(polygon);
|
|
77601
|
+
}
|
|
77602
|
+
return primitives;
|
|
77603
|
+
};
|
|
77604
|
+
var createEllipseContour = ({
|
|
77605
|
+
center,
|
|
77606
|
+
width,
|
|
77607
|
+
height,
|
|
77608
|
+
segmentCount = 64
|
|
77609
|
+
}) => {
|
|
77610
|
+
if (width <= 0 || height <= 0) {
|
|
77611
|
+
throw new Error("Ellipse must have positive dimensions");
|
|
77612
|
+
}
|
|
77613
|
+
return Array.from({ length: segmentCount }, (_, index) => {
|
|
77614
|
+
const angle = index / segmentCount * Math.PI * 2;
|
|
77615
|
+
return {
|
|
77616
|
+
x: center.x + width / 2 * Math.cos(angle),
|
|
77617
|
+
y: center.y + height / 2 * Math.sin(angle)
|
|
77618
|
+
};
|
|
77619
|
+
});
|
|
77620
|
+
};
|
|
77464
77621
|
function simpleHash(str) {
|
|
77465
77622
|
let hash = 0;
|
|
77466
77623
|
for (let i = 0;i < str.length; i++) {
|
|
@@ -77497,8 +77654,8 @@ var getCopperPourNetInfo = (pour, ctx) => {
|
|
|
77497
77654
|
};
|
|
77498
77655
|
var convertPointsToKicadXy = (points, c2kMatPcb) => {
|
|
77499
77656
|
return (points ?? []).map((point) => {
|
|
77500
|
-
const transformedPoint =
|
|
77501
|
-
return new
|
|
77657
|
+
const transformedPoint = applyToPoint10(c2kMatPcb, point);
|
|
77658
|
+
return new Xy5(transformedPoint.x, transformedPoint.y);
|
|
77502
77659
|
});
|
|
77503
77660
|
};
|
|
77504
77661
|
var rotateRingToStartAtTopRight = (points) => {
|
|
@@ -77538,7 +77695,7 @@ var removeRepeatedClosingPoint = (points) => {
|
|
|
77538
77695
|
};
|
|
77539
77696
|
var getRectRingPoints = (pour, c2kMatPcb) => {
|
|
77540
77697
|
const ccwRotationDegrees = pour.rotation ?? 0;
|
|
77541
|
-
const cornerTransform =
|
|
77698
|
+
const cornerTransform = compose4(translate4(pour.center.x, pour.center.y), rotate(ccwRotationDegrees * Math.PI / 180));
|
|
77542
77699
|
const halfWidth = pour.width / 2;
|
|
77543
77700
|
const halfHeight = pour.height / 2;
|
|
77544
77701
|
const corners = [
|
|
@@ -77546,7 +77703,7 @@ var getRectRingPoints = (pour, c2kMatPcb) => {
|
|
|
77546
77703
|
{ x: halfWidth, y: -halfHeight },
|
|
77547
77704
|
{ x: halfWidth, y: halfHeight },
|
|
77548
77705
|
{ x: -halfWidth, y: halfHeight }
|
|
77549
|
-
].map((corner) =>
|
|
77706
|
+
].map((corner) => applyToPoint10(cornerTransform, corner));
|
|
77550
77707
|
return convertPointsToKicadXy(corners, c2kMatPcb);
|
|
77551
77708
|
};
|
|
77552
77709
|
var getPolygonRingPoints = (pour, c2kMatPcb) => removeRepeatedClosingPoint(removeConsecutiveDuplicatePoints(rotateRingToStartAtTopRight(convertPointsToKicadXy(pour.points, c2kMatPcb))));
|
|
@@ -77570,16 +77727,15 @@ var getCopperPourZoneRings = (pour, c2kMatPcb) => {
|
|
|
77570
77727
|
var createZonePolygons = (outerRing, innerRings) => {
|
|
77571
77728
|
const polygons = [];
|
|
77572
77729
|
if (outerRing.length >= 3) {
|
|
77573
|
-
polygons.push(new ZonePolygon(new
|
|
77730
|
+
polygons.push(new ZonePolygon(new Pts5(outerRing)));
|
|
77574
77731
|
}
|
|
77575
77732
|
for (const innerRing of innerRings) {
|
|
77576
77733
|
if (innerRing.length < 3)
|
|
77577
77734
|
continue;
|
|
77578
|
-
polygons.push(new ZonePolygon(new
|
|
77735
|
+
polygons.push(new ZonePolygon(new Pts5(innerRing)));
|
|
77579
77736
|
}
|
|
77580
77737
|
return polygons;
|
|
77581
77738
|
};
|
|
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
77739
|
var createZoneFilledPolygons = (outerRing, innerRings, kicadLayer) => {
|
|
77584
77740
|
if (outerRing.length < 3) {
|
|
77585
77741
|
return [];
|
|
@@ -77589,45 +77745,14 @@ var createZoneFilledPolygons = (outerRing, innerRings, kicadLayer) => {
|
|
|
77589
77745
|
return [
|
|
77590
77746
|
new ZoneFilledPolygon({
|
|
77591
77747
|
layer,
|
|
77592
|
-
pts: new
|
|
77748
|
+
pts: new Pts5(outerRing)
|
|
77593
77749
|
})
|
|
77594
77750
|
];
|
|
77595
77751
|
}
|
|
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;
|
|
77752
|
+
return triangulatePolygonWithHoles(outerRing, innerRings).map((triangle) => new ZoneFilledPolygon({
|
|
77753
|
+
layer,
|
|
77754
|
+
pts: new Pts5(triangle.map((point) => new Xy5(point.x, point.y)))
|
|
77755
|
+
}));
|
|
77631
77756
|
};
|
|
77632
77757
|
var AddCopperPoursStage = class extends ConverterStage {
|
|
77633
77758
|
_step() {
|
|
@@ -77718,8 +77843,8 @@ var AddKeepoutsStage = class extends ConverterStage {
|
|
|
77718
77843
|
rawPoints = keepout.outline;
|
|
77719
77844
|
}
|
|
77720
77845
|
const kicadPoints = rawPoints.map((p) => {
|
|
77721
|
-
const t =
|
|
77722
|
-
return new
|
|
77846
|
+
const t = applyToPoint11(c2kMatPcb, p);
|
|
77847
|
+
return new Xy6(t.x, t.y);
|
|
77723
77848
|
});
|
|
77724
77849
|
const zone = new Zone2({
|
|
77725
77850
|
net: 0,
|
|
@@ -77733,7 +77858,7 @@ var AddKeepoutsStage = class extends ConverterStage {
|
|
|
77733
77858
|
copperpour: "not_allowed",
|
|
77734
77859
|
footprints: "not_allowed"
|
|
77735
77860
|
}),
|
|
77736
|
-
polygons: [new ZonePolygon2(new
|
|
77861
|
+
polygons: [new ZonePolygon2(new Pts6(kicadPoints))]
|
|
77737
77862
|
});
|
|
77738
77863
|
const zones = kicadPcb.zones;
|
|
77739
77864
|
zones.push(zone);
|
|
@@ -77781,6 +77906,14 @@ var InitializePcbStage = class extends ConverterStage {
|
|
|
77781
77906
|
return this.ctx.kicadPcb;
|
|
77782
77907
|
}
|
|
77783
77908
|
};
|
|
77909
|
+
var resolveKicadPcbNetName = ({
|
|
77910
|
+
candidateName,
|
|
77911
|
+
connectivityKey,
|
|
77912
|
+
boardId
|
|
77913
|
+
}) => {
|
|
77914
|
+
const name = candidateName && candidateName.trim().length > 0 ? candidateName : connectivityKey;
|
|
77915
|
+
return boardId ? `${boardId}/${name}` : name;
|
|
77916
|
+
};
|
|
77784
77917
|
var AddNetsStage = class extends ConverterStage {
|
|
77785
77918
|
_step() {
|
|
77786
77919
|
const { kicadPcb } = this.ctx;
|
|
@@ -77789,13 +77922,17 @@ var AddNetsStage = class extends ConverterStage {
|
|
|
77789
77922
|
}
|
|
77790
77923
|
this.ctx.pcbNetMap = /* @__PURE__ */ new Map;
|
|
77791
77924
|
const netNameByKey = /* @__PURE__ */ new Map;
|
|
77925
|
+
const boardOwnerMap = this.ctx.db.pcb_board.list().length > 1 ? createBoardOwnerMap(this.input) : undefined;
|
|
77792
77926
|
const sourceNets = this.ctx.db.source_net?.list() ?? [];
|
|
77793
77927
|
for (const sourceNet of sourceNets) {
|
|
77794
77928
|
const connectivityKey = sourceNet.subcircuit_connectivity_map_key || sourceNet.source_net_id;
|
|
77795
77929
|
if (!connectivityKey)
|
|
77796
77930
|
continue;
|
|
77797
|
-
const
|
|
77798
|
-
|
|
77931
|
+
const netName = resolveKicadPcbNetName({
|
|
77932
|
+
candidateName: sourceNet.name || sourceNet.source_net_id,
|
|
77933
|
+
connectivityKey,
|
|
77934
|
+
boardId: boardOwnerMap?.get(sourceNet.subcircuit_id ?? "")?.pcb_board_id
|
|
77935
|
+
});
|
|
77799
77936
|
netNameByKey.set(connectivityKey, netName);
|
|
77800
77937
|
}
|
|
77801
77938
|
const sourceTraces = this.ctx.db.source_trace?.list() ?? [];
|
|
@@ -77813,8 +77950,11 @@ var AddNetsStage = class extends ConverterStage {
|
|
|
77813
77950
|
if (!connectivityKey)
|
|
77814
77951
|
continue;
|
|
77815
77952
|
if (!netNameByKey.has(connectivityKey)) {
|
|
77816
|
-
const
|
|
77817
|
-
|
|
77953
|
+
const netName = resolveKicadPcbNetName({
|
|
77954
|
+
candidateName: sourceTrace.display_name || sourceTrace.source_trace_id,
|
|
77955
|
+
connectivityKey,
|
|
77956
|
+
boardId: boardOwnerMap?.get(sourceTrace.subcircuit_id ?? "")?.pcb_board_id
|
|
77957
|
+
});
|
|
77818
77958
|
netNameByKey.set(connectivityKey, netName);
|
|
77819
77959
|
}
|
|
77820
77960
|
}
|
|
@@ -78040,7 +78180,8 @@ var ExtractFootprintsStage = class extends ConverterStage {
|
|
|
78040
78180
|
for (let i = 0;i < pads.length; i++) {
|
|
78041
78181
|
const pad = pads[i];
|
|
78042
78182
|
if (pad) {
|
|
78043
|
-
pad.
|
|
78183
|
+
const padIdentity = pad.number === "" ? `unnumbered-${i}` : pad.number ?? i;
|
|
78184
|
+
pad.uuid = generateDeterministicUuid(`${footprintName}-pad-${padIdentity}`);
|
|
78044
78185
|
pad.net = undefined;
|
|
78045
78186
|
}
|
|
78046
78187
|
}
|
|
@@ -78328,7 +78469,7 @@ function convertSilkscreenCircles(silkscreenCircles, { componentCenter, componen
|
|
|
78328
78469
|
const fpCircles = [];
|
|
78329
78470
|
const rotationMatrix = componentRotation !== 0 ? rotate2(componentRotation * Math.PI / 180) : identity();
|
|
78330
78471
|
for (const circle of silkscreenCircles) {
|
|
78331
|
-
const relativeCenter =
|
|
78472
|
+
const relativeCenter = applyToPoint12(rotationMatrix, {
|
|
78332
78473
|
x: circle.center.x - componentCenter.x,
|
|
78333
78474
|
y: -(circle.center.y - componentCenter.y)
|
|
78334
78475
|
});
|
|
@@ -78356,13 +78497,13 @@ function getBoardToFootprintTransform({
|
|
|
78356
78497
|
footprintOrigin,
|
|
78357
78498
|
ccwRotationDegrees = 0
|
|
78358
78499
|
}) {
|
|
78359
|
-
return
|
|
78500
|
+
return compose5(rotateDEG(ccwRotationDegrees), scale3(1, -1), translate5(-footprintOrigin.x, -footprintOrigin.y));
|
|
78360
78501
|
}
|
|
78361
78502
|
function convertCourtyardCircles(courtyardCircles, placement) {
|
|
78362
78503
|
const fpCircles = [];
|
|
78363
78504
|
const boardToFootprintTransform = getBoardToFootprintTransform(placement);
|
|
78364
78505
|
for (const circle of courtyardCircles) {
|
|
78365
|
-
const center =
|
|
78506
|
+
const center = applyToPoint13(boardToFootprintTransform, circle.center);
|
|
78366
78507
|
const layerMap = {
|
|
78367
78508
|
top: "F.CrtYd",
|
|
78368
78509
|
bottom: "B.CrtYd"
|
|
@@ -78389,7 +78530,7 @@ function convertNoteRectToFootprintGraphic({
|
|
|
78389
78530
|
footprintOrigin,
|
|
78390
78531
|
ccwRotationDegrees = 0
|
|
78391
78532
|
}) {
|
|
78392
|
-
const rectToFootprintTransform =
|
|
78533
|
+
const rectToFootprintTransform = compose6(getBoardToFootprintTransform({ footprintOrigin, ccwRotationDegrees }), translate6(rect.center.x, rect.center.y));
|
|
78393
78534
|
const halfWidth = rect.width / 2;
|
|
78394
78535
|
const halfHeight = rect.height / 2;
|
|
78395
78536
|
const corners = [
|
|
@@ -78397,7 +78538,7 @@ function convertNoteRectToFootprintGraphic({
|
|
|
78397
78538
|
{ x: halfWidth, y: -halfHeight },
|
|
78398
78539
|
{ x: halfWidth, y: halfHeight },
|
|
78399
78540
|
{ x: -halfWidth, y: halfHeight }
|
|
78400
|
-
].map((point) =>
|
|
78541
|
+
].map((point) => applyToPoint14(rectToFootprintTransform, point));
|
|
78401
78542
|
const stroke = new Stroke7;
|
|
78402
78543
|
stroke.width = rect.stroke_width || 0.1;
|
|
78403
78544
|
stroke.type = "default";
|
|
@@ -78472,7 +78613,7 @@ function rotateCenter(point, degrees) {
|
|
|
78472
78613
|
case 270:
|
|
78473
78614
|
return { x: point.y, y: -point.x };
|
|
78474
78615
|
default:
|
|
78475
|
-
return
|
|
78616
|
+
return applyToPoint15(rotate3(degrees * Math.PI / 180), point);
|
|
78476
78617
|
}
|
|
78477
78618
|
}
|
|
78478
78619
|
function convertCourtyardRects({
|
|
@@ -78482,7 +78623,7 @@ function convertCourtyardRects({
|
|
|
78482
78623
|
}) {
|
|
78483
78624
|
const fpRects = [];
|
|
78484
78625
|
const fpPolys = [];
|
|
78485
|
-
const toLocal =
|
|
78626
|
+
const toLocal = compose7(rotate3(componentRotation * Math.PI / 180), scale4(1, -1), translate7(-componentCenter.x, -componentCenter.y));
|
|
78486
78627
|
for (const rect of courtyardRects) {
|
|
78487
78628
|
const halfW = rect.width / 2;
|
|
78488
78629
|
const halfH = rect.height / 2;
|
|
@@ -78516,13 +78657,13 @@ function convertCourtyardRects({
|
|
|
78516
78657
|
fill: false
|
|
78517
78658
|
}));
|
|
78518
78659
|
} else {
|
|
78519
|
-
const fromRectCenter =
|
|
78660
|
+
const fromRectCenter = compose7(translate7(rect.center.x, rect.center.y), rotate3(rotation * Math.PI / 180));
|
|
78520
78661
|
const points = [
|
|
78521
78662
|
{ x: -halfW, y: -halfH },
|
|
78522
78663
|
{ x: halfW, y: -halfH },
|
|
78523
78664
|
{ x: halfW, y: halfH },
|
|
78524
78665
|
{ x: -halfW, y: halfH }
|
|
78525
|
-
].map((point) =>
|
|
78666
|
+
].map((point) => applyToPoint15(toLocal, applyToPoint15(fromRectCenter, point)));
|
|
78526
78667
|
fpPolys.push(new FpPoly4({
|
|
78527
78668
|
points,
|
|
78528
78669
|
layer,
|
|
@@ -78537,7 +78678,7 @@ function convertCourtyardRects({
|
|
|
78537
78678
|
function convertCourtyardOutlines(params2) {
|
|
78538
78679
|
const { courtyardOutlines, componentCenter, componentRotation = 0 } = params2;
|
|
78539
78680
|
const fpPolys = [];
|
|
78540
|
-
const cj2kicadMatrix =
|
|
78681
|
+
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
78682
|
for (const outline of courtyardOutlines) {
|
|
78542
78683
|
if (!outline.outline || outline.outline.length < 2)
|
|
78543
78684
|
continue;
|
|
@@ -78547,11 +78688,11 @@ function convertCourtyardOutlines(params2) {
|
|
|
78547
78688
|
};
|
|
78548
78689
|
const kicadLayer = layerMap[outline.layer] || "F.CrtYd";
|
|
78549
78690
|
const xyPoints = outline.outline.map((point) => {
|
|
78550
|
-
const transformedPoint =
|
|
78551
|
-
return new
|
|
78691
|
+
const transformedPoint = applyToPoint16(cj2kicadMatrix, point);
|
|
78692
|
+
return new Xy7(transformedPoint.x, transformedPoint.y);
|
|
78552
78693
|
});
|
|
78553
78694
|
const fpPoly = new FpPoly5;
|
|
78554
|
-
fpPoly.points = new
|
|
78695
|
+
fpPoly.points = new Pts7(xyPoints);
|
|
78555
78696
|
fpPoly.layer = kicadLayer;
|
|
78556
78697
|
fpPoly.fill = false;
|
|
78557
78698
|
fpPoly.uuid = generateDeterministicUuid(outline.pcb_courtyard_outline_id);
|
|
@@ -78621,7 +78762,7 @@ function createFpTextFromCircuitJson({
|
|
|
78621
78762
|
const relativeX = textElement.anchor_position.x - componentCenter.x;
|
|
78622
78763
|
const relativeY = -(textElement.anchor_position.y - componentCenter.y);
|
|
78623
78764
|
const rotationMatrix = componentRotation !== 0 ? rotate5(componentRotation * Math.PI / 180) : identity2();
|
|
78624
|
-
const rotatedPos =
|
|
78765
|
+
const rotatedPos = applyToPoint17(rotationMatrix, {
|
|
78625
78766
|
x: relativeX,
|
|
78626
78767
|
y: relativeY
|
|
78627
78768
|
});
|
|
@@ -78702,11 +78843,11 @@ function convertSilkscreenPaths(silkscreenPaths, { componentCenter, componentRot
|
|
|
78702
78843
|
const endPoint = path.route[i + 1];
|
|
78703
78844
|
if (!startPoint || !endPoint)
|
|
78704
78845
|
continue;
|
|
78705
|
-
const startRelative =
|
|
78846
|
+
const startRelative = applyToPoint18(rotationMatrix, {
|
|
78706
78847
|
x: startPoint.x - componentCenter.x,
|
|
78707
78848
|
y: -(startPoint.y - componentCenter.y)
|
|
78708
78849
|
});
|
|
78709
|
-
const endRelative =
|
|
78850
|
+
const endRelative = applyToPoint18(rotationMatrix, {
|
|
78710
78851
|
x: endPoint.x - componentCenter.x,
|
|
78711
78852
|
y: -(endPoint.y - componentCenter.y)
|
|
78712
78853
|
});
|
|
@@ -78756,13 +78897,13 @@ function convertSilkscreenRects({
|
|
|
78756
78897
|
componentCenter,
|
|
78757
78898
|
componentRotation = 0
|
|
78758
78899
|
}) {
|
|
78759
|
-
const toLocal =
|
|
78900
|
+
const toLocal = compose9(rotate7(componentRotation * Math.PI / 180), scale6(1, -1), translate9(-componentCenter.x, -componentCenter.y));
|
|
78760
78901
|
return silkscreenRects.flatMap((rect) => {
|
|
78761
78902
|
const hasStroke = rect.has_stroke ?? rect.stroke_width > 0;
|
|
78762
78903
|
if (!hasStroke && !rect.is_filled)
|
|
78763
78904
|
return [];
|
|
78764
|
-
const fromRectCenter =
|
|
78765
|
-
const points = getRectanglePoints(rect).map((point) =>
|
|
78905
|
+
const fromRectCenter = compose9(translate9(rect.center.x, rect.center.y), rotate7((rect.ccw_rotation ?? 0) * Math.PI / 180));
|
|
78906
|
+
const points = getRectanglePoints(rect).map((point) => applyToPoint19(toLocal, applyToPoint19(fromRectCenter, point)));
|
|
78766
78907
|
const stroke = hasStroke ? new Stroke11 : undefined;
|
|
78767
78908
|
if (stroke) {
|
|
78768
78909
|
stroke.width = rect.stroke_width;
|
|
@@ -78786,7 +78927,7 @@ function convertNoteTexts(params2) {
|
|
|
78786
78927
|
const relX = textElement.anchor_position.x - componentCenter.x;
|
|
78787
78928
|
const relY = -(textElement.anchor_position.y - componentCenter.y);
|
|
78788
78929
|
const rotationMatrix = componentRotation !== 0 ? rotate8(componentRotation * Math.PI / 180) : identity4();
|
|
78789
|
-
const rotatedPos =
|
|
78930
|
+
const rotatedPos = applyToPoint20(rotationMatrix, { x: relX, y: relY });
|
|
78790
78931
|
const fontSize = textElement.font_size || 1;
|
|
78791
78932
|
const font = new TextEffectsFont11;
|
|
78792
78933
|
font.size = { width: fontSize, height: fontSize };
|
|
@@ -78900,15 +79041,47 @@ function create3DModelsFromCadComponent(cadComponent, componentCenter, options)
|
|
|
78900
79041
|
model.offset = transform.offset;
|
|
78901
79042
|
model.rotate = transform.rotation;
|
|
78902
79043
|
if (cadComponent.model_unit_to_mm_scale_factor) {
|
|
78903
|
-
const
|
|
78904
|
-
model.scale = { x:
|
|
79044
|
+
const scale9 = cadComponent.model_unit_to_mm_scale_factor;
|
|
79045
|
+
model.scale = { x: scale9, y: scale9, z: scale9 };
|
|
78905
79046
|
}
|
|
78906
79047
|
models.push(model);
|
|
78907
79048
|
return models;
|
|
78908
79049
|
}
|
|
79050
|
+
var getResolvedPillRadius = ({
|
|
79051
|
+
width,
|
|
79052
|
+
height,
|
|
79053
|
+
radius
|
|
79054
|
+
}) => typeof radius === "number" && Number.isFinite(radius) ? radius : Math.min(width, height) / 2;
|
|
79055
|
+
var getKicadNativePadGeometry = (pad) => {
|
|
79056
|
+
switch (pad.shape) {
|
|
79057
|
+
case "circle":
|
|
79058
|
+
return {
|
|
79059
|
+
shape: "circle",
|
|
79060
|
+
size: [pad.radius * 2, pad.radius * 2],
|
|
79061
|
+
rotation: 0
|
|
79062
|
+
};
|
|
79063
|
+
case "rect":
|
|
79064
|
+
case "rotated_rect": {
|
|
79065
|
+
const cornerRadius = pad.corner_radius ?? pad.rect_border_radius;
|
|
79066
|
+
return {
|
|
79067
|
+
shape: cornerRadius ? "roundrect" : "rect",
|
|
79068
|
+
size: [pad.width, pad.height],
|
|
79069
|
+
rotation: pad.shape === "rotated_rect" ? pad.ccw_rotation ?? 0 : 0,
|
|
79070
|
+
roundrectRatio: cornerRadius ? cornerRadius / Math.min(pad.width, pad.height) : undefined
|
|
79071
|
+
};
|
|
79072
|
+
}
|
|
79073
|
+
case "pill":
|
|
79074
|
+
case "rotated_pill":
|
|
79075
|
+
return {
|
|
79076
|
+
shape: "roundrect",
|
|
79077
|
+
size: [pad.width, pad.height],
|
|
79078
|
+
rotation: pad.shape === "rotated_pill" ? pad.ccw_rotation ?? 0 : 0,
|
|
79079
|
+
roundrectRatio: getResolvedPillRadius(pad) / Math.min(pad.width, pad.height)
|
|
79080
|
+
};
|
|
79081
|
+
}
|
|
79082
|
+
};
|
|
78909
79083
|
function createSmdPadFromCircuitJson({
|
|
78910
79084
|
pcbPad,
|
|
78911
|
-
hasSolderPaste,
|
|
78912
79085
|
componentCenter,
|
|
78913
79086
|
padNumber,
|
|
78914
79087
|
componentRotation = 0,
|
|
@@ -78927,8 +79100,8 @@ function createSmdPadFromCircuitJson({
|
|
|
78927
79100
|
} else {
|
|
78928
79101
|
throw new Error("Pad must have either x/y coordinates or points array");
|
|
78929
79102
|
}
|
|
78930
|
-
const cj2kicadMatrix =
|
|
78931
|
-
const rotatedPos =
|
|
79103
|
+
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));
|
|
79104
|
+
const rotatedPos = applyToPoint21(cj2kicadMatrix, {
|
|
78932
79105
|
x: padX,
|
|
78933
79106
|
y: padY
|
|
78934
79107
|
});
|
|
@@ -78943,57 +79116,21 @@ function createSmdPadFromCircuitJson({
|
|
|
78943
79116
|
let padPrimitives;
|
|
78944
79117
|
let roundrect_rratio;
|
|
78945
79118
|
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);
|
|
79119
|
+
if (pcbPad.shape === "polygon") {
|
|
79120
|
+
padPrimitives = createFilledPolygonPrimitives({
|
|
79121
|
+
contours: [pcbPad.points],
|
|
79122
|
+
center: { x: padX, y: padY }
|
|
78958
79123
|
});
|
|
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
79124
|
padShape = "custom";
|
|
78966
79125
|
padOptions = new PadOptions;
|
|
78967
79126
|
padOptions.anchor = "circle";
|
|
78968
79127
|
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];
|
|
79128
|
+
} else {
|
|
79129
|
+
const geometry = getKicadNativePadGeometry(pcbPad);
|
|
79130
|
+
padShape = geometry.shape;
|
|
79131
|
+
padSize = geometry.size;
|
|
79132
|
+
rotation = geometry.rotation;
|
|
79133
|
+
roundrect_rratio = geometry.roundrectRatio;
|
|
78997
79134
|
}
|
|
78998
79135
|
const padData = `pad:${componentId}:${padNumber}:${rotatedPos.x},${rotatedPos.y}`;
|
|
78999
79136
|
const pad = new FootprintPad({
|
|
@@ -79004,7 +79141,6 @@ function createSmdPadFromCircuitJson({
|
|
|
79004
79141
|
size: padSize,
|
|
79005
79142
|
layers: [
|
|
79006
79143
|
`${padLayer}`,
|
|
79007
|
-
...hasSolderPaste ? [`${padLayer === "F.Cu" ? "F" : "B"}.Paste`] : [],
|
|
79008
79144
|
...pcbPad.is_covered_with_solder_mask ? [] : [`${padLayer === "F.Cu" ? "F" : "B"}.Mask`]
|
|
79009
79145
|
],
|
|
79010
79146
|
solderMaskMargin: pcbPad.soldermask_margin,
|
|
@@ -79041,7 +79177,6 @@ function convertSmdPads({
|
|
|
79041
79177
|
const resolvedPadNumber = getPhysicalPinName(sourcePort) ?? (sourcePort?.pin_number != null ? String(sourcePort.pin_number) : pinHint ? pinHint.replace(/^pin/i, "") : gridHint ?? String(padNumber));
|
|
79042
79178
|
const pad = createSmdPadFromCircuitJson({
|
|
79043
79179
|
pcbPad,
|
|
79044
|
-
hasSolderPaste: ctx.db.pcb_solder_paste.list().some((paste) => paste.pcb_smtpad_id === pcbPad.pcb_smtpad_id),
|
|
79045
79180
|
componentCenter,
|
|
79046
79181
|
padNumber: resolvedPadNumber,
|
|
79047
79182
|
componentRotation,
|
|
@@ -79067,7 +79202,7 @@ function createThruHolePadFromCircuitJson({
|
|
|
79067
79202
|
const relativeX = platedHole.x - componentCenter.x;
|
|
79068
79203
|
const relativeY = -(platedHole.y - componentCenter.y);
|
|
79069
79204
|
const rotationMatrix = componentRotation !== 0 ? rotate10(componentRotation * Math.PI / 180) : identity5();
|
|
79070
|
-
const rotatedPos =
|
|
79205
|
+
const rotatedPos = applyToPoint22(rotationMatrix, {
|
|
79071
79206
|
x: relativeX,
|
|
79072
79207
|
y: relativeY
|
|
79073
79208
|
});
|
|
@@ -79083,7 +79218,7 @@ function createThruHolePadFromCircuitJson({
|
|
|
79083
79218
|
y: platedHole.hole_offset_y ?? 0
|
|
79084
79219
|
};
|
|
79085
79220
|
if (rawOffset.x !== 0 || rawOffset.y !== 0) {
|
|
79086
|
-
const rotatedOffset =
|
|
79221
|
+
const rotatedOffset = applyToPoint22(rotationMatrix, {
|
|
79087
79222
|
x: -rawOffset.x,
|
|
79088
79223
|
y: rawOffset.y
|
|
79089
79224
|
});
|
|
@@ -79199,7 +79334,7 @@ function createNpthPadFromCircuitJson({
|
|
|
79199
79334
|
const relativeX = pcbHole.x - componentCenter.x;
|
|
79200
79335
|
const relativeY = -(pcbHole.y - componentCenter.y);
|
|
79201
79336
|
const rotationMatrix = componentRotation !== 0 ? rotate11(componentRotation * Math.PI / 180) : identity6();
|
|
79202
|
-
const rotatedPos =
|
|
79337
|
+
const rotatedPos = applyToPoint23(rotationMatrix, {
|
|
79203
79338
|
x: relativeX,
|
|
79204
79339
|
y: relativeY
|
|
79205
79340
|
});
|
|
@@ -79283,11 +79418,11 @@ function convertFabricationNotePaths(fabricationNotePaths, {
|
|
|
79283
79418
|
const endPoint = fabricationNotePath.route[index + 1];
|
|
79284
79419
|
if (!startPoint || !endPoint)
|
|
79285
79420
|
continue;
|
|
79286
|
-
const startRelative =
|
|
79421
|
+
const startRelative = applyToPoint24(rotationMatrix, {
|
|
79287
79422
|
x: startPoint.x - componentCenter.x,
|
|
79288
79423
|
y: -(startPoint.y - componentCenter.y)
|
|
79289
79424
|
});
|
|
79290
|
-
const endRelative =
|
|
79425
|
+
const endRelative = applyToPoint24(rotationMatrix, {
|
|
79291
79426
|
x: endPoint.x - componentCenter.x,
|
|
79292
79427
|
y: -(endPoint.y - componentCenter.y)
|
|
79293
79428
|
});
|
|
@@ -79304,6 +79439,94 @@ function convertFabricationNotePaths(fabricationNotePaths, {
|
|
|
79304
79439
|
}
|
|
79305
79440
|
return fpLines;
|
|
79306
79441
|
}
|
|
79442
|
+
var getSolderPasteCenter = (solderPaste) => {
|
|
79443
|
+
if ("x" in solderPaste && "y" in solderPaste) {
|
|
79444
|
+
return { x: solderPaste.x, y: solderPaste.y };
|
|
79445
|
+
}
|
|
79446
|
+
return {
|
|
79447
|
+
x: solderPaste.points.reduce((sum, point) => sum + point.x, 0) / solderPaste.points.length,
|
|
79448
|
+
y: solderPaste.points.reduce((sum, point) => sum + point.y, 0) / solderPaste.points.length
|
|
79449
|
+
};
|
|
79450
|
+
};
|
|
79451
|
+
var createSolderPastePadFromCircuitJson = ({
|
|
79452
|
+
solderPaste,
|
|
79453
|
+
componentCenter,
|
|
79454
|
+
componentRotation = 0
|
|
79455
|
+
}) => {
|
|
79456
|
+
const polygonAnchor = solderPaste.shape === "polygon" ? getSafePolygonAnchor(solderPaste.points, solderPaste.holes) : undefined;
|
|
79457
|
+
const center = polygonAnchor?.center ?? getSolderPasteCenter(solderPaste);
|
|
79458
|
+
const boardToFootprint = getBoardToFootprintTransform({
|
|
79459
|
+
footprintOrigin: componentCenter,
|
|
79460
|
+
ccwRotationDegrees: componentRotation
|
|
79461
|
+
});
|
|
79462
|
+
const position = applyToPoint25(boardToFootprint, center);
|
|
79463
|
+
let shape;
|
|
79464
|
+
let size;
|
|
79465
|
+
let rotation = 0;
|
|
79466
|
+
let roundrectRatio;
|
|
79467
|
+
let options;
|
|
79468
|
+
let customContours;
|
|
79469
|
+
if (solderPaste.shape === "oval") {
|
|
79470
|
+
shape = "custom";
|
|
79471
|
+
size = [
|
|
79472
|
+
Math.min(0.001, solderPaste.width, solderPaste.height),
|
|
79473
|
+
Math.min(0.001, solderPaste.width, solderPaste.height)
|
|
79474
|
+
];
|
|
79475
|
+
options = new PadOptions2;
|
|
79476
|
+
options.anchor = "circle";
|
|
79477
|
+
customContours = [
|
|
79478
|
+
createEllipseContour({
|
|
79479
|
+
center,
|
|
79480
|
+
width: solderPaste.width,
|
|
79481
|
+
height: solderPaste.height
|
|
79482
|
+
})
|
|
79483
|
+
];
|
|
79484
|
+
} else if (solderPaste.shape === "polygon") {
|
|
79485
|
+
if (!polygonAnchor) {
|
|
79486
|
+
throw new Error("Solder-paste polygon is missing its anchor geometry");
|
|
79487
|
+
}
|
|
79488
|
+
shape = "custom";
|
|
79489
|
+
size = [polygonAnchor.diameter, polygonAnchor.diameter];
|
|
79490
|
+
options = new PadOptions2;
|
|
79491
|
+
options.anchor = "circle";
|
|
79492
|
+
customContours = solderPaste.holes?.length ? polygonAnchor.triangles : [solderPaste.points];
|
|
79493
|
+
} else {
|
|
79494
|
+
const geometry = getKicadNativePadGeometry(solderPaste);
|
|
79495
|
+
shape = geometry.shape;
|
|
79496
|
+
size = geometry.size;
|
|
79497
|
+
rotation = geometry.rotation;
|
|
79498
|
+
roundrectRatio = geometry.roundrectRatio;
|
|
79499
|
+
}
|
|
79500
|
+
const layer = solderPaste.layer === "bottom" ? "B.Paste" : "F.Paste";
|
|
79501
|
+
const pad = new FootprintPad4({
|
|
79502
|
+
number: "",
|
|
79503
|
+
padType: "smd",
|
|
79504
|
+
shape,
|
|
79505
|
+
at: [position.x, position.y, rotation],
|
|
79506
|
+
size,
|
|
79507
|
+
layers: [layer],
|
|
79508
|
+
roundrectRatio,
|
|
79509
|
+
uuid: generateDeterministicUuid(`solder_paste:${solderPaste.pcb_solder_paste_id}`)
|
|
79510
|
+
});
|
|
79511
|
+
if (options)
|
|
79512
|
+
pad.options = options;
|
|
79513
|
+
if (customContours) {
|
|
79514
|
+
pad.primitives = createFilledPolygonPrimitives({
|
|
79515
|
+
contours: customContours,
|
|
79516
|
+
center
|
|
79517
|
+
});
|
|
79518
|
+
}
|
|
79519
|
+
return pad;
|
|
79520
|
+
};
|
|
79521
|
+
var convertSolderPaste = ({
|
|
79522
|
+
solderPaste,
|
|
79523
|
+
componentCenter,
|
|
79524
|
+
componentRotation = 0
|
|
79525
|
+
}) => solderPaste.map((aperture) => createSolderPastePadFromCircuitJson({
|
|
79526
|
+
solderPaste: aperture,
|
|
79527
|
+
componentCenter,
|
|
79528
|
+
componentRotation
|
|
79529
|
+
}));
|
|
79307
79530
|
var AddFootprintsStage = class extends ConverterStage {
|
|
79308
79531
|
componentsProcessed = 0;
|
|
79309
79532
|
pcbComponents = [];
|
|
@@ -79379,7 +79602,7 @@ var AddFootprintsStage = class extends ConverterStage {
|
|
|
79379
79602
|
const cadComponent = this.getCadComponentForPcbComponent(component.pcb_component_id);
|
|
79380
79603
|
const footprintName = sourceComponent ? getKicadCompatibleComponentName(sourceComponent, cadComponent) : "Unknown";
|
|
79381
79604
|
const footprintOrigin = component.footprint_origin ?? component.center;
|
|
79382
|
-
const transformedPos =
|
|
79605
|
+
const transformedPos = applyToPoint26(c2kMatPcb, {
|
|
79383
79606
|
x: footprintOrigin.x,
|
|
79384
79607
|
y: footprintOrigin.y
|
|
79385
79608
|
});
|
|
@@ -79429,6 +79652,18 @@ var AddFootprintsStage = class extends ConverterStage {
|
|
|
79429
79652
|
getNetInfo
|
|
79430
79653
|
}, this.ctx);
|
|
79431
79654
|
fpPads.push(...smdPads);
|
|
79655
|
+
const pcbSolderPaste = this.ctx.db.pcb_solder_paste?.list().filter((paste) => {
|
|
79656
|
+
if (paste.pcb_component_id === component.pcb_component_id) {
|
|
79657
|
+
return true;
|
|
79658
|
+
}
|
|
79659
|
+
const linkedPad = paste.pcb_smtpad_id ? this.ctx.db.pcb_smtpad.get(paste.pcb_smtpad_id) : undefined;
|
|
79660
|
+
return !paste.pcb_component_id && linkedPad?.pcb_component_id === component.pcb_component_id;
|
|
79661
|
+
}) || [];
|
|
79662
|
+
fpPads.push(...convertSolderPaste({
|
|
79663
|
+
solderPaste: pcbSolderPaste,
|
|
79664
|
+
componentCenter: footprintOrigin,
|
|
79665
|
+
componentRotation: component.rotation || 0
|
|
79666
|
+
}));
|
|
79432
79667
|
const pcbPlatedHoles = this.ctx.db.pcb_plated_hole?.list().filter((hole) => hole.pcb_component_id === component.pcb_component_id) || [];
|
|
79433
79668
|
const { pads: thruHolePads } = convertPlatedHoles({
|
|
79434
79669
|
platedHoles: pcbPlatedHoles,
|
|
@@ -79628,8 +79863,8 @@ var AddTracesStage = class extends ConverterStage {
|
|
|
79628
79863
|
if (!startPosition || !endPosition) {
|
|
79629
79864
|
throw new Error(`Unable to convert pcb_trace route segment ${trace.pcb_trace_id ?? this.tracesProcessed}:${i} to KiCad segment`);
|
|
79630
79865
|
}
|
|
79631
|
-
const transformedStart =
|
|
79632
|
-
const transformedEnd =
|
|
79866
|
+
const transformedStart = applyToPoint27(c2kMatPcb, startPosition);
|
|
79867
|
+
const transformedEnd = applyToPoint27(c2kMatPcb, endPosition);
|
|
79633
79868
|
if (transformedStart.x === transformedEnd.x && transformedStart.y === transformedEnd.y) {
|
|
79634
79869
|
continue;
|
|
79635
79870
|
}
|
|
@@ -79712,6 +79947,11 @@ var createViaTenting = (via, board) => {
|
|
|
79712
79947
|
};
|
|
79713
79948
|
var DEFAULT_VIA_OUTER_DIAMETER = 0.8;
|
|
79714
79949
|
var DEFAULT_VIA_HOLE_DIAMETER = 0.4;
|
|
79950
|
+
var VIA_POSITION_TOLERANCE = 0.000001;
|
|
79951
|
+
var getViaPositionCell = (via) => ({
|
|
79952
|
+
x: Math.floor(via.x / VIA_POSITION_TOLERANCE),
|
|
79953
|
+
y: Math.floor(via.y / VIA_POSITION_TOLERANCE)
|
|
79954
|
+
});
|
|
79715
79955
|
var AddViasStage = class extends ConverterStage {
|
|
79716
79956
|
boardOwnerMap;
|
|
79717
79957
|
viasProcessed = 0;
|
|
@@ -79725,7 +79965,8 @@ var AddViasStage = class extends ConverterStage {
|
|
|
79725
79965
|
const seenRouteViaKeys = /* @__PURE__ */ new Set;
|
|
79726
79966
|
const standaloneViasByPosition = /* @__PURE__ */ new Map;
|
|
79727
79967
|
for (const via of standaloneVias) {
|
|
79728
|
-
const
|
|
79968
|
+
const { x, y } = getViaPositionCell(via);
|
|
79969
|
+
const positionKey = `${x}:${y}`;
|
|
79729
79970
|
const viasAtPosition = standaloneViasByPosition.get(positionKey) ?? [];
|
|
79730
79971
|
viasAtPosition.push(via);
|
|
79731
79972
|
standaloneViasByPosition.set(positionKey, viasAtPosition);
|
|
@@ -79744,8 +79985,14 @@ var AddViasStage = class extends ConverterStage {
|
|
|
79744
79985
|
tented_on_top: point.tented_on_top,
|
|
79745
79986
|
tented_on_bottom: point.tented_on_bottom
|
|
79746
79987
|
})).filter((via) => {
|
|
79747
|
-
const
|
|
79748
|
-
|
|
79988
|
+
const { x, y } = getViaPositionCell(via);
|
|
79989
|
+
const physicalVias = [];
|
|
79990
|
+
for (let dx = -1;dx <= 1; dx++) {
|
|
79991
|
+
for (let dy = -1;dy <= 1; dy++) {
|
|
79992
|
+
physicalVias.push(...standaloneViasByPosition.get(`${x + dx}:${y + dy}`) ?? []);
|
|
79993
|
+
}
|
|
79994
|
+
}
|
|
79995
|
+
if (physicalVias.some((physicalVia) => {
|
|
79749
79996
|
const sameTrace = physicalVia.pcb_trace_id !== undefined && physicalVia.pcb_trace_id === via.pcb_trace_id;
|
|
79750
79997
|
const physicalConnection = physicalVia.net?.id ?? physicalVia.subcircuit_connectivity_map_key;
|
|
79751
79998
|
const routeConnection = via.net?.id ?? via.subcircuit_connectivity_map_key;
|
|
@@ -79755,7 +80002,11 @@ var AddViasStage = class extends ConverterStage {
|
|
|
79755
80002
|
} else if (!sameTrace) {
|
|
79756
80003
|
return false;
|
|
79757
80004
|
}
|
|
79758
|
-
return isRouteViaCoveredByPhysicalVia(
|
|
80005
|
+
return isRouteViaCoveredByPhysicalVia({
|
|
80006
|
+
viaWithLayers: physicalVia,
|
|
80007
|
+
routeVia: via,
|
|
80008
|
+
positionTolerance: VIA_POSITION_TOLERANCE
|
|
80009
|
+
});
|
|
79759
80010
|
})) {
|
|
79760
80011
|
return false;
|
|
79761
80012
|
}
|
|
@@ -79814,10 +80065,10 @@ var AddViasStage = class extends ConverterStage {
|
|
|
79814
80065
|
this.finished = true;
|
|
79815
80066
|
return;
|
|
79816
80067
|
}
|
|
79817
|
-
this.boardOwnerMap ??=
|
|
80068
|
+
this.boardOwnerMap ??= createBoardOwnerMap2(this.input);
|
|
79818
80069
|
const boardOwnerId = via.pcb_via_id ?? via.pcb_trace_id;
|
|
79819
80070
|
const board = boardOwnerId ? this.boardOwnerMap.get(boardOwnerId) : undefined;
|
|
79820
|
-
const transformedPos =
|
|
80071
|
+
const transformedPos = applyToPoint28(c2kMatPcb, {
|
|
79821
80072
|
x: via.x,
|
|
79822
80073
|
y: via.y
|
|
79823
80074
|
});
|
|
@@ -79843,6 +80094,34 @@ var AddViasStage = class extends ConverterStage {
|
|
|
79843
80094
|
return this.ctx.kicadPcb;
|
|
79844
80095
|
}
|
|
79845
80096
|
};
|
|
80097
|
+
var normalizePolygonPoints = (points, origin) => points.map((point) => ({
|
|
80098
|
+
x: point.x - origin.x,
|
|
80099
|
+
y: point.y - origin.y
|
|
80100
|
+
}));
|
|
80101
|
+
var getSolderPasteLibraryLink = (paste) => {
|
|
80102
|
+
const prefix = `tscircuit:solderpaste_${paste.layer}_${paste.shape}`;
|
|
80103
|
+
switch (paste.shape) {
|
|
80104
|
+
case "circle":
|
|
80105
|
+
return `${prefix}_diameter${paste.radius * 2}mm`;
|
|
80106
|
+
case "rect":
|
|
80107
|
+
case "oval":
|
|
80108
|
+
return `${prefix}_width${paste.width}mm_height${paste.height}mm`;
|
|
80109
|
+
case "rotated_rect":
|
|
80110
|
+
return `${prefix}_width${paste.width}mm_height${paste.height}mm_ccwRotation${paste.ccw_rotation}deg`;
|
|
80111
|
+
case "pill":
|
|
80112
|
+
return `${prefix}_width${paste.width}mm_height${paste.height}mm_radius${getResolvedPillRadius(paste)}mm`;
|
|
80113
|
+
case "rotated_pill":
|
|
80114
|
+
return `${prefix}_width${paste.width}mm_height${paste.height}mm_radius${getResolvedPillRadius(paste)}mm_ccwRotation${paste.ccw_rotation}deg`;
|
|
80115
|
+
case "polygon": {
|
|
80116
|
+
const origin = paste.points[0] ?? { x: 0, y: 0 };
|
|
80117
|
+
const geometry = JSON.stringify({
|
|
80118
|
+
points: normalizePolygonPoints(paste.points, origin),
|
|
80119
|
+
holes: paste.holes?.map((hole) => normalizePolygonPoints(hole, origin))
|
|
80120
|
+
});
|
|
80121
|
+
return `${prefix}_${generateDeterministicUuid(geometry)}`;
|
|
80122
|
+
}
|
|
80123
|
+
}
|
|
80124
|
+
};
|
|
79846
80125
|
var AddStandalonePcbElements = class extends ConverterStage {
|
|
79847
80126
|
unprocessedElements = [];
|
|
79848
80127
|
constructor(input, ctx) {
|
|
@@ -79850,7 +80129,8 @@ var AddStandalonePcbElements = class extends ConverterStage {
|
|
|
79850
80129
|
this.unprocessedElements = [
|
|
79851
80130
|
...this.ctx.db.pcb_hole.list().filter((hole) => !hole.pcb_component_id),
|
|
79852
80131
|
...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)
|
|
80132
|
+
...this.ctx.db.pcb_smtpad.list().filter((pad) => !pad.pcb_component_id),
|
|
80133
|
+
...this.ctx.db.pcb_solder_paste.list().filter((paste) => !paste.pcb_component_id && !paste.pcb_smtpad_id)
|
|
79854
80134
|
];
|
|
79855
80135
|
}
|
|
79856
80136
|
_step() {
|
|
@@ -79870,21 +80150,45 @@ var AddStandalonePcbElements = class extends ConverterStage {
|
|
|
79870
80150
|
const pcbPad = elm;
|
|
79871
80151
|
const padCenter = this.getPcbSmtPadCenter(pcbPad);
|
|
79872
80152
|
const footprintSeed = `standalone_smtpad:${pcbPad.pcb_smtpad_id}:${padCenter.x},${padCenter.y}`;
|
|
79873
|
-
const kicadPos =
|
|
80153
|
+
const kicadPos = applyToPoint29(c2kMatPcb, padCenter);
|
|
79874
80154
|
const footprint = new Footprint5({
|
|
79875
80155
|
libraryLink: this.getSmtPadLibraryLink(pcbPad),
|
|
79876
80156
|
layer: "F.Cu",
|
|
79877
80157
|
at: [kicadPos.x, kicadPos.y, 0],
|
|
79878
80158
|
uuid: generateDeterministicUuid(footprintSeed)
|
|
79879
80159
|
});
|
|
80160
|
+
const linkedSolderPaste = this.ctx.db.pcb_solder_paste.list().filter((paste) => paste.pcb_smtpad_id === pcbPad.pcb_smtpad_id);
|
|
79880
80161
|
footprint.fpPads = [
|
|
79881
80162
|
createSmdPadFromCircuitJson({
|
|
79882
80163
|
pcbPad,
|
|
79883
|
-
hasSolderPaste: this.ctx.db.pcb_solder_paste.list().some((paste) => paste.pcb_smtpad_id === pcbPad.pcb_smtpad_id),
|
|
79884
80164
|
componentCenter: padCenter,
|
|
79885
80165
|
padNumber: 1,
|
|
79886
80166
|
componentRotation: 0,
|
|
79887
80167
|
componentId: pcbPad.pcb_smtpad_id
|
|
80168
|
+
}),
|
|
80169
|
+
...linkedSolderPaste.map((solderPaste) => createSolderPastePadFromCircuitJson({
|
|
80170
|
+
solderPaste,
|
|
80171
|
+
componentCenter: padCenter
|
|
80172
|
+
}))
|
|
80173
|
+
];
|
|
80174
|
+
applyInferredFootprintType(footprint);
|
|
80175
|
+
const footprints = kicadPcb.footprints;
|
|
80176
|
+
footprints.push(footprint);
|
|
80177
|
+
kicadPcb.footprints = footprints;
|
|
80178
|
+
} else if (elm.type === "pcb_solder_paste") {
|
|
80179
|
+
const center = getSolderPasteCenter(elm);
|
|
80180
|
+
const footprintSeed = `standalone_solder_paste:${elm.pcb_solder_paste_id}`;
|
|
80181
|
+
const kicadPos = applyToPoint29(c2kMatPcb, center);
|
|
80182
|
+
const footprint = new Footprint5({
|
|
80183
|
+
libraryLink: getSolderPasteLibraryLink(elm),
|
|
80184
|
+
layer: elm.layer === "bottom" ? "B.Cu" : "F.Cu",
|
|
80185
|
+
at: [kicadPos.x, kicadPos.y, 0],
|
|
80186
|
+
uuid: generateDeterministicUuid(footprintSeed)
|
|
80187
|
+
});
|
|
80188
|
+
footprint.fpPads = [
|
|
80189
|
+
createSolderPastePadFromCircuitJson({
|
|
80190
|
+
solderPaste: elm,
|
|
80191
|
+
componentCenter: center
|
|
79888
80192
|
})
|
|
79889
80193
|
];
|
|
79890
80194
|
applyInferredFootprintType(footprint);
|
|
@@ -79894,7 +80198,7 @@ var AddStandalonePcbElements = class extends ConverterStage {
|
|
|
79894
80198
|
} else if (elm.type === "pcb_hole") {
|
|
79895
80199
|
const hole = elm;
|
|
79896
80200
|
const footprintSeed = `standalone_hole:${hole.pcb_hole_id}:${hole.x},${hole.y}`;
|
|
79897
|
-
const kicadPos =
|
|
80201
|
+
const kicadPos = applyToPoint29(c2kMatPcb, { x: hole.x, y: hole.y });
|
|
79898
80202
|
const libraryLink = this.getHoleLibraryLink(hole);
|
|
79899
80203
|
const footprint = new Footprint5({
|
|
79900
80204
|
libraryLink,
|
|
@@ -79917,7 +80221,7 @@ var AddStandalonePcbElements = class extends ConverterStage {
|
|
|
79917
80221
|
} else if (elm.type === "pcb_plated_hole") {
|
|
79918
80222
|
const hole = elm;
|
|
79919
80223
|
const footprintSeed = `standalone_plated_hole:${hole.pcb_plated_hole_id}:${hole.x},${hole.y}`;
|
|
79920
|
-
const kicadPos =
|
|
80224
|
+
const kicadPos = applyToPoint29(c2kMatPcb, { x: hole.x, y: hole.y });
|
|
79921
80225
|
const libraryLink = this.getPlatedHoleLibraryLink(hole);
|
|
79922
80226
|
const footprint = new Footprint5({
|
|
79923
80227
|
libraryLink,
|
|
@@ -80015,7 +80319,7 @@ function createFabricationNoteTextFromCircuitJson({
|
|
|
80015
80319
|
if (!textElement.text || !textElement.anchor_position) {
|
|
80016
80320
|
return null;
|
|
80017
80321
|
}
|
|
80018
|
-
const transformedPos =
|
|
80322
|
+
const transformedPos = applyToPoint30(c2kMatPcb, {
|
|
80019
80323
|
x: textElement.anchor_position.x,
|
|
80020
80324
|
y: textElement.anchor_position.y
|
|
80021
80325
|
});
|
|
@@ -80056,7 +80360,8 @@ function createFabricationNoteTextFromCircuitJson({
|
|
|
80056
80360
|
if (anchorAlignment !== "center") {
|
|
80057
80361
|
textEffects.justify = justify;
|
|
80058
80362
|
}
|
|
80059
|
-
const
|
|
80363
|
+
const rotation = textElement.type === "pcb_fabrication_note_text" ? textElement.ccw_rotation ?? 0 : 0;
|
|
80364
|
+
const position = new At3([transformedPos.x, transformedPos.y, rotation]);
|
|
80060
80365
|
const grText = new GrText({
|
|
80061
80366
|
text: textElement.text,
|
|
80062
80367
|
layer: kicadLayer,
|
|
@@ -80073,7 +80378,7 @@ function createGrTextFromCircuitJson({
|
|
|
80073
80378
|
if (!textElement.text || !textElement.anchor_position) {
|
|
80074
80379
|
return null;
|
|
80075
80380
|
}
|
|
80076
|
-
const transformedPos =
|
|
80381
|
+
const transformedPos = applyToPoint31(c2kMatPcb, {
|
|
80077
80382
|
x: textElement.anchor_position.x,
|
|
80078
80383
|
y: textElement.anchor_position.y
|
|
80079
80384
|
});
|
|
@@ -80110,6 +80415,9 @@ function createGrTextFromCircuitJson({
|
|
|
80110
80415
|
grText.position = position;
|
|
80111
80416
|
return grText;
|
|
80112
80417
|
}
|
|
80418
|
+
var KICAD_PCB_UNITS_PER_MM = 1e6;
|
|
80419
|
+
var roundBoardCoordinate = (coordinateMm) => Math.round(coordinateMm * KICAD_PCB_UNITS_PER_MM) / KICAD_PCB_UNITS_PER_MM;
|
|
80420
|
+
var roundPolygonToKicadPrecision = (geometry) => geometry.map((polygon) => polygon.map((ring) => ring.map(([x, y]) => [roundBoardCoordinate(x), roundBoardCoordinate(y)])));
|
|
80113
80421
|
var pointsAreEqual = (a, b) => !!a && !!b && a.x === b.x && a.y === b.y;
|
|
80114
80422
|
var normalizeOutlineCorners = (corners) => {
|
|
80115
80423
|
const dedupedCorners = [];
|
|
@@ -80125,6 +80433,13 @@ var normalizeOutlineCorners = (corners) => {
|
|
|
80125
80433
|
return dedupedCorners;
|
|
80126
80434
|
};
|
|
80127
80435
|
var DEFAULT_EDGE_CUTS_WIDTH = 0.1;
|
|
80436
|
+
var toKicadPoint = (point, c2kMatPcb) => {
|
|
80437
|
+
const transformed = applyToPoint32(c2kMatPcb, point);
|
|
80438
|
+
return [
|
|
80439
|
+
roundBoardCoordinate(transformed.x),
|
|
80440
|
+
roundBoardCoordinate(transformed.y)
|
|
80441
|
+
];
|
|
80442
|
+
};
|
|
80128
80443
|
var appendGraphicLine = (kicadPcb, grLine) => {
|
|
80129
80444
|
const graphicLines = kicadPcb.graphicLines;
|
|
80130
80445
|
graphicLines.push(grLine);
|
|
@@ -80133,18 +80448,10 @@ var appendGraphicLine = (kicadPcb, grLine) => {
|
|
|
80133
80448
|
var rotatePointAroundOrigin = (point, rotationDegrees = 0) => {
|
|
80134
80449
|
if (!rotationDegrees)
|
|
80135
80450
|
return point;
|
|
80136
|
-
return
|
|
80451
|
+
return applyToPoint32(rotate13(rotationDegrees * Math.PI / 180), point);
|
|
80137
80452
|
};
|
|
80138
80453
|
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) => {
|
|
80454
|
+
return getRectanglePoints(cutout).map((point) => {
|
|
80148
80455
|
const rotatedPoint = rotatePointAroundOrigin(point, cutout.rotation);
|
|
80149
80456
|
return {
|
|
80150
80457
|
x: rotatedPoint.x + cutout.center.x,
|
|
@@ -80171,11 +80478,11 @@ var AddGraphicsStage = class extends ConverterStage {
|
|
|
80171
80478
|
const endPoint = path.route[i + 1];
|
|
80172
80479
|
if (!startPoint || !endPoint)
|
|
80173
80480
|
continue;
|
|
80174
|
-
const transformedStart =
|
|
80481
|
+
const transformedStart = applyToPoint32(c2kMatPcb, {
|
|
80175
80482
|
x: startPoint.x,
|
|
80176
80483
|
y: startPoint.y
|
|
80177
80484
|
});
|
|
80178
|
-
const transformedEnd =
|
|
80485
|
+
const transformedEnd = applyToPoint32(c2kMatPcb, {
|
|
80179
80486
|
x: endPoint.x,
|
|
80180
80487
|
y: endPoint.y
|
|
80181
80488
|
});
|
|
@@ -80221,15 +80528,14 @@ var AddGraphicsStage = class extends ConverterStage {
|
|
|
80221
80528
|
kicadPcb.graphicTexts = graphicTexts;
|
|
80222
80529
|
}
|
|
80223
80530
|
}
|
|
80224
|
-
const
|
|
80225
|
-
|
|
80226
|
-
|
|
80227
|
-
|
|
80228
|
-
|
|
80229
|
-
|
|
80230
|
-
}
|
|
80531
|
+
const outlineElements = [
|
|
80532
|
+
...this.ctx.db.pcb_panel.list(),
|
|
80533
|
+
...this.ctx.db.pcb_board.list()
|
|
80534
|
+
];
|
|
80535
|
+
const outlinePolys = [];
|
|
80536
|
+
for (const board of outlineElements) {
|
|
80231
80537
|
let corners;
|
|
80232
|
-
if (board.outline && board.outline.length > 0) {
|
|
80538
|
+
if (board.type === "pcb_board" && board.outline && board.outline.length > 0) {
|
|
80233
80539
|
corners = normalizeOutlineCorners(board.outline);
|
|
80234
80540
|
} else {
|
|
80235
80541
|
const halfWidth = board.width ? board.width / 2 : 0;
|
|
@@ -80241,25 +80547,43 @@ var AddGraphicsStage = class extends ConverterStage {
|
|
|
80241
80547
|
{ x: board.center.x - halfWidth, y: board.center.y + halfHeight }
|
|
80242
80548
|
];
|
|
80243
80549
|
}
|
|
80550
|
+
outlinePolys.push([
|
|
80551
|
+
[corners.map((point) => toKicadPoint(point, c2kMatPcb))]
|
|
80552
|
+
]);
|
|
80553
|
+
}
|
|
80554
|
+
const [firstOutline, ...otherOutlines] = outlinePolys;
|
|
80555
|
+
if (firstOutline) {
|
|
80244
80556
|
const pcbCutouts2 = this.ctx.db.pcb_cutout?.list() || [];
|
|
80245
80557
|
const cutoutPolys = [];
|
|
80246
80558
|
for (const cutout of pcbCutouts2) {
|
|
80247
80559
|
if (cutout.shape === "rect") {
|
|
80248
80560
|
const cutoutCorners = getRectCutoutCorners(cutout);
|
|
80249
|
-
cutoutPolys.push([
|
|
80561
|
+
cutoutPolys.push([
|
|
80562
|
+
[cutoutCorners.map((point) => toKicadPoint(point, c2kMatPcb))]
|
|
80563
|
+
]);
|
|
80250
80564
|
} else if (cutout.shape === "circle") {
|
|
80251
|
-
cutoutPolys.push([
|
|
80565
|
+
cutoutPolys.push([
|
|
80566
|
+
[
|
|
80567
|
+
circleToPolygon(cutout.center, cutout.radius).map(([x, y]) => toKicadPoint({ x, y }, c2kMatPcb))
|
|
80568
|
+
]
|
|
80569
|
+
]);
|
|
80252
80570
|
} else if (cutout.shape === "polygon") {
|
|
80253
|
-
cutoutPolys.push([
|
|
80571
|
+
cutoutPolys.push([
|
|
80572
|
+
[cutout.points.map((point) => toKicadPoint(point, c2kMatPcb))]
|
|
80573
|
+
]);
|
|
80254
80574
|
}
|
|
80255
80575
|
}
|
|
80256
|
-
let boardGeom =
|
|
80576
|
+
let boardGeom = otherOutlines.length > 0 ? import_polygon_clipping.default.union(firstOutline, ...otherOutlines) : firstOutline;
|
|
80257
80577
|
if (cutoutPolys.length > 0) {
|
|
80258
|
-
boardGeom = import_polygon_clipping.default.difference(boardGeom, ...cutoutPolys);
|
|
80578
|
+
boardGeom = import_polygon_clipping.default.difference(roundPolygonToKicadPrecision(boardGeom), ...cutoutPolys);
|
|
80259
80579
|
}
|
|
80580
|
+
boardGeom = roundPolygonToKicadPrecision(boardGeom);
|
|
80260
80581
|
for (const poly of boardGeom) {
|
|
80261
80582
|
for (const ring of poly) {
|
|
80262
|
-
const transformedRing = ring.map((
|
|
80583
|
+
const transformedRing = ring.map(([x, y]) => ({
|
|
80584
|
+
x,
|
|
80585
|
+
y
|
|
80586
|
+
}));
|
|
80263
80587
|
for (let i = 0;i < transformedRing.length; i++) {
|
|
80264
80588
|
const start = transformedRing[i];
|
|
80265
80589
|
const end = transformedRing[(i + 1) % transformedRing.length];
|
|
@@ -80288,8 +80612,8 @@ var AddGraphicsStage = class extends ConverterStage {
|
|
|
80288
80612
|
const endPoint = cutout.route[i + 1];
|
|
80289
80613
|
if (!startPoint || !endPoint)
|
|
80290
80614
|
continue;
|
|
80291
|
-
const transformedStart =
|
|
80292
|
-
const transformedEnd =
|
|
80615
|
+
const transformedStart = applyToPoint32(c2kMatPcb, startPoint);
|
|
80616
|
+
const transformedEnd = applyToPoint32(c2kMatPcb, endPoint);
|
|
80293
80617
|
appendGraphicLine(kicadPcb, new GrLine({
|
|
80294
80618
|
start: transformedStart,
|
|
80295
80619
|
end: transformedEnd,
|
|
@@ -80324,7 +80648,7 @@ var CircuitJsonToKicadPcbConverter = class {
|
|
|
80324
80648
|
generator: "circuit-json-to-kicad",
|
|
80325
80649
|
generatorVersion: "0.0.1"
|
|
80326
80650
|
}),
|
|
80327
|
-
c2kMatPcb:
|
|
80651
|
+
c2kMatPcb: compose11(translate11(KICAD_PCB_CENTER_X, KICAD_PCB_CENTER_Y), scale8(CIRCUIT_JSON_TO_MM_SCALE, -CIRCUIT_JSON_TO_MM_SCALE)),
|
|
80328
80652
|
projectName: options?.projectName,
|
|
80329
80653
|
edgeCutsWidth: options?.edgeCutsWidth,
|
|
80330
80654
|
pcbModel3dSourcePaths: []
|
|
@@ -80410,6 +80734,46 @@ var CircuitJsonToKicadProConverter = class {
|
|
|
80410
80734
|
trackWidth: minTrackWidth
|
|
80411
80735
|
})
|
|
80412
80736
|
];
|
|
80737
|
+
const sourceNets = this.ctx.db.source_net?.list() ?? [];
|
|
80738
|
+
const netClassNameByTraceWidth = /* @__PURE__ */ new Map([
|
|
80739
|
+
[minTrackWidth, "Default"]
|
|
80740
|
+
]);
|
|
80741
|
+
const explicitTraceWidths = Array.from(new Set(sourceNets.flatMap((sourceNet) => sourceNet.trace_width === undefined ? [] : [sourceNet.trace_width]))).sort((a, b) => a - b);
|
|
80742
|
+
for (const traceWidth of explicitTraceWidths) {
|
|
80743
|
+
if (netClassNameByTraceWidth.has(traceWidth))
|
|
80744
|
+
continue;
|
|
80745
|
+
const netClassName = `Trace Width ${traceWidth} mm`;
|
|
80746
|
+
netClasses.push(this.createBaseNetClass({
|
|
80747
|
+
name: netClassName,
|
|
80748
|
+
viaDiameter: minViaDiameter,
|
|
80749
|
+
viaDrill: minViaDrill,
|
|
80750
|
+
clearance: minTraceToPadClearance,
|
|
80751
|
+
trackWidth: traceWidth
|
|
80752
|
+
}));
|
|
80753
|
+
netClassNameByTraceWidth.set(traceWidth, netClassName);
|
|
80754
|
+
}
|
|
80755
|
+
const netClassByNetName = /* @__PURE__ */ new Map;
|
|
80756
|
+
const boardOwnerMap = this.ctx.db.pcb_board.list().length > 1 ? createBoardOwnerMap3(this.ctx.circuitJson) : undefined;
|
|
80757
|
+
const sourceNetsWithTraceWidths = sourceNets.filter((sourceNet) => sourceNet.trace_width !== undefined).map((sourceNet) => {
|
|
80758
|
+
const connectivityKey = sourceNet.subcircuit_connectivity_map_key || sourceNet.source_net_id;
|
|
80759
|
+
return {
|
|
80760
|
+
sourceNet,
|
|
80761
|
+
netName: resolveKicadPcbNetName({
|
|
80762
|
+
candidateName: sourceNet.name || sourceNet.source_net_id,
|
|
80763
|
+
connectivityKey,
|
|
80764
|
+
boardId: boardOwnerMap?.get(sourceNet.subcircuit_id ?? "")?.pcb_board_id
|
|
80765
|
+
})
|
|
80766
|
+
};
|
|
80767
|
+
}).sort((a, b) => a.netName.localeCompare(b.netName) || a.sourceNet.source_net_id.localeCompare(b.sourceNet.source_net_id));
|
|
80768
|
+
for (const { sourceNet, netName } of sourceNetsWithTraceWidths) {
|
|
80769
|
+
const netClassName = netClassNameByTraceWidth.get(sourceNet.trace_width);
|
|
80770
|
+
const existingNetClassName = netClassByNetName.get(netName);
|
|
80771
|
+
if (existingNetClassName !== undefined && existingNetClassName !== netClassName) {
|
|
80772
|
+
throw new Error(`Cannot preserve conflicting trace widths for KiCad net "${netName}": ${existingNetClassName} and ${netClassName}`);
|
|
80773
|
+
}
|
|
80774
|
+
netClassByNetName.set(netName, netClassName);
|
|
80775
|
+
}
|
|
80776
|
+
const netclassPatterns = Array.from(netClassByNetName, ([pattern, netclass]) => ({ pattern, netclass }));
|
|
80413
80777
|
this.project = {
|
|
80414
80778
|
version: 1,
|
|
80415
80779
|
head: {
|
|
@@ -80441,10 +80805,11 @@ var CircuitJsonToKicadProConverter = class {
|
|
|
80441
80805
|
},
|
|
80442
80806
|
net_settings: {
|
|
80443
80807
|
meta: {
|
|
80444
|
-
version:
|
|
80808
|
+
version: 3
|
|
80445
80809
|
},
|
|
80446
|
-
last_net_id:
|
|
80447
|
-
classes: netClasses
|
|
80810
|
+
last_net_id: 0,
|
|
80811
|
+
classes: netClasses,
|
|
80812
|
+
netclass_patterns: netclassPatterns
|
|
80448
80813
|
},
|
|
80449
80814
|
pcbnew: {
|
|
80450
80815
|
page_layout_descr_file: "",
|