From b59d8ef197c3e8babff0859ffe73f58965868834 Mon Sep 17 00:00:00 2001 From: seveibar Date: Mon, 28 Sep 2026 23:23:40 -0700 Subject: [PATCH 1/2] Document automatic teardrops and saved trace width interpolation --- .../saved-tapered-paths.circuit.tsx | 30 ++++++++++ .../trace-teardrops.circuit.tsx | 14 +++++ docs/elements/trace.mdx | 48 ++++++++++++++++ .../reusing-saved-fanout-trace-paths.mdx | 57 ++++++++++++++++++- 4 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 codetestingplayground/saved-tapered-paths.circuit.tsx create mode 100644 codetestingplayground/trace-teardrops.circuit.tsx diff --git a/codetestingplayground/saved-tapered-paths.circuit.tsx b/codetestingplayground/saved-tapered-paths.circuit.tsx new file mode 100644 index 00000000..3947eb24 --- /dev/null +++ b/codetestingplayground/saved-tapered-paths.circuit.tsx @@ -0,0 +1,30 @@ +import type { FanoutTracePath } from "@tscircuit/props" + +const savedPaths: FanoutTracePath[] = [ + { + connection: "R1.1", + route: [ + { + route_type: "wire", + x: -0.51, + y: 0, + width: 0.5, + layer: "top", + width_interpolation_mode: "quadratic", + }, + { route_type: "wire", x: -1.5, y: 0, width: 0.15, layer: "top" }, + { route_type: "wire", x: -2.5, y: 1, width: 0.15, layer: "top" }, + { route_type: "wire", x: -3.5, y: 1, width: 0.15, layer: "top" }, + ], + }, +] + +export default () => ( + + + + + + + +) diff --git a/codetestingplayground/trace-teardrops.circuit.tsx b/codetestingplayground/trace-teardrops.circuit.tsx new file mode 100644 index 00000000..bd0e2462 --- /dev/null +++ b/codetestingplayground/trace-teardrops.circuit.tsx @@ -0,0 +1,14 @@ +export default () => ( + + + + + +) diff --git a/docs/elements/trace.mdx b/docs/elements/trace.mdx index b48c01c6..1e03be18 100644 --- a/docs/elements/trace.mdx +++ b/docs/elements/trace.mdx @@ -41,8 +41,56 @@ Here's a simple example connecting two components: | `width` | Width of the trace (optional) | `"0.2mm"` | | `thickness` | Same as `width`; sets the copper width for the trace (optional) | `"0.2mm"` | | `pcbPath` | Array of points defining a manual PCB path relative to an anchor port | `[{ x: 1, y: 0 }, { x: 1, y: 1 }]` | +| `pcbTeardrops` | Enable automatic PCB teardrops | `true` | +| `pcbTeardropStart` | Teardrop at the start (from) of trace | `true` | +| `pcbTeardropEnd` | Teardrop at the end (to) of trace | `false` | | `pcbPathRelativeTo` | Port selector that `pcbPath` coordinates are relative to (defaults to the `from` port) | `".R1 > .pin2"` | +## PCB teardrops + +Teardrops widen a trace as it meets a pad or via. Set `pcbTeardrops` to add +teardrops automatically after routing. The routed centerline stays in place, +and copper pours are generated afterward. + +| Property | Description | +| --- | --- | +| `pcbTeardrops` | Enable automatic teardrops at supported pad and via contacts. Defaults to disabled. | +| `pcbTeardropStart` | Teardrop at the start (from) of trace. | +| `pcbTeardropEnd` | Teardrop at the end (to) of trace. | + +Start and end refer to the logical `from` and `to` connections, even if the +stored route runs in reverse. When omitted, either endpoint setting inherits +`pcbTeardrops`. An explicit `true` or `false` overrides that setting for the +endpoint. For example, this enables teardrops but disables them at C1: + +```tsx +export default () => ( + + + + + +) +``` + +To enable only the `from` endpoint, set `pcbTeardropStart` without +`pcbTeardrops`. To enable via teardrops while disabling both endpoints, use +`pcbTeardrops` with `pcbTeardropStart={false}` and `pcbTeardropEnd={false}`. + +Automatic teardrops depend on the contact geometry and available straight +trace length. Unsupported pad shapes and segments too short for a taper are +skipped. These controls do not choose a curve or set custom dimensions. +For explicit widths and interpolation, use +[saved `pcbTracePaths`](../guides/reusing-saved-fanout-trace-paths.mdx#tapered-wire-segments). +Explicit tapers in saved paths are preserved by automatic teardrop generation. + ## Connecting to Nets Traces can connect to named nets like power and ground: diff --git a/docs/guides/reusing-saved-fanout-trace-paths.mdx b/docs/guides/reusing-saved-fanout-trace-paths.mdx index 0e747363..77355d8f 100644 --- a/docs/guides/reusing-saved-fanout-trace-paths.mdx +++ b/docs/guides/reusing-saved-fanout-trace-paths.mdx @@ -96,7 +96,7 @@ Each route contains at least two points: | Point | Required fields | Optional fields | | --- | --- | --- | -| Wire | `route_type: "wire"`, `x`, `y`, `width`, `layer` | — | +| Wire | `route_type: "wire"`, `x`, `y`, `width`, `layer` | `width_interpolation_mode` | | Via | `route_type: "via"`, `x`, `y`, `from_layer`, `to_layer` | `via_diameter`, `via_hole_diameter` | Only wire and via points are supported. Wire widths and specified via diameters @@ -110,6 +110,61 @@ including `false`. A trailing via creates its exit on `to_layer`. Core emits coincident wire contacts around endpoint vias for Circuit JSON connectivity; those contacts do not move the via or alter the saved copper. +## Tapered wire segments + +Set `width_interpolation_mode` on a wire point to interpolate from its `width` +to the next wire point's `width`. Use `"linear"` for a straight-sided taper or +`"quadratic"` for a curved teardrop profile. The mode applies to the outgoing +segment only. Without it, that segment keeps its starting width even if the +next point has a different width. + +This example narrows from the left pad of a 0402 resistor to a 0.15 mm trace, +then continues to a fanout exit. The pad center is `(-0.51, 0)` in the fanout's +local frame. + +```tsx +import type { FanoutTracePath } from "@tscircuit/props" + +const savedPaths: FanoutTracePath[] = [ + { + connection: "R1.1", + route: [ + { + route_type: "wire", + x: -0.51, + y: 0, + width: 0.5, + layer: "top", + width_interpolation_mode: "quadratic", + }, + { route_type: "wire", x: -1.5, y: 0, width: 0.15, layer: "top" }, + { route_type: "wire", x: -2.5, y: 1, width: 0.15, layer: "top" }, + { route_type: "wire", x: -3.5, y: 1, width: 0.15, layer: "top" }, + ], + }, +] + +export default () => ( + + + + + + + +) +``` + +Interpolation requires a next wire point on the same layer at a different +position. Do not set it on the last point, or directly before a via. To taper +into a via, insert a wire point at the via's coordinates first; that point's +width is the taper's ending width. + +The same point format works in `pcbTracePaths` on +[``](../elements/autoroutingphase.mdx). For automatically +sized pad and via teardrops, use the +[`` teardrop controls](../elements/trace.mdx#pcb-teardrops). + ## Coverage and validation `pcbTracePaths` replaces automatic routing for that fanout. Supply a path for From 156c5a0d7c953bda0d9720cb65274d3e343b9753 Mon Sep 17 00:00:00 2001 From: seveibar Date: Tue, 29 Sep 2026 12:06:08 -0700 Subject: [PATCH 2/2] Keep teardrop docs concise and restore saved fanout guide --- .../saved-tapered-paths.circuit.tsx | 30 ---------- docs/elements/trace.mdx | 32 ++--------- .../reusing-saved-fanout-trace-paths.mdx | 57 +------------------ 3 files changed, 7 insertions(+), 112 deletions(-) delete mode 100644 codetestingplayground/saved-tapered-paths.circuit.tsx diff --git a/codetestingplayground/saved-tapered-paths.circuit.tsx b/codetestingplayground/saved-tapered-paths.circuit.tsx deleted file mode 100644 index 3947eb24..00000000 --- a/codetestingplayground/saved-tapered-paths.circuit.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import type { FanoutTracePath } from "@tscircuit/props" - -const savedPaths: FanoutTracePath[] = [ - { - connection: "R1.1", - route: [ - { - route_type: "wire", - x: -0.51, - y: 0, - width: 0.5, - layer: "top", - width_interpolation_mode: "quadratic", - }, - { route_type: "wire", x: -1.5, y: 0, width: 0.15, layer: "top" }, - { route_type: "wire", x: -2.5, y: 1, width: 0.15, layer: "top" }, - { route_type: "wire", x: -3.5, y: 1, width: 0.15, layer: "top" }, - ], - }, -] - -export default () => ( - - - - - - - -) diff --git a/docs/elements/trace.mdx b/docs/elements/trace.mdx index 1e03be18..0c2083ac 100644 --- a/docs/elements/trace.mdx +++ b/docs/elements/trace.mdx @@ -48,22 +48,13 @@ Here's a simple example connecting two components: ## PCB teardrops -Teardrops widen a trace as it meets a pad or via. Set `pcbTeardrops` to add -teardrops automatically after routing. The routed centerline stays in place, -and copper pours are generated afterward. +Set `pcbTeardrops` to widen traces at pad and via contacts after routing. +Use `pcbTeardropStart` and `pcbTeardropEnd` to override the `from` and `to` +endpoints. Omitted endpoint settings inherit `pcbTeardrops`. -| Property | Description | -| --- | --- | -| `pcbTeardrops` | Enable automatic teardrops at supported pad and via contacts. Defaults to disabled. | -| `pcbTeardropStart` | Teardrop at the start (from) of trace. | -| `pcbTeardropEnd` | Teardrop at the end (to) of trace. | +This example adds a teardrop at R1 while leaving the C1 end unchanged: -Start and end refer to the logical `from` and `to` connections, even if the -stored route runs in reverse. When omitted, either endpoint setting inherits -`pcbTeardrops`. An explicit `true` or `false` overrides that setting for the -endpoint. For example, this enables teardrops but disables them at C1: - -```tsx + ( @@ -78,18 +69,7 @@ export default () => ( /> ) -``` - -To enable only the `from` endpoint, set `pcbTeardropStart` without -`pcbTeardrops`. To enable via teardrops while disabling both endpoints, use -`pcbTeardrops` with `pcbTeardropStart={false}` and `pcbTeardropEnd={false}`. - -Automatic teardrops depend on the contact geometry and available straight -trace length. Unsupported pad shapes and segments too short for a taper are -skipped. These controls do not choose a curve or set custom dimensions. -For explicit widths and interpolation, use -[saved `pcbTracePaths`](../guides/reusing-saved-fanout-trace-paths.mdx#tapered-wire-segments). -Explicit tapers in saved paths are preserved by automatic teardrop generation. +`} /> ## Connecting to Nets diff --git a/docs/guides/reusing-saved-fanout-trace-paths.mdx b/docs/guides/reusing-saved-fanout-trace-paths.mdx index 77355d8f..0e747363 100644 --- a/docs/guides/reusing-saved-fanout-trace-paths.mdx +++ b/docs/guides/reusing-saved-fanout-trace-paths.mdx @@ -96,7 +96,7 @@ Each route contains at least two points: | Point | Required fields | Optional fields | | --- | --- | --- | -| Wire | `route_type: "wire"`, `x`, `y`, `width`, `layer` | `width_interpolation_mode` | +| Wire | `route_type: "wire"`, `x`, `y`, `width`, `layer` | — | | Via | `route_type: "via"`, `x`, `y`, `from_layer`, `to_layer` | `via_diameter`, `via_hole_diameter` | Only wire and via points are supported. Wire widths and specified via diameters @@ -110,61 +110,6 @@ including `false`. A trailing via creates its exit on `to_layer`. Core emits coincident wire contacts around endpoint vias for Circuit JSON connectivity; those contacts do not move the via or alter the saved copper. -## Tapered wire segments - -Set `width_interpolation_mode` on a wire point to interpolate from its `width` -to the next wire point's `width`. Use `"linear"` for a straight-sided taper or -`"quadratic"` for a curved teardrop profile. The mode applies to the outgoing -segment only. Without it, that segment keeps its starting width even if the -next point has a different width. - -This example narrows from the left pad of a 0402 resistor to a 0.15 mm trace, -then continues to a fanout exit. The pad center is `(-0.51, 0)` in the fanout's -local frame. - -```tsx -import type { FanoutTracePath } from "@tscircuit/props" - -const savedPaths: FanoutTracePath[] = [ - { - connection: "R1.1", - route: [ - { - route_type: "wire", - x: -0.51, - y: 0, - width: 0.5, - layer: "top", - width_interpolation_mode: "quadratic", - }, - { route_type: "wire", x: -1.5, y: 0, width: 0.15, layer: "top" }, - { route_type: "wire", x: -2.5, y: 1, width: 0.15, layer: "top" }, - { route_type: "wire", x: -3.5, y: 1, width: 0.15, layer: "top" }, - ], - }, -] - -export default () => ( - - - - - - - -) -``` - -Interpolation requires a next wire point on the same layer at a different -position. Do not set it on the last point, or directly before a via. To taper -into a via, insert a wire point at the via's coordinates first; that point's -width is the taper's ending width. - -The same point format works in `pcbTracePaths` on -[``](../elements/autoroutingphase.mdx). For automatically -sized pad and via teardrops, use the -[`` teardrop controls](../elements/trace.mdx#pcb-teardrops). - ## Coverage and validation `pcbTracePaths` replaces automatic routing for that fanout. Supply a path for