@tscircuit/core 0.0.944 → 0.0.946

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
@@ -151,6 +151,7 @@ type SimplifiedPcbTrace = {
151
151
  }>;
152
152
  };
153
153
  type Obstacle = {
154
+ obstacleId?: string;
154
155
  type: "rect";
155
156
  layers: string[];
156
157
  center: {
@@ -26148,6 +26149,11 @@ declare class SilkscreenRect extends PrimitiveComponent<typeof silkscreenRectPro
26148
26149
  stroke?: "none" | "dashed" | "solid" | undefined;
26149
26150
  }>;
26150
26151
  };
26152
+ /**
26153
+ * Check if the component is rotated 90 or 270 degrees based on global transform.
26154
+ * For these rotations, we need to swap width/height instead of using ccw_rotation.
26155
+ */
26156
+ private _isRotated90Degrees;
26151
26157
  doInitialPcbPrimitiveRender(): void;
26152
26158
  getPcbSize(): {
26153
26159
  width: number;
@@ -45798,6 +45804,12 @@ interface GenericLocalAutorouter {
45798
45804
  on(event: "error", callback: (ev: AutorouterErrorEvent) => void): void;
45799
45805
  on(event: "progress", callback: (ev: AutorouterProgressEvent) => void): void;
45800
45806
  solveSync(): SimplifiedPcbTrace[];
45807
+ /**
45808
+ * Get the mapping of obstacle IDs to root connection names that were
45809
+ * connected via off-board paths (e.g., interconnects).
45810
+ * Returns empty object if not supported by the autorouter.
45811
+ */
45812
+ getConnectedOffboardObstacles?(): Record<string, string>;
45801
45813
  }
45802
45814
 
45803
45815
  declare const applyPcbEditEventsToManualEditsFile: ({ circuitJson, editEvents, manualEditsFile, }: {
package/dist/index.js CHANGED
@@ -9801,6 +9801,17 @@ var TscircuitAutorouter = class {
9801
9801
  }
9802
9802
  return this.solver.getOutputSimpleRouteJson().traces || [];
9803
9803
  }
9804
+ /**
9805
+ * Get the mapping of obstacle IDs to root connection names that were
9806
+ * connected via off-board paths (e.g., interconnects).
9807
+ * Only available when using AssignableAutoroutingPipeline2.
9808
+ */
9809
+ getConnectedOffboardObstacles() {
9810
+ if ("getConnectedOffboardObstacles" in this.solver) {
9811
+ return this.solver.getConnectedOffboardObstacles();
9812
+ }
9813
+ return {};
9814
+ }
9804
9815
  };
9805
9816
 
9806
9817
  // lib/components/primitive-components/Group/Group.ts
@@ -12673,6 +12684,81 @@ var Group_doInitialPcbLayoutFlex = (group) => {
12673
12684
  // lib/components/primitive-components/Group/Group.ts
12674
12685
  import { convertSrjToGraphicsObject } from "@tscircuit/capacity-autorouter";
12675
12686
 
12687
+ // lib/utils/autorouting/createSourceTracesFromOffboardConnections.ts
12688
+ var createSourceTracesFromOffboardConnections = ({
12689
+ db,
12690
+ connectedOffboardObstacles,
12691
+ simpleRouteJson,
12692
+ subcircuit_id
12693
+ }) => {
12694
+ if (Object.keys(connectedOffboardObstacles).length === 0) return;
12695
+ const pcbElementIdToSourcePortId = /* @__PURE__ */ new Map();
12696
+ for (const pcbPort of db.pcb_port.list()) {
12697
+ if (pcbPort.source_port_id) {
12698
+ const smtpad = db.pcb_smtpad.getWhere({
12699
+ pcb_port_id: pcbPort.pcb_port_id
12700
+ });
12701
+ if (smtpad) {
12702
+ pcbElementIdToSourcePortId.set(
12703
+ smtpad.pcb_smtpad_id,
12704
+ pcbPort.source_port_id
12705
+ );
12706
+ }
12707
+ const platedHole = db.pcb_plated_hole.getWhere({
12708
+ pcb_port_id: pcbPort.pcb_port_id
12709
+ });
12710
+ if (platedHole) {
12711
+ pcbElementIdToSourcePortId.set(
12712
+ platedHole.pcb_plated_hole_id,
12713
+ pcbPort.source_port_id
12714
+ );
12715
+ }
12716
+ }
12717
+ }
12718
+ const obstacleById = /* @__PURE__ */ new Map();
12719
+ for (const obstacle of simpleRouteJson.obstacles) {
12720
+ if (obstacle.obstacleId) {
12721
+ obstacleById.set(obstacle.obstacleId, obstacle);
12722
+ }
12723
+ }
12724
+ const connectionGroups = /* @__PURE__ */ new Map();
12725
+ for (const [obstacleId, rootConnectionName] of Object.entries(
12726
+ connectedOffboardObstacles
12727
+ )) {
12728
+ if (!connectionGroups.has(rootConnectionName)) {
12729
+ connectionGroups.set(rootConnectionName, []);
12730
+ }
12731
+ connectionGroups.get(rootConnectionName).push(obstacleId);
12732
+ }
12733
+ for (const [rootConnectionName, obstacleIds] of connectionGroups) {
12734
+ const sourcePortIds = /* @__PURE__ */ new Set();
12735
+ for (const obstacleId of obstacleIds) {
12736
+ const obstacle = obstacleById.get(obstacleId);
12737
+ if (!obstacle) continue;
12738
+ for (const connectedId of obstacle.connectedTo) {
12739
+ const sourcePortId = pcbElementIdToSourcePortId.get(connectedId);
12740
+ if (sourcePortId) {
12741
+ sourcePortIds.add(sourcePortId);
12742
+ }
12743
+ }
12744
+ }
12745
+ if (sourcePortIds.size < 2) continue;
12746
+ const sourcePortIdArray = Array.from(sourcePortIds);
12747
+ const existingTraces = db.source_trace.list();
12748
+ const alreadyConnected = existingTraces.some((trace) => {
12749
+ const tracePortIds = new Set(trace.connected_source_port_ids);
12750
+ return sourcePortIdArray.every((id) => tracePortIds.has(id));
12751
+ });
12752
+ if (alreadyConnected) continue;
12753
+ db.source_trace.insert({
12754
+ connected_source_port_ids: sourcePortIdArray,
12755
+ connected_source_net_ids: [],
12756
+ subcircuit_id: subcircuit_id ?? void 0,
12757
+ display_name: `offboard_${rootConnectionName}`
12758
+ });
12759
+ }
12760
+ };
12761
+
12676
12762
  // lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/Group_doInitialSchematicTraceRender.ts
12677
12763
  import { SchematicTracePipelineSolver as SchematicTracePipelineSolver4 } from "@tscircuit/schematic-trace-solver";
12678
12764
  import Debug11 from "debug";
@@ -14200,6 +14286,15 @@ var Group6 = class extends NormalComponent3 {
14200
14286
  autorouter.start();
14201
14287
  try {
14202
14288
  const traces = await routingPromise;
14289
+ if (autorouter.getConnectedOffboardObstacles) {
14290
+ const connectedOffboardObstacles = autorouter.getConnectedOffboardObstacles();
14291
+ createSourceTracesFromOffboardConnections({
14292
+ db,
14293
+ connectedOffboardObstacles,
14294
+ simpleRouteJson,
14295
+ subcircuit_id: this.subcircuit_id
14296
+ });
14297
+ }
14203
14298
  this._asyncAutoroutingResult = {
14204
14299
  output_pcb_traces: traces
14205
14300
  };
@@ -18205,6 +18300,7 @@ var SilkscreenCircle = class extends PrimitiveComponent2 {
18205
18300
 
18206
18301
  // lib/components/primitive-components/SilkscreenRect.ts
18207
18302
  import { silkscreenRectProps } from "@tscircuit/props";
18303
+ import { decomposeTSR as decomposeTSR6 } from "transformation-matrix";
18208
18304
  var SilkscreenRect = class extends PrimitiveComponent2 {
18209
18305
  pcb_silkscreen_rect_id = null;
18210
18306
  isPcbPrimitive = true;
@@ -18214,6 +18310,18 @@ var SilkscreenRect = class extends PrimitiveComponent2 {
18214
18310
  zodProps: silkscreenRectProps
18215
18311
  };
18216
18312
  }
18313
+ /**
18314
+ * Check if the component is rotated 90 or 270 degrees based on global transform.
18315
+ * For these rotations, we need to swap width/height instead of using ccw_rotation.
18316
+ */
18317
+ _isRotated90Degrees() {
18318
+ const globalTransform = this._computePcbGlobalTransformBeforeLayout();
18319
+ const decomposedTransform = decomposeTSR6(globalTransform);
18320
+ const rotationDegrees = decomposedTransform.rotation.angle * 180 / Math.PI;
18321
+ const normalizedRotationDegrees = (rotationDegrees % 360 + 360) % 360;
18322
+ const rotationTolerance = 0.01;
18323
+ return Math.abs(normalizedRotationDegrees - 90) < rotationTolerance || Math.abs(normalizedRotationDegrees - 270) < rotationTolerance;
18324
+ }
18217
18325
  doInitialPcbPrimitiveRender() {
18218
18326
  if (this.root?.pcbDisabled) return;
18219
18327
  const { db } = this.root;
@@ -18227,6 +18335,9 @@ var SilkscreenRect = class extends PrimitiveComponent2 {
18227
18335
  }
18228
18336
  const subcircuit = this.getSubcircuit();
18229
18337
  const position = this._getGlobalPcbPositionBeforeLayout();
18338
+ const isRotated90Degrees = this._isRotated90Degrees();
18339
+ const finalWidth = isRotated90Degrees ? props.height : props.width;
18340
+ const finalHeight = isRotated90Degrees ? props.width : props.height;
18230
18341
  const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id;
18231
18342
  const pcb_silkscreen_rect = db.pcb_silkscreen_rect.insert({
18232
18343
  pcb_component_id,
@@ -18235,8 +18346,8 @@ var SilkscreenRect = class extends PrimitiveComponent2 {
18235
18346
  x: position.x,
18236
18347
  y: position.y
18237
18348
  },
18238
- width: props.width,
18239
- height: props.height,
18349
+ width: finalWidth,
18350
+ height: finalHeight,
18240
18351
  subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
18241
18352
  pcb_group_id: this?.getGroup()?.pcb_group_id ?? void 0,
18242
18353
  stroke_width: props.strokeWidth ?? 0.1,
@@ -18247,6 +18358,10 @@ var SilkscreenRect = class extends PrimitiveComponent2 {
18247
18358
  }
18248
18359
  getPcbSize() {
18249
18360
  const { _parsedProps: props } = this;
18361
+ const isRotated90Degrees = this._isRotated90Degrees();
18362
+ if (isRotated90Degrees) {
18363
+ return { width: props.height, height: props.width };
18364
+ }
18250
18365
  return { width: props.width, height: props.height };
18251
18366
  }
18252
18367
  _moveCircuitJsonElements({
@@ -20008,7 +20123,7 @@ import { identity as identity5 } from "transformation-matrix";
20008
20123
  var package_default = {
20009
20124
  name: "@tscircuit/core",
20010
20125
  type: "module",
20011
- version: "0.0.943",
20126
+ version: "0.0.945",
20012
20127
  types: "dist/index.d.ts",
20013
20128
  main: "dist/index.js",
20014
20129
  module: "dist/index.js",
@@ -20039,7 +20154,7 @@ var package_default = {
20039
20154
  devDependencies: {
20040
20155
  "@biomejs/biome": "^1.8.3",
20041
20156
  "@resvg/resvg-js": "^2.6.2",
20042
- "@tscircuit/capacity-autorouter": "^0.0.194",
20157
+ "@tscircuit/capacity-autorouter": "^0.0.204",
20043
20158
  "@tscircuit/checks": "^0.0.87",
20044
20159
  "@tscircuit/circuit-json-util": "^0.0.73",
20045
20160
  "@tscircuit/common": "^0.0.20",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.944",
4
+ "version": "0.0.946",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -32,7 +32,7 @@
32
32
  "devDependencies": {
33
33
  "@biomejs/biome": "^1.8.3",
34
34
  "@resvg/resvg-js": "^2.6.2",
35
- "@tscircuit/capacity-autorouter": "^0.0.194",
35
+ "@tscircuit/capacity-autorouter": "^0.0.204",
36
36
  "@tscircuit/checks": "^0.0.87",
37
37
  "@tscircuit/circuit-json-util": "^0.0.73",
38
38
  "@tscircuit/common": "^0.0.20",