@tscircuit/core 0.0.58 → 0.0.60
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.d.ts
CHANGED
|
@@ -3773,7 +3773,7 @@ declare class PlatedHole extends PrimitiveComponent<typeof platedHoleProps> {
|
|
|
3773
3773
|
}>]>, "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6", "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
|
|
3774
3774
|
name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
|
|
3775
3775
|
}>>;
|
|
3776
|
-
}, "
|
|
3776
|
+
}, "pcbRotation" | "layer">, {
|
|
3777
3777
|
name: zod.ZodOptional<zod.ZodString>;
|
|
3778
3778
|
shape: zod.ZodLiteral<"circle">;
|
|
3779
3779
|
holeDiameter: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
|
|
@@ -3808,7 +3808,7 @@ declare class PlatedHole extends PrimitiveComponent<typeof platedHoleProps> {
|
|
|
3808
3808
|
}>]>, "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6", "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
|
|
3809
3809
|
name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
|
|
3810
3810
|
}>>;
|
|
3811
|
-
}, "
|
|
3811
|
+
}, "pcbRotation" | "layer">, {
|
|
3812
3812
|
name: zod.ZodOptional<zod.ZodString>;
|
|
3813
3813
|
shape: zod.ZodLiteral<"oval">;
|
|
3814
3814
|
outerWidth: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
|
package/dist/index.js
CHANGED
|
@@ -1693,6 +1693,13 @@ var NormalComponent = class extends PrimitiveComponent {
|
|
|
1693
1693
|
if (!footprint) return;
|
|
1694
1694
|
if (typeof footprint === "string") {
|
|
1695
1695
|
const fpSoup = fp.string(footprint).soup();
|
|
1696
|
+
if (this.props.layer) {
|
|
1697
|
+
for (const elm of fpSoup) {
|
|
1698
|
+
if ("layer" in elm) {
|
|
1699
|
+
elm.layer = this.props.layer;
|
|
1700
|
+
}
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1696
1703
|
const fpComponents = createComponentsFromSoup(fpSoup);
|
|
1697
1704
|
this.addAll(fpComponents);
|
|
1698
1705
|
}
|
|
@@ -2250,6 +2257,7 @@ var portToObjective = (port) => {
|
|
|
2250
2257
|
layers: port.getAvailablePcbLayers()
|
|
2251
2258
|
};
|
|
2252
2259
|
};
|
|
2260
|
+
var SHOULD_USE_SINGLE_LAYER_ROUTING = false;
|
|
2253
2261
|
var Trace = class extends PrimitiveComponent {
|
|
2254
2262
|
source_trace_id = null;
|
|
2255
2263
|
pcb_trace_id = null;
|
|
@@ -2464,7 +2472,7 @@ searched component ${targetComponent.getString()}, which has ports: ${targetComp
|
|
|
2464
2472
|
const candidateLayerCombinations = findPossibleTraceLayerCombinations(
|
|
2465
2473
|
orderedRouteObjectives
|
|
2466
2474
|
);
|
|
2467
|
-
if (candidateLayerCombinations.length === 0) {
|
|
2475
|
+
if (SHOULD_USE_SINGLE_LAYER_ROUTING && candidateLayerCombinations.length === 0) {
|
|
2468
2476
|
this.renderError(
|
|
2469
2477
|
`Could not find a common layer (using hints) for trace ${this.getString()}`
|
|
2470
2478
|
);
|
|
@@ -2498,32 +2506,38 @@ searched component ${targetComponent.getString()}, which has ports: ${targetComp
|
|
|
2498
2506
|
}
|
|
2499
2507
|
}
|
|
2500
2508
|
}
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2509
|
+
let orderedRoutePoints = [];
|
|
2510
|
+
if (candidateLayerCombinations.length === 0) {
|
|
2511
|
+
orderedRoutePoints = orderedRouteObjectives;
|
|
2512
|
+
} else {
|
|
2513
|
+
const candidateLayerSelections = candidateLayerCombinations[0].layer_path;
|
|
2514
|
+
orderedRoutePoints = orderedRouteObjectives.map((t, idx) => {
|
|
2515
|
+
if (t.via) {
|
|
2516
|
+
return {
|
|
2517
|
+
...t,
|
|
2518
|
+
via_to_layer: candidateLayerSelections[idx]
|
|
2519
|
+
};
|
|
2520
|
+
}
|
|
2521
|
+
return { ...t, layers: [candidateLayerSelections[idx]] };
|
|
2522
|
+
});
|
|
2523
|
+
}
|
|
2511
2524
|
const routes = [];
|
|
2512
2525
|
for (const [a, b] of pairs(orderedRoutePoints)) {
|
|
2513
2526
|
const dominantLayer = "via_to_layer" in a ? a.via_to_layer : null;
|
|
2514
2527
|
const BOUNDS_MARGIN = 2;
|
|
2528
|
+
const aLayer = "layers" in a && a.layers.length === 1 ? a.layers[0] : dominantLayer ?? "top";
|
|
2529
|
+
const bLayer = "layers" in b && b.layers.length === 1 ? b.layers[0] : dominantLayer ?? "top";
|
|
2515
2530
|
const ijump = new MultilayerIjump({
|
|
2516
2531
|
OBSTACLE_MARGIN: 0.3,
|
|
2517
2532
|
isRemovePathLoopsEnabled: true,
|
|
2518
|
-
layerCount: 2,
|
|
2519
2533
|
input: {
|
|
2520
2534
|
obstacles,
|
|
2521
2535
|
connections: [
|
|
2522
2536
|
{
|
|
2523
2537
|
name: connMap.getNetConnectedToId(this.source_trace_id),
|
|
2524
2538
|
pointsToConnect: [
|
|
2525
|
-
{ ...a, layer:
|
|
2526
|
-
{ ...b, layer:
|
|
2539
|
+
{ ...a, layer: aLayer },
|
|
2540
|
+
{ ...b, layer: bLayer }
|
|
2527
2541
|
]
|
|
2528
2542
|
}
|
|
2529
2543
|
],
|
|
@@ -2577,36 +2591,21 @@ searched component ${targetComponent.getString()}, which has ports: ${targetComp
|
|
|
2577
2591
|
routes.push(trace.route);
|
|
2578
2592
|
}
|
|
2579
2593
|
const mergedRoute = mergeRoutes(routes);
|
|
2580
|
-
const
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
},
|
|
2592
|
-
point
|
|
2593
|
-
];
|
|
2594
|
+
for (const point of mergedRoute) {
|
|
2595
|
+
if (point.route_type === "via") {
|
|
2596
|
+
db.pcb_via.insert({
|
|
2597
|
+
x: point.x,
|
|
2598
|
+
y: point.y,
|
|
2599
|
+
hole_diameter: 0.3,
|
|
2600
|
+
outer_diameter: 0.6,
|
|
2601
|
+
layers: [point.from_layer, point.to_layer],
|
|
2602
|
+
from_layer: point.from_layer,
|
|
2603
|
+
to_layer: point.to_layer
|
|
2604
|
+
});
|
|
2594
2605
|
}
|
|
2595
|
-
return [point];
|
|
2596
|
-
});
|
|
2597
|
-
for (const via of routeWithVias.filter((p) => p.route_type === "via")) {
|
|
2598
|
-
db.pcb_via.insert({
|
|
2599
|
-
x: via.x,
|
|
2600
|
-
y: via.y,
|
|
2601
|
-
hole_diameter: 0.3,
|
|
2602
|
-
outer_diameter: 0.6,
|
|
2603
|
-
layers: [via.from_layer, via.to_layer],
|
|
2604
|
-
from_layer: via.from_layer,
|
|
2605
|
-
to_layer: via.to_layer
|
|
2606
|
-
});
|
|
2607
2606
|
}
|
|
2608
2607
|
const pcb_trace = db.pcb_trace.insert({
|
|
2609
|
-
route:
|
|
2608
|
+
route: mergedRoute,
|
|
2610
2609
|
source_trace_id: this.source_trace_id
|
|
2611
2610
|
});
|
|
2612
2611
|
this._portsRoutedOnPcb = ports;
|
|
@@ -119,6 +119,14 @@ export class NormalComponent<
|
|
|
119
119
|
if (!footprint) return
|
|
120
120
|
if (typeof footprint === "string") {
|
|
121
121
|
const fpSoup = fp.string(footprint).soup()
|
|
122
|
+
// Adjust the layer of the footprint to match the layer of the component
|
|
123
|
+
if (this.props.layer) {
|
|
124
|
+
for (const elm of fpSoup) {
|
|
125
|
+
if ("layer" in elm) {
|
|
126
|
+
elm.layer = this.props.layer
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
122
130
|
const fpComponents = createComponentsFromSoup(fpSoup)
|
|
123
131
|
this.addAll(fpComponents)
|
|
124
132
|
}
|
|
@@ -54,6 +54,8 @@ const portToObjective = (port: Port): PcbRouteObjective => {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
const SHOULD_USE_SINGLE_LAYER_ROUTING = false
|
|
58
|
+
|
|
57
59
|
export class Trace extends PrimitiveComponent<typeof traceProps> {
|
|
58
60
|
source_trace_id: string | null = null
|
|
59
61
|
pcb_trace_id: string | null = null
|
|
@@ -355,7 +357,10 @@ export class Trace extends PrimitiveComponent<typeof traceProps> {
|
|
|
355
357
|
orderedRouteObjectives,
|
|
356
358
|
)
|
|
357
359
|
|
|
358
|
-
if (
|
|
360
|
+
if (
|
|
361
|
+
SHOULD_USE_SINGLE_LAYER_ROUTING &&
|
|
362
|
+
candidateLayerCombinations.length === 0
|
|
363
|
+
) {
|
|
359
364
|
this.renderError(
|
|
360
365
|
`Could not find a common layer (using hints) for trace ${this.getString()}`,
|
|
361
366
|
)
|
|
@@ -396,22 +401,27 @@ export class Trace extends PrimitiveComponent<typeof traceProps> {
|
|
|
396
401
|
}
|
|
397
402
|
}
|
|
398
403
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
404
|
+
let orderedRoutePoints: PcbRouteObjective[] = []
|
|
405
|
+
if (candidateLayerCombinations.length === 0) {
|
|
406
|
+
orderedRoutePoints = orderedRouteObjectives
|
|
407
|
+
} else {
|
|
408
|
+
// TODO explore all candidate layer combinations if one fails
|
|
409
|
+
const candidateLayerSelections = candidateLayerCombinations[0].layer_path
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Apply the candidate layer selections to the route objectives, now we
|
|
413
|
+
* have a set of points that have definite layers
|
|
414
|
+
*/
|
|
415
|
+
orderedRoutePoints = orderedRouteObjectives.map((t, idx) => {
|
|
416
|
+
if (t.via) {
|
|
417
|
+
return {
|
|
418
|
+
...t,
|
|
419
|
+
via_to_layer: candidateLayerSelections[idx],
|
|
420
|
+
}
|
|
411
421
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
}
|
|
422
|
+
return { ...t, layers: [candidateLayerSelections[idx]] }
|
|
423
|
+
})
|
|
424
|
+
}
|
|
415
425
|
|
|
416
426
|
const routes: PCBTrace["route"][] = []
|
|
417
427
|
for (const [a, b] of pairs(orderedRoutePoints)) {
|
|
@@ -419,18 +429,26 @@ export class Trace extends PrimitiveComponent<typeof traceProps> {
|
|
|
419
429
|
"via_to_layer" in a ? (a.via_to_layer as LayerRef) : null
|
|
420
430
|
const BOUNDS_MARGIN = 2 //mm
|
|
421
431
|
|
|
432
|
+
const aLayer =
|
|
433
|
+
"layers" in a && a.layers.length === 1
|
|
434
|
+
? a.layers[0]
|
|
435
|
+
: dominantLayer ?? "top"
|
|
436
|
+
const bLayer =
|
|
437
|
+
"layers" in b && b.layers.length === 1
|
|
438
|
+
? b.layers[0]
|
|
439
|
+
: dominantLayer ?? "top"
|
|
440
|
+
|
|
422
441
|
const ijump = new MultilayerIjump({
|
|
423
442
|
OBSTACLE_MARGIN: 0.3,
|
|
424
443
|
isRemovePathLoopsEnabled: true,
|
|
425
|
-
layerCount: 2,
|
|
426
444
|
input: {
|
|
427
445
|
obstacles,
|
|
428
446
|
connections: [
|
|
429
447
|
{
|
|
430
448
|
name: connMap.getNetConnectedToId(this.source_trace_id!)!,
|
|
431
449
|
pointsToConnect: [
|
|
432
|
-
{ ...a, layer:
|
|
433
|
-
{ ...b, layer:
|
|
450
|
+
{ ...a, layer: aLayer },
|
|
451
|
+
{ ...b, layer: bLayer },
|
|
434
452
|
],
|
|
435
453
|
},
|
|
436
454
|
],
|
|
@@ -491,43 +509,22 @@ export class Trace extends PrimitiveComponent<typeof traceProps> {
|
|
|
491
509
|
|
|
492
510
|
const mergedRoute = mergeRoutes(routes)
|
|
493
511
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
route_type: "via",
|
|
506
|
-
from_layer: point.layer,
|
|
507
|
-
to_layer: nextPoint.layer,
|
|
508
|
-
x: nextPoint.x,
|
|
509
|
-
y: nextPoint.y,
|
|
510
|
-
} as (typeof mergedRoute)[number],
|
|
511
|
-
point,
|
|
512
|
-
]
|
|
512
|
+
for (const point of mergedRoute) {
|
|
513
|
+
if (point.route_type === "via") {
|
|
514
|
+
db.pcb_via.insert({
|
|
515
|
+
x: point.x,
|
|
516
|
+
y: point.y,
|
|
517
|
+
hole_diameter: 0.3,
|
|
518
|
+
outer_diameter: 0.6,
|
|
519
|
+
layers: [point.from_layer as LayerRef, point.to_layer as LayerRef],
|
|
520
|
+
from_layer: point.from_layer as LayerRef,
|
|
521
|
+
to_layer: point.to_layer as LayerRef,
|
|
522
|
+
})
|
|
513
523
|
}
|
|
514
|
-
return [point]
|
|
515
|
-
})
|
|
516
|
-
|
|
517
|
-
for (const via of routeWithVias.filter((p) => p.route_type === "via")) {
|
|
518
|
-
db.pcb_via.insert({
|
|
519
|
-
x: via.x,
|
|
520
|
-
y: via.y,
|
|
521
|
-
hole_diameter: 0.3,
|
|
522
|
-
outer_diameter: 0.6,
|
|
523
|
-
layers: [via.from_layer as LayerRef, via.to_layer as LayerRef],
|
|
524
|
-
from_layer: via.from_layer as LayerRef,
|
|
525
|
-
to_layer: via.to_layer as LayerRef,
|
|
526
|
-
})
|
|
527
524
|
}
|
|
528
525
|
|
|
529
526
|
const pcb_trace = db.pcb_trace.insert({
|
|
530
|
-
route:
|
|
527
|
+
route: mergedRoute,
|
|
531
528
|
source_trace_id: this.source_trace_id!,
|
|
532
529
|
})
|
|
533
530
|
this._portsRoutedOnPcb = ports
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@tscircuit/core",
|
|
3
3
|
"module": "index.ts",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.60",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"main": "dist/index.js",
|
|
8
8
|
"files": [
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@lume/kiwi": "^0.4.3",
|
|
37
|
-
"@tscircuit/infgrid-ijump-astar": "^0.0.
|
|
37
|
+
"@tscircuit/infgrid-ijump-astar": "^0.0.16",
|
|
38
38
|
"@tscircuit/props": "^0.0.62",
|
|
39
39
|
"@tscircuit/soup": "^0.0.67",
|
|
40
40
|
"@tscircuit/soup-util": "^0.0.23",
|