@tscircuit/core 0.0.48 → 0.0.49

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
@@ -3771,7 +3771,7 @@ declare class PlatedHole extends PrimitiveComponent<typeof platedHoleProps> {
3771
3771
  }>]>, "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6", "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
3772
3772
  name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
3773
3773
  }>>;
3774
- }, "pcbRotation" | "layer">, {
3774
+ }, "layer" | "pcbRotation">, {
3775
3775
  name: zod.ZodOptional<zod.ZodString>;
3776
3776
  shape: zod.ZodLiteral<"circle">;
3777
3777
  holeDiameter: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
@@ -3806,7 +3806,7 @@ declare class PlatedHole extends PrimitiveComponent<typeof platedHoleProps> {
3806
3806
  }>]>, "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6", "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
3807
3807
  name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
3808
3808
  }>>;
3809
- }, "pcbRotation" | "layer">, {
3809
+ }, "layer" | "pcbRotation">, {
3810
3810
  name: zod.ZodOptional<zod.ZodString>;
3811
3811
  shape: zod.ZodLiteral<"oval">;
3812
3812
  outerWidth: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
package/dist/index.js CHANGED
@@ -2439,6 +2439,7 @@ searched component ${targetComponent.getString()}, which has ports: ${targetComp
2439
2439
  this.renderError(
2440
2440
  `Could not find a common layer (using hints) for trace ${this.getString()}`
2441
2441
  );
2442
+ return;
2442
2443
  }
2443
2444
  const obstacles = getObstaclesFromSoup(this.root.db.toArray());
2444
2445
  markObstaclesAsConnected(
@@ -2479,7 +2480,7 @@ searched component ${targetComponent.getString()}, which has ports: ${targetComp
2479
2480
  pointsToConnect: [a, b]
2480
2481
  }
2481
2482
  ],
2482
- layerCount: 1,
2483
+ layerCount: 2,
2483
2484
  bounds: {
2484
2485
  minX: Math.min(a.x, b.x) - BOUNDS_MARGIN,
2485
2486
  maxX: Math.max(a.x, b.x) + BOUNDS_MARGIN,
@@ -2490,16 +2491,53 @@ searched component ${targetComponent.getString()}, which has ports: ${targetComp
2490
2491
  });
2491
2492
  const traces = ijump.solveAndMapToTraces();
2492
2493
  if (traces.length === 0) {
2493
- console.log(
2494
- `Could not find a route between ${a} and ${b} for ${this} (TODO render error)`
2494
+ this.renderError(
2495
+ `Could not find a route between ${JSON.stringify(a)} and ${JSON.stringify(b)} for ${this}`
2495
2496
  );
2496
2497
  return;
2497
2498
  }
2498
2499
  const [trace] = traces;
2500
+ if ("via_to_layer" in a) {
2501
+ trace.route = trace.route.map((p) => {
2502
+ if (p.route_type === "wire") {
2503
+ p.layer = a.via_to_layer;
2504
+ }
2505
+ return p;
2506
+ });
2507
+ }
2499
2508
  routes.push(trace.route);
2500
2509
  }
2510
+ const mergedRoute = mergeRoutes(routes);
2511
+ const routeWithVias = mergedRoute.flatMap((point, index) => {
2512
+ const nextPoint = mergedRoute[index + 1];
2513
+ if (!nextPoint) return [point];
2514
+ if (point.route_type === "wire" && nextPoint.route_type === "wire" && point.layer !== nextPoint.layer) {
2515
+ return [
2516
+ {
2517
+ route_type: "via",
2518
+ from_layer: point.layer,
2519
+ to_layer: nextPoint.layer,
2520
+ x: nextPoint.x,
2521
+ y: nextPoint.y
2522
+ },
2523
+ point
2524
+ ];
2525
+ }
2526
+ return [point];
2527
+ });
2528
+ for (const via of routeWithVias.filter((p) => p.route_type === "via")) {
2529
+ db.pcb_via.insert({
2530
+ x: via.x,
2531
+ y: via.y,
2532
+ hole_diameter: 0.3,
2533
+ outer_diameter: 0.6,
2534
+ layers: [via.from_layer, via.to_layer],
2535
+ from_layer: via.from_layer,
2536
+ to_layer: via.to_layer
2537
+ });
2538
+ }
2501
2539
  const pcb_trace = db.pcb_trace.insert({
2502
- route: mergeRoutes(routes),
2540
+ route: routeWithVias,
2503
2541
  source_trace_id: this.source_trace_id
2504
2542
  });
2505
2543
  this._portsRoutedOnPcb = ports;
@@ -9,6 +9,7 @@ import {
9
9
  } from "@tscircuit/infgrid-ijump-astar"
10
10
  import type {
11
11
  AnySoupElement,
12
+ LayerRef,
12
13
  PCBTrace,
13
14
  RouteHintPoint,
14
15
  SchematicTrace,
@@ -366,6 +367,7 @@ export class Trace extends PrimitiveComponent<typeof traceProps> {
366
367
  this.renderError(
367
368
  `Could not find a common layer (using hints) for trace ${this.getString()}`,
368
369
  )
370
+ return
369
371
  }
370
372
 
371
373
  // Cache the PCB obstacles, they'll be needed for each segment between
@@ -420,7 +422,7 @@ export class Trace extends PrimitiveComponent<typeof traceProps> {
420
422
  pointsToConnect: [a, b],
421
423
  },
422
424
  ],
423
- layerCount: 1,
425
+ layerCount: 2,
424
426
  bounds: {
425
427
  minX: Math.min(a.x, b.x) - BOUNDS_MARGIN,
426
428
  maxX: Math.max(a.x, b.x) + BOUNDS_MARGIN,
@@ -431,18 +433,67 @@ export class Trace extends PrimitiveComponent<typeof traceProps> {
431
433
  })
432
434
  const traces = ijump.solveAndMapToTraces()
433
435
  if (traces.length === 0) {
434
- console.log(
435
- `Could not find a route between ${a} and ${b} for ${this} (TODO render error)`,
436
+ this.renderError(
437
+ `Could not find a route between ${JSON.stringify(a)} and ${JSON.stringify(b)} for ${this}`,
436
438
  )
437
439
  return
438
440
  }
439
441
  // TODO ijump returns multiple traces for some reason
440
442
  const [trace] = traces as PCBTrace[]
443
+ // TODO ijump always returns on top layer and has no multilayer support
444
+ // https://github.com/tscircuit/autorouting-dataset/issues/35
445
+ // For now, we'll move the trace to whatever layer the first point
446
+ // specifies we should have "via'd" to
447
+ if ("via_to_layer" in a) {
448
+ trace.route = trace.route.map((p) => {
449
+ if (p.route_type === "wire") {
450
+ p.layer = a.via_to_layer as LayerRef
451
+ }
452
+ return p
453
+ })
454
+ }
441
455
  routes.push(trace.route)
442
456
  }
443
457
 
458
+ const mergedRoute = mergeRoutes(routes)
459
+
460
+ // Add vias where layer changes occur
461
+ const routeWithVias = mergedRoute.flatMap((point, index) => {
462
+ const nextPoint = mergedRoute[index + 1]
463
+ if (!nextPoint) return [point]
464
+ if (
465
+ point.route_type === "wire" &&
466
+ nextPoint.route_type === "wire" &&
467
+ point.layer !== nextPoint.layer
468
+ ) {
469
+ return [
470
+ {
471
+ route_type: "via",
472
+ from_layer: point.layer,
473
+ to_layer: nextPoint.layer,
474
+ x: nextPoint.x,
475
+ y: nextPoint.y,
476
+ } as (typeof mergedRoute)[number],
477
+ point,
478
+ ]
479
+ }
480
+ return [point]
481
+ })
482
+
483
+ for (const via of routeWithVias.filter((p) => p.route_type === "via")) {
484
+ db.pcb_via.insert({
485
+ x: via.x,
486
+ y: via.y,
487
+ hole_diameter: 0.3,
488
+ outer_diameter: 0.6,
489
+ layers: [via.from_layer as LayerRef, via.to_layer as LayerRef],
490
+ from_layer: via.from_layer as LayerRef,
491
+ to_layer: via.to_layer as LayerRef,
492
+ })
493
+ }
494
+
444
495
  const pcb_trace = db.pcb_trace.insert({
445
- route: mergeRoutes(routes),
496
+ route: routeWithVias,
446
497
  source_trace_id: this.source_trace_id!,
447
498
  })
448
499
  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.48",
5
+ "version": "0.0.49",
6
6
  "types": "dist/index.d.ts",
7
7
  "main": "dist/index.js",
8
8
  "files": [