@tscircuit/core 0.0.480 → 0.0.482
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 +287 -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,289 @@ 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 === "circular_hole_with_rect_pad") {
|
|
4533
|
+
obstacles.push({
|
|
4534
|
+
// @ts-ignore
|
|
4535
|
+
type: "rect",
|
|
4536
|
+
layers: EVERY_LAYER,
|
|
4537
|
+
center: {
|
|
4538
|
+
x: element.x,
|
|
4539
|
+
y: element.y
|
|
4540
|
+
},
|
|
4541
|
+
width: element.rect_pad_width,
|
|
4542
|
+
height: element.rect_pad_height,
|
|
4543
|
+
connectedTo: withNetId([element.pcb_plated_hole_id])
|
|
4544
|
+
});
|
|
4545
|
+
} else if (element.shape === "oval" || element.shape === "pill") {
|
|
4546
|
+
obstacles.push({
|
|
4547
|
+
// @ts-ignore
|
|
4548
|
+
type: "oval",
|
|
4549
|
+
layers: EVERY_LAYER,
|
|
4550
|
+
center: {
|
|
4551
|
+
x: element.x,
|
|
4552
|
+
y: element.y
|
|
4553
|
+
},
|
|
4554
|
+
width: element.outer_width,
|
|
4555
|
+
height: element.outer_height,
|
|
4556
|
+
connectedTo: withNetId([element.pcb_plated_hole_id])
|
|
4557
|
+
});
|
|
4558
|
+
}
|
|
4559
|
+
} else if (element.type === "pcb_trace") {
|
|
4560
|
+
const traceObstacles = getObstaclesFromRoute(
|
|
4561
|
+
element.route.map((rp) => ({
|
|
4562
|
+
x: rp.x,
|
|
4563
|
+
y: rp.y,
|
|
4564
|
+
layer: "layer" in rp ? rp.layer : rp.from_layer
|
|
4565
|
+
})),
|
|
4566
|
+
element.source_trace_id
|
|
4567
|
+
);
|
|
4568
|
+
obstacles.push(...traceObstacles);
|
|
4569
|
+
} else if (element.type === "pcb_via") {
|
|
4570
|
+
obstacles.push({
|
|
4571
|
+
type: "rect",
|
|
4572
|
+
layers: element.layers,
|
|
4573
|
+
center: {
|
|
4574
|
+
x: element.x,
|
|
4575
|
+
y: element.y
|
|
4576
|
+
},
|
|
4577
|
+
connectedTo: [],
|
|
4578
|
+
// TODO we can associate source_ports with this via
|
|
4579
|
+
width: element.outer_diameter,
|
|
4580
|
+
height: element.outer_diameter
|
|
4581
|
+
});
|
|
4582
|
+
}
|
|
4583
|
+
}
|
|
4584
|
+
return obstacles;
|
|
4585
|
+
};
|
|
4586
|
+
|
|
4307
4587
|
// lib/components/primitive-components/Trace/Trace.ts
|
|
4308
4588
|
var portToObjective = (port) => {
|
|
4309
4589
|
const portPosition = port._getGlobalPcbPositionAfterLayout();
|
|
@@ -4613,7 +4893,7 @@ searched component ${targetComponent.getString()}, which has ports: ${targetComp
|
|
|
4613
4893
|
this.root.db.toArray()
|
|
4614
4894
|
);
|
|
4615
4895
|
const [obstacles, errGettingObstacles] = tryNow(
|
|
4616
|
-
() =>
|
|
4896
|
+
() => getObstaclesFromCircuitJson(this.root.db.toArray())
|
|
4617
4897
|
// Remove as any when autorouting-dataset gets updated
|
|
4618
4898
|
);
|
|
4619
4899
|
if (errGettingObstacles) {
|
|
@@ -6310,7 +6590,6 @@ var applyEditEvents = ({
|
|
|
6310
6590
|
};
|
|
6311
6591
|
|
|
6312
6592
|
// lib/utils/autorouting/getSimpleRouteJsonFromCircuitJson.ts
|
|
6313
|
-
import { getObstaclesFromSoup as getObstaclesFromSoup2 } from "@tscircuit/infgrid-ijump-astar";
|
|
6314
6593
|
import { su as su4 } from "@tscircuit/circuit-json-util";
|
|
6315
6594
|
import {
|
|
6316
6595
|
getFullConnectivityMapFromCircuitJson as getFullConnectivityMapFromCircuitJson2
|
|
@@ -6365,7 +6644,7 @@ var getSimpleRouteJsonFromCircuitJson = ({
|
|
|
6365
6644
|
const board = db.pcb_board.list()[0];
|
|
6366
6645
|
db = su4(subcircuitElements);
|
|
6367
6646
|
const connMap = getFullConnectivityMapFromCircuitJson2(subcircuitElements);
|
|
6368
|
-
const obstacles =
|
|
6647
|
+
const obstacles = getObstaclesFromCircuitJson(
|
|
6369
6648
|
[
|
|
6370
6649
|
...db.pcb_component.list(),
|
|
6371
6650
|
...db.pcb_smtpad.list(),
|
|
@@ -9898,7 +10177,7 @@ import { identity as identity4 } from "transformation-matrix";
|
|
|
9898
10177
|
var package_default = {
|
|
9899
10178
|
name: "@tscircuit/core",
|
|
9900
10179
|
type: "module",
|
|
9901
|
-
version: "0.0.
|
|
10180
|
+
version: "0.0.481",
|
|
9902
10181
|
types: "dist/index.d.ts",
|
|
9903
10182
|
main: "dist/index.js",
|
|
9904
10183
|
module: "dist/index.js",
|