@tscircuit/core 0.0.480 → 0.0.481
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +274 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3565,10 +3565,7 @@ var getNumericSchPinStyle = (pinStyles, pinLabels) => {
|
|
|
3565
3565
|
};
|
|
3566
3566
|
|
|
3567
3567
|
// lib/components/primitive-components/Trace/Trace.ts
|
|
3568
|
-
import {
|
|
3569
|
-
MultilayerIjump,
|
|
3570
|
-
getObstaclesFromSoup
|
|
3571
|
-
} from "@tscircuit/infgrid-ijump-astar";
|
|
3568
|
+
import { MultilayerIjump } from "@tscircuit/infgrid-ijump-astar";
|
|
3572
3569
|
import { traceProps } from "@tscircuit/props";
|
|
3573
3570
|
import "circuit-json";
|
|
3574
3571
|
import { getFullConnectivityMapFromCircuitJson } from "circuit-json-to-connectivity-map";
|
|
@@ -4304,6 +4301,276 @@ var isRouteOutsideBoard = (mergedRoute, { db }) => {
|
|
|
4304
4301
|
return outsideBoard;
|
|
4305
4302
|
};
|
|
4306
4303
|
|
|
4304
|
+
// lib/utils/obstacles/getObstaclesFromRoute.ts
|
|
4305
|
+
var isCloseTo = (a, b) => Math.abs(a - b) < 1e-4;
|
|
4306
|
+
var getObstaclesFromRoute = (route, source_trace_id, { viaDiameter = 0.5 } = {}) => {
|
|
4307
|
+
const obstacles = [];
|
|
4308
|
+
for (let i = 0; i < route.length - 1; i++) {
|
|
4309
|
+
const [start, end] = [route[i], route[i + 1]];
|
|
4310
|
+
const prev = i - 1 >= 0 ? route[i - 1] : null;
|
|
4311
|
+
const isHorz = isCloseTo(start.y, end.y);
|
|
4312
|
+
const isVert = isCloseTo(start.x, end.x);
|
|
4313
|
+
if (!isHorz && !isVert) {
|
|
4314
|
+
throw new Error(
|
|
4315
|
+
`getObstaclesFromTrace currently only supports horizontal and vertical traces (not diagonals) Conflicting trace: ${source_trace_id}, start: (${start.x}, ${start.y}), end: (${end.x}, ${end.y})`
|
|
4316
|
+
);
|
|
4317
|
+
}
|
|
4318
|
+
const obstacle = {
|
|
4319
|
+
type: "rect",
|
|
4320
|
+
layers: [start.layer],
|
|
4321
|
+
center: {
|
|
4322
|
+
x: (start.x + end.x) / 2,
|
|
4323
|
+
y: (start.y + end.y) / 2
|
|
4324
|
+
},
|
|
4325
|
+
width: isHorz ? Math.abs(start.x - end.x) : 0.1,
|
|
4326
|
+
// TODO use route width
|
|
4327
|
+
height: isVert ? Math.abs(start.y - end.y) : 0.1,
|
|
4328
|
+
// TODO use route width
|
|
4329
|
+
connectedTo: [source_trace_id]
|
|
4330
|
+
};
|
|
4331
|
+
obstacles.push(obstacle);
|
|
4332
|
+
if (prev && prev.layer === start.layer && start.layer !== end.layer) {
|
|
4333
|
+
const via = {
|
|
4334
|
+
type: "rect",
|
|
4335
|
+
layers: [start.layer, end.layer],
|
|
4336
|
+
center: {
|
|
4337
|
+
x: start.x,
|
|
4338
|
+
y: start.y
|
|
4339
|
+
},
|
|
4340
|
+
connectedTo: [source_trace_id],
|
|
4341
|
+
width: viaDiameter,
|
|
4342
|
+
height: viaDiameter
|
|
4343
|
+
};
|
|
4344
|
+
obstacles.push(via);
|
|
4345
|
+
}
|
|
4346
|
+
}
|
|
4347
|
+
return obstacles;
|
|
4348
|
+
};
|
|
4349
|
+
|
|
4350
|
+
// lib/utils/obstacles/generateApproximatingRects.ts
|
|
4351
|
+
function generateApproximatingRects(rotatedRect, numRects = 4) {
|
|
4352
|
+
const { center, width, height, rotation: rotation2 } = rotatedRect;
|
|
4353
|
+
const rects = [];
|
|
4354
|
+
const angleRad = rotation2 * Math.PI / 180;
|
|
4355
|
+
const cosAngle = Math.cos(angleRad);
|
|
4356
|
+
const sinAngle = Math.sin(angleRad);
|
|
4357
|
+
const normalizedRotation = (rotation2 % 360 + 360) % 360;
|
|
4358
|
+
const sliceAlongWidth = height <= width ? normalizedRotation >= 45 && normalizedRotation < 135 || normalizedRotation >= 225 && normalizedRotation < 315 : normalizedRotation >= 135 && normalizedRotation < 225 || normalizedRotation >= 315 || normalizedRotation < 45;
|
|
4359
|
+
if (sliceAlongWidth) {
|
|
4360
|
+
const sliceWidth = width / numRects;
|
|
4361
|
+
for (let i = 0; i < numRects; i++) {
|
|
4362
|
+
const x = (i - numRects / 2 + 0.5) * sliceWidth;
|
|
4363
|
+
const rotatedX = -x * cosAngle;
|
|
4364
|
+
const rotatedY = -x * sinAngle;
|
|
4365
|
+
const coverageWidth = sliceWidth * 1.1;
|
|
4366
|
+
const coverageHeight = Math.abs(height * cosAngle) + Math.abs(sliceWidth * sinAngle);
|
|
4367
|
+
rects.push({
|
|
4368
|
+
center: {
|
|
4369
|
+
x: center.x + rotatedX,
|
|
4370
|
+
y: center.y + rotatedY
|
|
4371
|
+
},
|
|
4372
|
+
width: coverageWidth,
|
|
4373
|
+
height: coverageHeight
|
|
4374
|
+
});
|
|
4375
|
+
}
|
|
4376
|
+
} else {
|
|
4377
|
+
const sliceHeight = height / numRects;
|
|
4378
|
+
for (let i = 0; i < numRects; i++) {
|
|
4379
|
+
const y = (i - numRects / 2 + 0.5) * sliceHeight;
|
|
4380
|
+
const rotatedX = -y * sinAngle;
|
|
4381
|
+
const rotatedY = y * cosAngle;
|
|
4382
|
+
const coverageWidth = Math.abs(width * cosAngle) + Math.abs(sliceHeight * sinAngle);
|
|
4383
|
+
const coverageHeight = sliceHeight * 1.1;
|
|
4384
|
+
rects.push({
|
|
4385
|
+
center: {
|
|
4386
|
+
x: center.x + rotatedX,
|
|
4387
|
+
y: center.y + rotatedY
|
|
4388
|
+
},
|
|
4389
|
+
width: coverageWidth,
|
|
4390
|
+
height: coverageHeight
|
|
4391
|
+
});
|
|
4392
|
+
}
|
|
4393
|
+
}
|
|
4394
|
+
return rects;
|
|
4395
|
+
}
|
|
4396
|
+
|
|
4397
|
+
// lib/utils/obstacles/getObstaclesFromCircuitJson.ts
|
|
4398
|
+
var EVERY_LAYER = ["top", "inner1", "inner2", "bottom"];
|
|
4399
|
+
var getObstaclesFromCircuitJson = (soup, connMap) => {
|
|
4400
|
+
const withNetId = (idList) => connMap ? idList.concat(
|
|
4401
|
+
idList.map((id) => connMap?.getNetConnectedToId(id)).filter(Boolean)
|
|
4402
|
+
) : idList;
|
|
4403
|
+
const obstacles = [];
|
|
4404
|
+
for (const element of soup) {
|
|
4405
|
+
if (element.type === "pcb_smtpad") {
|
|
4406
|
+
if (element.shape === "circle") {
|
|
4407
|
+
obstacles.push({
|
|
4408
|
+
// @ts-ignore
|
|
4409
|
+
type: "oval",
|
|
4410
|
+
layers: [element.layer],
|
|
4411
|
+
center: {
|
|
4412
|
+
x: element.x,
|
|
4413
|
+
y: element.y
|
|
4414
|
+
},
|
|
4415
|
+
width: element.radius * 2,
|
|
4416
|
+
height: element.radius * 2,
|
|
4417
|
+
connectedTo: withNetId([element.pcb_smtpad_id])
|
|
4418
|
+
});
|
|
4419
|
+
} else if (element.shape === "rect") {
|
|
4420
|
+
obstacles.push({
|
|
4421
|
+
type: "rect",
|
|
4422
|
+
layers: [element.layer],
|
|
4423
|
+
center: {
|
|
4424
|
+
x: element.x,
|
|
4425
|
+
y: element.y
|
|
4426
|
+
},
|
|
4427
|
+
width: element.width,
|
|
4428
|
+
height: element.height,
|
|
4429
|
+
connectedTo: withNetId([element.pcb_smtpad_id])
|
|
4430
|
+
});
|
|
4431
|
+
} else if (element.shape === "rotated_rect") {
|
|
4432
|
+
const rotatedRect = {
|
|
4433
|
+
center: { x: element.x, y: element.y },
|
|
4434
|
+
width: element.width,
|
|
4435
|
+
height: element.height,
|
|
4436
|
+
rotation: element.ccw_rotation
|
|
4437
|
+
};
|
|
4438
|
+
const approximatingRects = generateApproximatingRects(rotatedRect);
|
|
4439
|
+
for (const rect of approximatingRects) {
|
|
4440
|
+
obstacles.push({
|
|
4441
|
+
type: "rect",
|
|
4442
|
+
layers: [element.layer],
|
|
4443
|
+
center: rect.center,
|
|
4444
|
+
width: rect.width,
|
|
4445
|
+
height: rect.height,
|
|
4446
|
+
connectedTo: withNetId([element.pcb_smtpad_id])
|
|
4447
|
+
});
|
|
4448
|
+
}
|
|
4449
|
+
}
|
|
4450
|
+
} else if (element.type === "pcb_keepout") {
|
|
4451
|
+
if (element.shape === "circle") {
|
|
4452
|
+
obstacles.push({
|
|
4453
|
+
// @ts-ignore
|
|
4454
|
+
type: "oval",
|
|
4455
|
+
layers: element.layers,
|
|
4456
|
+
center: {
|
|
4457
|
+
x: element.center.x,
|
|
4458
|
+
y: element.center.y
|
|
4459
|
+
},
|
|
4460
|
+
width: element.radius * 2,
|
|
4461
|
+
height: element.radius * 2,
|
|
4462
|
+
connectedTo: []
|
|
4463
|
+
});
|
|
4464
|
+
} else if (element.shape === "rect") {
|
|
4465
|
+
obstacles.push({
|
|
4466
|
+
type: "rect",
|
|
4467
|
+
layers: element.layers,
|
|
4468
|
+
center: {
|
|
4469
|
+
x: element.center.x,
|
|
4470
|
+
y: element.center.y
|
|
4471
|
+
},
|
|
4472
|
+
width: element.width,
|
|
4473
|
+
height: element.height,
|
|
4474
|
+
connectedTo: []
|
|
4475
|
+
});
|
|
4476
|
+
}
|
|
4477
|
+
} else if (element.type === "pcb_hole") {
|
|
4478
|
+
if (element.hole_shape === "oval") {
|
|
4479
|
+
obstacles.push({
|
|
4480
|
+
// @ts-ignore
|
|
4481
|
+
type: "oval",
|
|
4482
|
+
center: {
|
|
4483
|
+
x: element.x,
|
|
4484
|
+
y: element.y
|
|
4485
|
+
},
|
|
4486
|
+
width: element.hole_width,
|
|
4487
|
+
height: element.hole_height,
|
|
4488
|
+
connectedTo: []
|
|
4489
|
+
});
|
|
4490
|
+
} else if (element.hole_shape === "square") {
|
|
4491
|
+
obstacles.push({
|
|
4492
|
+
type: "rect",
|
|
4493
|
+
layers: EVERY_LAYER,
|
|
4494
|
+
center: {
|
|
4495
|
+
x: element.x,
|
|
4496
|
+
y: element.y
|
|
4497
|
+
},
|
|
4498
|
+
width: element.hole_diameter,
|
|
4499
|
+
height: element.hole_diameter,
|
|
4500
|
+
connectedTo: []
|
|
4501
|
+
});
|
|
4502
|
+
} else if (
|
|
4503
|
+
// @ts-ignore
|
|
4504
|
+
element.hole_shape === "round" || element.hole_shape === "circle"
|
|
4505
|
+
) {
|
|
4506
|
+
obstacles.push({
|
|
4507
|
+
type: "rect",
|
|
4508
|
+
layers: EVERY_LAYER,
|
|
4509
|
+
center: {
|
|
4510
|
+
x: element.x,
|
|
4511
|
+
y: element.y
|
|
4512
|
+
},
|
|
4513
|
+
width: element.hole_diameter,
|
|
4514
|
+
height: element.hole_diameter,
|
|
4515
|
+
connectedTo: []
|
|
4516
|
+
});
|
|
4517
|
+
}
|
|
4518
|
+
} else if (element.type === "pcb_plated_hole") {
|
|
4519
|
+
if (element.shape === "circle") {
|
|
4520
|
+
obstacles.push({
|
|
4521
|
+
// @ts-ignore
|
|
4522
|
+
type: "oval",
|
|
4523
|
+
layers: EVERY_LAYER,
|
|
4524
|
+
center: {
|
|
4525
|
+
x: element.x,
|
|
4526
|
+
y: element.y
|
|
4527
|
+
},
|
|
4528
|
+
width: element.outer_diameter,
|
|
4529
|
+
height: element.outer_diameter,
|
|
4530
|
+
connectedTo: withNetId([element.pcb_plated_hole_id])
|
|
4531
|
+
});
|
|
4532
|
+
} else if (element.shape === "oval" || element.shape === "pill") {
|
|
4533
|
+
obstacles.push({
|
|
4534
|
+
// @ts-ignore
|
|
4535
|
+
type: "oval",
|
|
4536
|
+
layers: EVERY_LAYER,
|
|
4537
|
+
center: {
|
|
4538
|
+
x: element.x,
|
|
4539
|
+
y: element.y
|
|
4540
|
+
},
|
|
4541
|
+
width: element.outer_width,
|
|
4542
|
+
height: element.outer_height,
|
|
4543
|
+
connectedTo: withNetId([element.pcb_plated_hole_id])
|
|
4544
|
+
});
|
|
4545
|
+
}
|
|
4546
|
+
} else if (element.type === "pcb_trace") {
|
|
4547
|
+
const traceObstacles = getObstaclesFromRoute(
|
|
4548
|
+
element.route.map((rp) => ({
|
|
4549
|
+
x: rp.x,
|
|
4550
|
+
y: rp.y,
|
|
4551
|
+
layer: "layer" in rp ? rp.layer : rp.from_layer
|
|
4552
|
+
})),
|
|
4553
|
+
element.source_trace_id
|
|
4554
|
+
);
|
|
4555
|
+
obstacles.push(...traceObstacles);
|
|
4556
|
+
} else if (element.type === "pcb_via") {
|
|
4557
|
+
obstacles.push({
|
|
4558
|
+
type: "rect",
|
|
4559
|
+
layers: element.layers,
|
|
4560
|
+
center: {
|
|
4561
|
+
x: element.x,
|
|
4562
|
+
y: element.y
|
|
4563
|
+
},
|
|
4564
|
+
connectedTo: [],
|
|
4565
|
+
// TODO we can associate source_ports with this via
|
|
4566
|
+
width: element.outer_diameter,
|
|
4567
|
+
height: element.outer_diameter
|
|
4568
|
+
});
|
|
4569
|
+
}
|
|
4570
|
+
}
|
|
4571
|
+
return obstacles;
|
|
4572
|
+
};
|
|
4573
|
+
|
|
4307
4574
|
// lib/components/primitive-components/Trace/Trace.ts
|
|
4308
4575
|
var portToObjective = (port) => {
|
|
4309
4576
|
const portPosition = port._getGlobalPcbPositionAfterLayout();
|
|
@@ -4613,7 +4880,7 @@ searched component ${targetComponent.getString()}, which has ports: ${targetComp
|
|
|
4613
4880
|
this.root.db.toArray()
|
|
4614
4881
|
);
|
|
4615
4882
|
const [obstacles, errGettingObstacles] = tryNow(
|
|
4616
|
-
() =>
|
|
4883
|
+
() => getObstaclesFromCircuitJson(this.root.db.toArray())
|
|
4617
4884
|
// Remove as any when autorouting-dataset gets updated
|
|
4618
4885
|
);
|
|
4619
4886
|
if (errGettingObstacles) {
|
|
@@ -6310,7 +6577,6 @@ var applyEditEvents = ({
|
|
|
6310
6577
|
};
|
|
6311
6578
|
|
|
6312
6579
|
// lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts
|
|
6313
|
-
import { getObstaclesFromSoup as getObstaclesFromSoup2 } from "@tscircuit/infgrid-ijump-astar";
|
|
6314
6580
|
import { su as su4 } from "@tscircuit/circuit-json-util";
|
|
6315
6581
|
import {
|
|
6316
6582
|
getFullConnectivityMapFromCircuitJson as getFullConnectivityMapFromCircuitJson2
|
|
@@ -6365,7 +6631,7 @@ var getSimpleRouteJsonFromCircuitJson = ({
|
|
|
6365
6631
|
const board = db.pcb_board.list()[0];
|
|
6366
6632
|
db = su4(subcircuitElements);
|
|
6367
6633
|
const connMap = getFullConnectivityMapFromCircuitJson2(subcircuitElements);
|
|
6368
|
-
const obstacles =
|
|
6634
|
+
const obstacles = getObstaclesFromCircuitJson(
|
|
6369
6635
|
[
|
|
6370
6636
|
...db.pcb_component.list(),
|
|
6371
6637
|
...db.pcb_smtpad.list(),
|
|
@@ -9898,7 +10164,7 @@ import { identity as identity4 } from "transformation-matrix";
|
|
|
9898
10164
|
var package_default = {
|
|
9899
10165
|
name: "@tscircuit/core",
|
|
9900
10166
|
type: "module",
|
|
9901
|
-
version: "0.0.
|
|
10167
|
+
version: "0.0.480",
|
|
9902
10168
|
types: "dist/index.d.ts",
|
|
9903
10169
|
main: "dist/index.js",
|
|
9904
10170
|
module: "dist/index.js",
|