From 040f8429822e93f48be655d1c1aa0992cc33d250 Mon Sep 17 00:00:00 2001 From: techmannih Date: Fri, 3 Jul 2026 14:20:22 +0530 Subject: [PATCH 1/9] add diode fab polarity symbols --- src/fn/melf.ts | 9 ++ src/fn/micromelf.ts | 9 ++ src/fn/minimelf.ts | 9 ++ src/fn/sma.ts | 9 ++ src/fn/smb.ts | 9 ++ src/fn/smbf.ts | 9 ++ src/fn/smc.ts | 9 ++ src/fn/smf.ts | 9 ++ src/fn/sod110.ts | 9 ++ src/fn/sod123.ts | 9 ++ src/fn/sod123f.ts | 9 ++ src/fn/sod123fl.ts | 9 ++ src/fn/sod123w.ts | 9 ++ src/fn/sod128.ts | 9 ++ src/fn/sod323.ts | 9 ++ src/fn/sod323f.ts | 9 ++ src/fn/sod323fl.ts | 9 ++ src/fn/sod323w.ts | 9 ++ src/fn/sod523.ts | 9 ++ src/fn/sod723.ts | 3 + src/fn/sod80.ts | 9 ++ src/fn/sod882.ts | 9 ++ src/fn/sod882d.ts | 9 ++ src/fn/sod923.ts | 9 ++ src/helpers/apply-origin.ts | 12 ++ src/helpers/diode-fabrication-notes.ts | 129 ++++++++++++++++++ src/helpers/passive-fn.ts | 12 ++ tests/__snapshots__/diode.snap.svg | 2 +- tests/__snapshots__/diode0201.snap.svg | 2 +- tests/__snapshots__/diode0603.snap.svg | 2 +- tests/__snapshots__/diode1210.snap.svg | 2 +- tests/__snapshots__/diode2512.snap.svg | 2 +- tests/__snapshots__/melf.snap.svg | 2 +- tests/__snapshots__/micromelf.snap.svg | 2 +- tests/__snapshots__/minimelf.snap.svg | 2 +- tests/__snapshots__/sma.snap.svg | 2 +- tests/__snapshots__/smb.snap.svg | 2 +- tests/__snapshots__/smbf.snap.svg | 2 +- tests/__snapshots__/smc.snap.svg | 2 +- tests/__snapshots__/smf.snap.svg | 2 +- tests/__snapshots__/sod110.snap.svg | 2 +- tests/__snapshots__/sod123.snap.svg | 2 +- tests/__snapshots__/sod123f.snap.svg | 2 +- tests/__snapshots__/sod123fl.snap.svg | 2 +- tests/__snapshots__/sod123w.snap.svg | 2 +- tests/__snapshots__/sod128.snap.svg | 2 +- tests/__snapshots__/sod323.snap.svg | 2 +- tests/__snapshots__/sod323f.snap.svg | 2 +- tests/__snapshots__/sod323fl.snap.svg | 2 +- tests/__snapshots__/sod323w.snap.svg | 2 +- tests/__snapshots__/sod523.snap.svg | 2 +- tests/__snapshots__/sod80.snap.svg | 2 +- tests/__snapshots__/sod882.snap.svg | 2 +- tests/__snapshots__/sod882d.snap.svg | 2 +- tests/__snapshots__/sod923.snap.svg | 2 +- tests/diode.test.ts | 46 +++++++ .../kicad-parity/__snapshots__/melf.snap.svg | 2 +- .../__snapshots__/micromelf.snap.svg | 2 +- .../__snapshots__/minimelf.snap.svg | 2 +- tests/kicad-parity/__snapshots__/sma.snap.svg | 2 +- tests/kicad-parity/__snapshots__/smb.snap.svg | 2 +- tests/kicad-parity/__snapshots__/smc.snap.svg | 2 +- .../__snapshots__/sod110.snap.svg | 2 +- .../__snapshots__/sod123.snap.svg | 2 +- .../__snapshots__/sod123f.snap.svg | 2 +- .../__snapshots__/sod123w.snap.svg | 2 +- .../__snapshots__/sod128.snap.svg | 2 +- .../__snapshots__/sod323.snap.svg | 2 +- .../__snapshots__/sod323f.snap.svg | 2 +- .../__snapshots__/sod523.snap.svg | 2 +- .../__snapshots__/sod882.snap.svg | 2 +- .../__snapshots__/sod882d.snap.svg | 2 +- .../__snapshots__/sod923.snap.svg | 2 +- .../__snapshots__/d_0201_0603metric.snap.svg | 2 +- .../diodes/__snapshots__/melf.snap.svg | 2 +- .../diodes/__snapshots__/micromelf.snap.svg | 2 +- .../diodes/__snapshots__/minimelf.snap.svg | 2 +- .../diodes/__snapshots__/sma.snap.svg | 2 +- .../diodes/__snapshots__/smb.snap.svg | 2 +- .../diodes/__snapshots__/smc.snap.svg | 2 +- .../diodes/__snapshots__/sod110.snap.svg | 2 +- .../diodes/__snapshots__/sod123.snap.svg | 2 +- .../diodes/__snapshots__/sod123f.snap.svg | 2 +- .../diodes/__snapshots__/sod123w.snap.svg | 2 +- .../diodes/__snapshots__/sod128.snap.svg | 2 +- .../diodes/__snapshots__/sod323.snap.svg | 2 +- .../diodes/__snapshots__/sod323f.snap.svg | 2 +- .../diodes/__snapshots__/sod523.snap.svg | 2 +- .../diodes/__snapshots__/sod882.snap.svg | 2 +- .../diodes/__snapshots__/sod882d.snap.svg | 2 +- .../diodes/__snapshots__/sod923.snap.svg | 2 +- tests/origin.test.ts | 52 +++++++ tests/sod123.test.ts | 24 ++++ tests/sod723.test.ts | 11 ++ 94 files changed, 559 insertions(+), 63 deletions(-) create mode 100644 src/helpers/diode-fabrication-notes.ts diff --git a/src/fn/melf.ts b/src/fn/melf.ts index 3f5ccc71..80cb7edd 100644 --- a/src/fn/melf.ts +++ b/src/fn/melf.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const melf = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = melf_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -71,6 +79,7 @@ export const melf = ( return { circuitJson: melfWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/micromelf.ts b/src/fn/micromelf.ts index 165c0b05..f91ab7d7 100644 --- a/src/fn/micromelf.ts +++ b/src/fn/micromelf.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const micromelf = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = micromelf_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -71,6 +79,7 @@ export const micromelf = ( return { circuitJson: microMelfWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/minimelf.ts b/src/fn/minimelf.ts index 4b032c54..bdcf4c9d 100644 --- a/src/fn/minimelf.ts +++ b/src/fn/minimelf.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const minimelf = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = minimelf_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -71,6 +79,7 @@ export const minimelf = ( return { circuitJson: miniMelfWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sma.ts b/src/fn/sma.ts index 4142a555..0ed8c75a 100644 --- a/src/fn/sma.ts +++ b/src/fn/sma.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const sma = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sma_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -71,6 +79,7 @@ export const sma = ( return { circuitJson: smaWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/smb.ts b/src/fn/smb.ts index 5b71080c..71b24f4d 100644 --- a/src/fn/smb.ts +++ b/src/fn/smb.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const smb = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = smb_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -71,6 +79,7 @@ export const smb = ( return { circuitJson: smbWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/smbf.ts b/src/fn/smbf.ts index 5cc68bbb..0dde53d0 100644 --- a/src/fn/smbf.ts +++ b/src/fn/smbf.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const smbf = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = smbf_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -71,6 +79,7 @@ export const smbf = ( return { circuitJson: smbfWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/smc.ts b/src/fn/smc.ts index 3444e450..677c6fe0 100644 --- a/src/fn/smc.ts +++ b/src/fn/smc.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const smc = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = smc_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef(0, 3, 0.3) @@ -67,6 +75,7 @@ export const smc = ( return { circuitJson: smcWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/smf.ts b/src/fn/smf.ts index 17a3eb6c..81fd5ce5 100644 --- a/src/fn/smf.ts +++ b/src/fn/smf.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const smf = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = smf_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -71,6 +79,7 @@ export const smf = ( return { circuitJson: smfWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod110.ts b/src/fn/sod110.ts index 7e8dbae2..09550bc8 100644 --- a/src/fn/sod110.ts +++ b/src/fn/sod110.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -23,6 +24,13 @@ export const sod110 = ( raw_params: z.input, ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) + + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, length.parse(parameters.h) / 2 + 0.5, @@ -69,6 +77,7 @@ export const sod110 = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod123.ts b/src/fn/sod123.ts index f346b7b4..aaff7689 100644 --- a/src/fn/sod123.ts +++ b/src/fn/sod123.ts @@ -2,6 +2,7 @@ import type { AnyCircuitElement, PcbCourtyardRect } from "circuit-json" import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -19,6 +20,13 @@ export const sod123 = ( raw_params: z.input, ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) + + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, length.parse(parameters.h) / 4 + 0.4, @@ -39,6 +47,7 @@ export const sod123 = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, ), diff --git a/src/fn/sod123f.ts b/src/fn/sod123f.ts index bd3bf040..70505d42 100644 --- a/src/fn/sod123f.ts +++ b/src/fn/sod123f.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const sod123f = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -72,6 +80,7 @@ export const sod123f = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod123fl.ts b/src/fn/sod123fl.ts index b1555915..541710f5 100644 --- a/src/fn/sod123fl.ts +++ b/src/fn/sod123fl.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const sod123fl = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod123FL_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -72,6 +80,7 @@ export const sod123fl = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod123w.ts b/src/fn/sod123w.ts index b2138813..180464f5 100644 --- a/src/fn/sod123w.ts +++ b/src/fn/sod123w.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const sod123w = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -72,6 +80,7 @@ export const sod123w = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod128.ts b/src/fn/sod128.ts index fb164e48..d008f46a 100644 --- a/src/fn/sod128.ts +++ b/src/fn/sod128.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const sod128 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -72,6 +80,7 @@ export const sod128 = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod323.ts b/src/fn/sod323.ts index 4c7ea3aa..e2587215 100644 --- a/src/fn/sod323.ts +++ b/src/fn/sod323.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const sod323 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -71,6 +79,7 @@ export const sod323 = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod323f.ts b/src/fn/sod323f.ts index 74883fa2..5ffab823 100644 --- a/src/fn/sod323f.ts +++ b/src/fn/sod323f.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const sod323f = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.pad_spacing) / 2, + pin2PadX: length.parse(parameters.pad_spacing) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -72,6 +80,7 @@ export const sod323f = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod323fl.ts b/src/fn/sod323fl.ts index 76fdb356..9a02e058 100644 --- a/src/fn/sod323fl.ts +++ b/src/fn/sod323fl.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const sod323fl = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod323FL_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.pad_spacing) / 2, + pin2PadX: length.parse(parameters.pad_spacing) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -72,6 +80,7 @@ export const sod323fl = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod323w.ts b/src/fn/sod323w.ts index 35740742..97f54994 100644 --- a/src/fn/sod323w.ts +++ b/src/fn/sod323w.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const sod323w = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod323w_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.pad_spacing) / 2, + pin2PadX: length.parse(parameters.pad_spacing) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -72,6 +80,7 @@ export const sod323w = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod523.ts b/src/fn/sod523.ts index edd8d5b4..f2887e77 100644 --- a/src/fn/sod523.ts +++ b/src/fn/sod523.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const sod523 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -72,6 +80,7 @@ export const sod523 = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod723.ts b/src/fn/sod723.ts index 05f530fe..ee887ace 100644 --- a/src/fn/sod723.ts +++ b/src/fn/sod723.ts @@ -24,6 +24,8 @@ export const sod723 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) + const fabricationNotes: AnyCircuitElement[] = [] + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -71,6 +73,7 @@ export const sod723 = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod80.ts b/src/fn/sod80.ts index 206cb917..5531e712 100644 --- a/src/fn/sod80.ts +++ b/src/fn/sod80.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const sod80 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod80_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -71,6 +79,7 @@ export const sod80 = ( return { circuitJson: sod80WithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod882.ts b/src/fn/sod882.ts index 7fddcf8b..a1e06c0e 100644 --- a/src/fn/sod882.ts +++ b/src/fn/sod882.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const sod882 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -72,6 +80,7 @@ export const sod882 = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod882d.ts b/src/fn/sod882d.ts index 0ed8447a..e8fa557b 100644 --- a/src/fn/sod882d.ts +++ b/src/fn/sod882d.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" @@ -24,6 +25,13 @@ export const sod882d = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) + // Define silkscreen reference text const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, @@ -72,6 +80,7 @@ export const sod882d = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/fn/sod923.ts b/src/fn/sod923.ts index 8c3b365b..227d482f 100644 --- a/src/fn/sod923.ts +++ b/src/fn/sod923.ts @@ -6,6 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" +import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" import { createRectUnionOutline } from "src/helpers/rect-union-outline" @@ -24,6 +25,13 @@ export const sod923 = ( raw_params: z.input, ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) + + const fabricationNotes = createDiodeFabricationNotes({ + pin1PadX: -length.parse(parameters.p) / 2, + pin2PadX: length.parse(parameters.p) / 2, + padWidth: length.parse(parameters.pl), + padHeight: length.parse(parameters.pw), + }) const w = length.parse(parameters.w) const h = length.parse(parameters.h) const pl = length.parse(parameters.pl) @@ -96,6 +104,7 @@ export const sod923 = ( return { circuitJson: sodWithoutParsing(parameters).concat( + fabricationNotes as AnyCircuitElement[], silkscreenLine as AnyCircuitElement, silkscreenRefText as AnyCircuitElement, courtyard as AnyCircuitElement, diff --git a/src/helpers/apply-origin.ts b/src/helpers/apply-origin.ts index 369ace12..97a22d96 100644 --- a/src/helpers/apply-origin.ts +++ b/src/helpers/apply-origin.ts @@ -109,10 +109,22 @@ export const applyOrigin = ( } } + if (el.type === "pcb_fabrication_note_path") { + for (const pt of el.route) { + pt.x -= dx + pt.y -= dy + } + } + if (el.type === "pcb_silkscreen_text" && el.anchor_position) { el.anchor_position.x -= dx el.anchor_position.y -= dy } + + if (el.type === "pcb_fabrication_note_text" && el.anchor_position) { + el.anchor_position.x -= dx + el.anchor_position.y -= dy + } } return elements diff --git a/src/helpers/diode-fabrication-notes.ts b/src/helpers/diode-fabrication-notes.ts new file mode 100644 index 00000000..23850d1d --- /dev/null +++ b/src/helpers/diode-fabrication-notes.ts @@ -0,0 +1,129 @@ +import type { + AnyCircuitElement, + PcbFabricationNotePath, +} from "circuit-json" + +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +export const createDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const centerX = (pin1PadX + pin2PadX) / 2 + const padDistance = Math.abs(pin2PadX - pin1PadX) + + // KiCad-like fab body rectangle that overlaps the pad area a bit. + const bodyWidth = Math.max(padDistance + padWidth * 0.3, padWidth * 1.8) + const bodyHeight = Math.max(padHeight * 1.35, 0.9) + + const leftX = centerX - bodyWidth / 2 + const rightX = centerX + bodyWidth / 2 + const topY = y + bodyHeight / 2 + const bottomY = y - bodyHeight / 2 + + // Build the symbol from the inner pad-facing edges so it never starts on top of pads. + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * 0.22 + const cathodeBarX = leadRightX - direction * usableSymbolWidth * 0.16 + const symbolHalfHeight = clamp( + Math.min(bodyHeight * 0.3, usableSymbolWidth * 0.46), + 0.12, + bodyHeight * 0.36, + ) + + const strokeWidth = clamp( + Math.min(bodyHeight * 0.055, bodyWidth * 0.035), + 0.025, + 0.06, + ) + + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + + // Diode triangle / arrow + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + + // Cathode bar + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + + // Cathode side lead + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [ ...fabPaths] +} diff --git a/src/helpers/passive-fn.ts b/src/helpers/passive-fn.ts index a4d8d718..b5dbcfaa 100644 --- a/src/helpers/passive-fn.ts +++ b/src/helpers/passive-fn.ts @@ -9,6 +9,7 @@ import { platedhole } from "./platedhole" import { z } from "zod" import { length, distance } from "circuit-json" import { type SilkscreenRef, silkscreenRef } from "./silkscreenRef" +import { createDiodeFabricationNotes } from "./diode-fabrication-notes" import { base_def } from "./zod/base_def" type StandardSize = { @@ -334,11 +335,21 @@ export const passive = (params: PassiveDef): AnyCircuitElement[] => { sz?.courtyard_width_mm && sz.courtyard_height_mm ? createCourtyardRect(sz.courtyard_width_mm, sz.courtyard_height_mm) : null + const fabricationNotes = + fn === "diode" && sz?.imperial !== "01005" + ? createDiodeFabricationNotes({ + pin1PadX: -p / 2, + pin2PadX: p / 2, + padWidth: pw, + padHeight: ph, + }) + : [] if (tht) { return [ platedhole(1, -p / 2, 0, pw, (pw * 1) / 0.8), platedhole(2, p / 2, 0, pw, (pw * 1) / 0.8), + ...fabricationNotes, ...silkscreenLines, silkscreenRefText, ...(courtyard ? [courtyard] : []), @@ -347,6 +358,7 @@ export const passive = (params: PassiveDef): AnyCircuitElement[] => { return [ rectpad(["1", "left"], -p / 2, 0, pw, ph), rectpad(["2", "right"], p / 2, 0, pw, ph), + ...fabricationNotes, ...silkscreenLines, silkscreenRefText, ...(courtyard ? [courtyard] : []), diff --git a/tests/__snapshots__/diode.snap.svg b/tests/__snapshots__/diode.snap.svg index 0b60b957..f99f6aa4 100644 --- a/tests/__snapshots__/diode.snap.svg +++ b/tests/__snapshots__/diode.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/diode0201.snap.svg b/tests/__snapshots__/diode0201.snap.svg index 3e5ea3af..f37d8491 100644 --- a/tests/__snapshots__/diode0201.snap.svg +++ b/tests/__snapshots__/diode0201.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/diode0603.snap.svg b/tests/__snapshots__/diode0603.snap.svg index 1bbda6e0..3fde5433 100644 --- a/tests/__snapshots__/diode0603.snap.svg +++ b/tests/__snapshots__/diode0603.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/diode1210.snap.svg b/tests/__snapshots__/diode1210.snap.svg index c37c0ad8..aeaad62b 100644 --- a/tests/__snapshots__/diode1210.snap.svg +++ b/tests/__snapshots__/diode1210.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/diode2512.snap.svg b/tests/__snapshots__/diode2512.snap.svg index b1a70c07..aba079f0 100644 --- a/tests/__snapshots__/diode2512.snap.svg +++ b/tests/__snapshots__/diode2512.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/melf.snap.svg b/tests/__snapshots__/melf.snap.svg index 0f92e0d5..bfc35276 100644 --- a/tests/__snapshots__/melf.snap.svg +++ b/tests/__snapshots__/melf.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/micromelf.snap.svg b/tests/__snapshots__/micromelf.snap.svg index 0777a53a..beab40d1 100644 --- a/tests/__snapshots__/micromelf.snap.svg +++ b/tests/__snapshots__/micromelf.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/minimelf.snap.svg b/tests/__snapshots__/minimelf.snap.svg index 2d770d1c..a87b2631 100644 --- a/tests/__snapshots__/minimelf.snap.svg +++ b/tests/__snapshots__/minimelf.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sma.snap.svg b/tests/__snapshots__/sma.snap.svg index 8bb1c437..e9a7f1d8 100644 --- a/tests/__snapshots__/sma.snap.svg +++ b/tests/__snapshots__/sma.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/smb.snap.svg b/tests/__snapshots__/smb.snap.svg index a023f486..57085ab6 100644 --- a/tests/__snapshots__/smb.snap.svg +++ b/tests/__snapshots__/smb.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/smbf.snap.svg b/tests/__snapshots__/smbf.snap.svg index 713685d7..ee8249e9 100644 --- a/tests/__snapshots__/smbf.snap.svg +++ b/tests/__snapshots__/smbf.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/smc.snap.svg b/tests/__snapshots__/smc.snap.svg index 36b1b93e..a134abe8 100644 --- a/tests/__snapshots__/smc.snap.svg +++ b/tests/__snapshots__/smc.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/smf.snap.svg b/tests/__snapshots__/smf.snap.svg index 0e4a8197..36d33300 100644 --- a/tests/__snapshots__/smf.snap.svg +++ b/tests/__snapshots__/smf.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod110.snap.svg b/tests/__snapshots__/sod110.snap.svg index 87d9a294..3edc9b26 100644 --- a/tests/__snapshots__/sod110.snap.svg +++ b/tests/__snapshots__/sod110.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod123.snap.svg b/tests/__snapshots__/sod123.snap.svg index be674646..e48752cc 100644 --- a/tests/__snapshots__/sod123.snap.svg +++ b/tests/__snapshots__/sod123.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod123f.snap.svg b/tests/__snapshots__/sod123f.snap.svg index 66409c57..6e20f2dd 100644 --- a/tests/__snapshots__/sod123f.snap.svg +++ b/tests/__snapshots__/sod123f.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod123fl.snap.svg b/tests/__snapshots__/sod123fl.snap.svg index 768d6b4c..e4e132ee 100644 --- a/tests/__snapshots__/sod123fl.snap.svg +++ b/tests/__snapshots__/sod123fl.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod123w.snap.svg b/tests/__snapshots__/sod123w.snap.svg index 0d9ce4c8..8ca5ec22 100644 --- a/tests/__snapshots__/sod123w.snap.svg +++ b/tests/__snapshots__/sod123w.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod128.snap.svg b/tests/__snapshots__/sod128.snap.svg index 221ad88a..03097d01 100644 --- a/tests/__snapshots__/sod128.snap.svg +++ b/tests/__snapshots__/sod128.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod323.snap.svg b/tests/__snapshots__/sod323.snap.svg index f3827cf3..80c07666 100644 --- a/tests/__snapshots__/sod323.snap.svg +++ b/tests/__snapshots__/sod323.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod323f.snap.svg b/tests/__snapshots__/sod323f.snap.svg index 553c0813..17a53909 100644 --- a/tests/__snapshots__/sod323f.snap.svg +++ b/tests/__snapshots__/sod323f.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod323fl.snap.svg b/tests/__snapshots__/sod323fl.snap.svg index 0f799bee..dae02ea2 100644 --- a/tests/__snapshots__/sod323fl.snap.svg +++ b/tests/__snapshots__/sod323fl.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod323w.snap.svg b/tests/__snapshots__/sod323w.snap.svg index 14396708..64cf89c3 100644 --- a/tests/__snapshots__/sod323w.snap.svg +++ b/tests/__snapshots__/sod323w.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod523.snap.svg b/tests/__snapshots__/sod523.snap.svg index 36f79e59..75b5c4f2 100644 --- a/tests/__snapshots__/sod523.snap.svg +++ b/tests/__snapshots__/sod523.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod80.snap.svg b/tests/__snapshots__/sod80.snap.svg index 8799fe57..4ad4c71a 100644 --- a/tests/__snapshots__/sod80.snap.svg +++ b/tests/__snapshots__/sod80.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod882.snap.svg b/tests/__snapshots__/sod882.snap.svg index 0ccf0914..730cb80b 100644 --- a/tests/__snapshots__/sod882.snap.svg +++ b/tests/__snapshots__/sod882.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod882d.snap.svg b/tests/__snapshots__/sod882d.snap.svg index 7580f80f..cde1be50 100644 --- a/tests/__snapshots__/sod882d.snap.svg +++ b/tests/__snapshots__/sod882d.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod923.snap.svg b/tests/__snapshots__/sod923.snap.svg index 2012a033..291147d2 100644 --- a/tests/__snapshots__/sod923.snap.svg +++ b/tests/__snapshots__/sod923.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/diode.test.ts b/tests/diode.test.ts index f0281745..d9ae3b7b 100644 --- a/tests/diode.test.ts +++ b/tests/diode.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -43,3 +44,48 @@ test("diode2512", () => { const svgContent = convertCircuitJsonToPcbSvg(soup) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "diode2512") }) + +test("diode fabrication notes include polarity guidance and cathode direction", () => { + const circuitJson = fp().diode().imperial("0603").circuitJson() + const pad1 = circuitJson.find( + (element) => + element.type === "pcb_smtpad" && element.port_hints?.[0] === "1", + )! + const pad2 = circuitJson.find( + (element) => + element.type === "pcb_smtpad" && element.port_hints?.[0] === "2", + )! + + const fabricationNotePaths = circuitJson.filter( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path", + ) + const arrowPath = fabricationNotePaths.find( + (path) => path.pcb_fabrication_note_path_id === "diode_symbol_arrow", + ) + const cathodeBar = fabricationNotePaths.find( + (path) => path.pcb_fabrication_note_path_id === "diode_symbol_cathode_bar", + ) + const outlinePath = fabricationNotePaths.find( + (path) => path.pcb_fabrication_note_path_id === "diode_symbol_outline", + ) + const leadInPath = fabricationNotePaths.find( + (path) => path.pcb_fabrication_note_path_id === "diode_symbol_lead_in", + ) + expect(fabricationNotePaths).toHaveLength(5) + expect(outlinePath?.route).toHaveLength(5) + expect(leadInPath?.route[0]?.x).toBeGreaterThan(pad1.x + pad1.width / 2) + expect(cathodeBar?.route[0]?.x).toBeLessThan(pad2.x - pad2.width / 2) + expect(arrowPath?.route[1]?.x).toBeGreaterThan(arrowPath?.route[0]?.x ?? 0) + expect(cathodeBar?.route[0]?.x).toBeGreaterThan(0) +}) + +test("diode01005 does not include fabrication notes", () => { + const circuitJson = fp().diode().imperial("01005").circuitJson() + const fabricationNotePaths = circuitJson.filter( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path", + ) + + expect(fabricationNotePaths).toHaveLength(0) +}) diff --git a/tests/kicad-parity/__snapshots__/melf.snap.svg b/tests/kicad-parity/__snapshots__/melf.snap.svg index bed1ab1d..0762018b 100644 --- a/tests/kicad-parity/__snapshots__/melf.snap.svg +++ b/tests/kicad-parity/__snapshots__/melf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/micromelf.snap.svg b/tests/kicad-parity/__snapshots__/micromelf.snap.svg index 830f5195..51a2897c 100644 --- a/tests/kicad-parity/__snapshots__/micromelf.snap.svg +++ b/tests/kicad-parity/__snapshots__/micromelf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/minimelf.snap.svg b/tests/kicad-parity/__snapshots__/minimelf.snap.svg index db93e6b7..11af8dc8 100644 --- a/tests/kicad-parity/__snapshots__/minimelf.snap.svg +++ b/tests/kicad-parity/__snapshots__/minimelf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sma.snap.svg b/tests/kicad-parity/__snapshots__/sma.snap.svg index 2943c11b..988c6b8c 100644 --- a/tests/kicad-parity/__snapshots__/sma.snap.svg +++ b/tests/kicad-parity/__snapshots__/sma.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/smb.snap.svg b/tests/kicad-parity/__snapshots__/smb.snap.svg index a014b419..52ee09e6 100644 --- a/tests/kicad-parity/__snapshots__/smb.snap.svg +++ b/tests/kicad-parity/__snapshots__/smb.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/smc.snap.svg b/tests/kicad-parity/__snapshots__/smc.snap.svg index 568dd7aa..fc38cfb0 100644 --- a/tests/kicad-parity/__snapshots__/smc.snap.svg +++ b/tests/kicad-parity/__snapshots__/smc.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod110.snap.svg b/tests/kicad-parity/__snapshots__/sod110.snap.svg index 83532844..6b224a0b 100644 --- a/tests/kicad-parity/__snapshots__/sod110.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod110.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod123.snap.svg b/tests/kicad-parity/__snapshots__/sod123.snap.svg index 0490d493..a9d0d9ce 100644 --- a/tests/kicad-parity/__snapshots__/sod123.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod123.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod123f.snap.svg b/tests/kicad-parity/__snapshots__/sod123f.snap.svg index a0c4fb1a..9d520ead 100644 --- a/tests/kicad-parity/__snapshots__/sod123f.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod123f.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod123w.snap.svg b/tests/kicad-parity/__snapshots__/sod123w.snap.svg index f97632ac..6e43d980 100644 --- a/tests/kicad-parity/__snapshots__/sod123w.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod123w.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod128.snap.svg b/tests/kicad-parity/__snapshots__/sod128.snap.svg index 7583e18c..85d7a05f 100644 --- a/tests/kicad-parity/__snapshots__/sod128.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod128.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod323.snap.svg b/tests/kicad-parity/__snapshots__/sod323.snap.svg index ebe22399..bdc71bd2 100644 --- a/tests/kicad-parity/__snapshots__/sod323.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod323.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod323f.snap.svg b/tests/kicad-parity/__snapshots__/sod323f.snap.svg index 261376e6..c33de7b3 100644 --- a/tests/kicad-parity/__snapshots__/sod323f.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod323f.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod523.snap.svg b/tests/kicad-parity/__snapshots__/sod523.snap.svg index 9c050d49..cb5ad740 100644 --- a/tests/kicad-parity/__snapshots__/sod523.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod523.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod882.snap.svg b/tests/kicad-parity/__snapshots__/sod882.snap.svg index 257f07ce..b8bdb98d 100644 --- a/tests/kicad-parity/__snapshots__/sod882.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod882.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod882d.snap.svg b/tests/kicad-parity/__snapshots__/sod882d.snap.svg index fc29e92a..378b53f5 100644 --- a/tests/kicad-parity/__snapshots__/sod882d.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod882d.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod923.snap.svg b/tests/kicad-parity/__snapshots__/sod923.snap.svg index 8f2c2777..af342cac 100644 --- a/tests/kicad-parity/__snapshots__/sod923.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod923.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/d_0201_0603metric.snap.svg b/tests/kicad-parity/diodes/__snapshots__/d_0201_0603metric.snap.svg index 2dcaf193..619e43c8 100644 --- a/tests/kicad-parity/diodes/__snapshots__/d_0201_0603metric.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/d_0201_0603metric.snap.svg @@ -1 +1 @@ -{REF}REF** \ No newline at end of file +{REF}REF** \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/melf.snap.svg b/tests/kicad-parity/diodes/__snapshots__/melf.snap.svg index bed1ab1d..0762018b 100644 --- a/tests/kicad-parity/diodes/__snapshots__/melf.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/melf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg b/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg index 830f5195..51a2897c 100644 --- a/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/minimelf.snap.svg b/tests/kicad-parity/diodes/__snapshots__/minimelf.snap.svg index db93e6b7..11af8dc8 100644 --- a/tests/kicad-parity/diodes/__snapshots__/minimelf.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/minimelf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sma.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sma.snap.svg index 7ee73dc9..988c6b8c 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sma.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sma.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/smb.snap.svg b/tests/kicad-parity/diodes/__snapshots__/smb.snap.svg index e5670960..52ee09e6 100644 --- a/tests/kicad-parity/diodes/__snapshots__/smb.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/smb.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/smc.snap.svg b/tests/kicad-parity/diodes/__snapshots__/smc.snap.svg index cc25a2f1..fc38cfb0 100644 --- a/tests/kicad-parity/diodes/__snapshots__/smc.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/smc.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod110.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod110.snap.svg index 83532844..6b224a0b 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod110.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod110.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod123.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod123.snap.svg index 0490d493..a9d0d9ce 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod123.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod123.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod123f.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod123f.snap.svg index a0c4fb1a..9d520ead 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod123f.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod123f.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod123w.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod123w.snap.svg index 35fc4fd0..6e43d980 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod123w.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod123w.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod128.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod128.snap.svg index 7583e18c..85d7a05f 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod128.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod128.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod323.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod323.snap.svg index ebe22399..bdc71bd2 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod323.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod323.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod323f.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod323f.snap.svg index 261376e6..c33de7b3 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod323f.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod323f.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod523.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod523.snap.svg index 9c050d49..cb5ad740 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod523.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod523.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod882.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod882.snap.svg index a4c72abc..b8bdb98d 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod882.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod882.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod882d.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod882d.snap.svg index fc29e92a..378b53f5 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod882d.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod882d.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod923.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod923.snap.svg index 8f2c2777..af342cac 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod923.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod923.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/origin.test.ts b/tests/origin.test.ts index 83d1e436..1640b202 100644 --- a/tests/origin.test.ts +++ b/tests/origin.test.ts @@ -131,3 +131,55 @@ test("res origin bottomleft snapshot", () => { "0603_bottomleft_origin", ) }) + +test("diode origin bottomleft shifts fabrication notes and symbol", () => { + const baseCircuit = fp().diode().imperial("0603").circuitJson() + const shiftedCircuit = fp() + .diode() + .imperial("0603") + .origin("bottomleft") + .circuitJson() + const basePad1 = baseCircuit.find( + (el) => el.type === "pcb_smtpad" && el.port_hints?.[0] === "1", + )! + const shiftedPad1 = shiftedCircuit.find( + (el) => el.type === "pcb_smtpad" && el.port_hints?.[0] === "1", + )! + const baseOutline = baseCircuit.find( + (el) => + el.type === "pcb_fabrication_note_path" && + el.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const shiftedOutline = shiftedCircuit.find( + (el) => + el.type === "pcb_fabrication_note_path" && + el.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const baseCathodeBar = baseCircuit.find( + (el) => + el.type === "pcb_fabrication_note_path" && + el.pcb_fabrication_note_path_id === "diode_symbol_cathode_bar", + )! + const shiftedCathodeBar = shiftedCircuit.find( + (el) => + el.type === "pcb_fabrication_note_path" && + el.pcb_fabrication_note_path_id === "diode_symbol_cathode_bar", + )! + const dx = basePad1.x - shiftedPad1.x + const dy = basePad1.y - shiftedPad1.y + + expect(shiftedOutline.route[0].x).toBeCloseTo(baseOutline.route[0].x - dx) + expect(shiftedOutline.route[0].y).toBeCloseTo(baseOutline.route[0].y - dy) + expect(shiftedCathodeBar.route[0].x).toBeCloseTo( + baseCathodeBar.route[0].x - dx, + ) + expect(shiftedCathodeBar.route[0].y).toBeCloseTo( + baseCathodeBar.route[0].y - dy, + ) + expect(shiftedCathodeBar.route[1].x).toBeCloseTo( + baseCathodeBar.route[1].x - dx, + ) + expect(shiftedCathodeBar.route[1].y).toBeCloseTo( + baseCathodeBar.route[1].y - dy, + ) +}) diff --git a/tests/sod123.test.ts b/tests/sod123.test.ts index fd2b7ad1..d3028e48 100644 --- a/tests/sod123.test.ts +++ b/tests/sod123.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -7,3 +8,26 @@ test("sod123", () => { const svgContent = convertCircuitJsonToPcbSvg(soup) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod123") }) + +test("sod123 fabrication notes include cathode direction symbol", () => { + const circuitJson = fp.string("sod123").circuitJson() + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + ) + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + ) + const cathodeBar = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_cathode_bar", + ) + + expect(outlinePath?.route).toHaveLength(5) + expect(arrowPath?.route[1]?.x).toBeGreaterThan(arrowPath?.route[0]?.x ?? 0) + expect(cathodeBar?.route[0]?.x).toBeGreaterThan(0) +}) diff --git a/tests/sod723.test.ts b/tests/sod723.test.ts index b546611c..d56642d5 100644 --- a/tests/sod723.test.ts +++ b/tests/sod723.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,13 @@ test("sod723", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod723") }) + +test("sod723 does not include fabrication notes", () => { + const circuitJson = fp.string("sod723").circuitJson() + const fabricationNotePaths = circuitJson.filter( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path", + ) + + expect(fabricationNotePaths).toHaveLength(0) +}) From 07e8cc905c776b56fd7de544b596808d8f556ee4 Mon Sep 17 00:00:00 2001 From: techmannih Date: Fri, 3 Jul 2026 20:13:42 +0530 Subject: [PATCH 2/9] update --- src/fn/melf.ts | 152 +++++++++++++++- src/fn/micromelf.ts | 152 +++++++++++++++- src/fn/minimelf.ts | 152 +++++++++++++++- src/fn/sma.ts | 152 +++++++++++++++- src/fn/smb.ts | 152 +++++++++++++++- src/fn/smbf.ts | 152 +++++++++++++++- src/fn/smc.ts | 152 +++++++++++++++- src/fn/smf.ts | 152 +++++++++++++++- src/fn/sod110.ts | 152 +++++++++++++++- src/fn/sod123.ts | 156 +++++++++++++++- src/fn/sod123f.ts | 152 +++++++++++++++- src/fn/sod123fl.ts | 152 +++++++++++++++- src/fn/sod123w.ts | 152 +++++++++++++++- src/fn/sod128.ts | 152 +++++++++++++++- src/fn/sod323.ts | 159 +++++++++++++++- src/fn/sod323f.ts | 159 +++++++++++++++- src/fn/sod323fl.ts | 152 +++++++++++++++- src/fn/sod323w.ts | 152 +++++++++++++++- src/fn/sod523.ts | 152 +++++++++++++++- src/fn/sod80.ts | 152 +++++++++++++++- src/fn/sod882.ts | 153 +++++++++++++++- src/fn/sod882d.ts | 153 +++++++++++++++- src/fn/sod923.ts | 152 +++++++++++++++- src/helpers/diode-fabrication-notes.ts | 129 ------------- src/helpers/passive-fn.ts | 171 +++++++++++++++++- tests/__snapshots__/diode.snap.svg | 2 +- tests/__snapshots__/diode0201.snap.svg | 2 +- tests/__snapshots__/diode0603.snap.svg | 2 +- tests/__snapshots__/diode1210.snap.svg | 2 +- tests/__snapshots__/diode2512.snap.svg | 2 +- tests/__snapshots__/melf.snap.svg | 2 +- tests/__snapshots__/micromelf.snap.svg | 2 +- tests/__snapshots__/minimelf.snap.svg | 2 +- tests/__snapshots__/sma.snap.svg | 2 +- tests/__snapshots__/smb.snap.svg | 2 +- tests/__snapshots__/smbf.snap.svg | 2 +- tests/__snapshots__/smc.snap.svg | 2 +- tests/__snapshots__/smf.snap.svg | 2 +- tests/__snapshots__/sod110.snap.svg | 2 +- tests/__snapshots__/sod123.snap.svg | 2 +- tests/__snapshots__/sod123f.snap.svg | 2 +- tests/__snapshots__/sod123fl.snap.svg | 2 +- tests/__snapshots__/sod123w.snap.svg | 2 +- tests/__snapshots__/sod128.snap.svg | 2 +- tests/__snapshots__/sod323.snap.svg | 2 +- tests/__snapshots__/sod323f.snap.svg | 2 +- tests/__snapshots__/sod323fl.snap.svg | 2 +- tests/__snapshots__/sod323w.snap.svg | 2 +- tests/__snapshots__/sod523.snap.svg | 2 +- tests/__snapshots__/sod80.snap.svg | 2 +- tests/__snapshots__/sod882.snap.svg | 2 +- tests/__snapshots__/sod882d.snap.svg | 2 +- tests/__snapshots__/sod923.snap.svg | 2 +- tests/diode.test.ts | 110 ++++++++++- .../kicad-parity/__snapshots__/melf.snap.svg | 2 +- .../__snapshots__/micromelf.snap.svg | 2 +- .../__snapshots__/minimelf.snap.svg | 2 +- tests/kicad-parity/__snapshots__/sma.snap.svg | 2 +- tests/kicad-parity/__snapshots__/smb.snap.svg | 2 +- tests/kicad-parity/__snapshots__/smc.snap.svg | 2 +- .../__snapshots__/sod110.snap.svg | 2 +- .../__snapshots__/sod123.snap.svg | 2 +- .../__snapshots__/sod123f.snap.svg | 2 +- .../__snapshots__/sod123w.snap.svg | 2 +- .../__snapshots__/sod128.snap.svg | 2 +- .../__snapshots__/sod323.snap.svg | 2 +- .../__snapshots__/sod323f.snap.svg | 2 +- .../__snapshots__/sod523.snap.svg | 2 +- .../__snapshots__/sod882.snap.svg | 2 +- .../__snapshots__/sod882d.snap.svg | 2 +- .../__snapshots__/sod923.snap.svg | 2 +- .../__snapshots__/d_0201_0603metric.snap.svg | 2 +- .../diodes/__snapshots__/melf.snap.svg | 2 +- .../diodes/__snapshots__/micromelf.snap.svg | 2 +- .../diodes/__snapshots__/minimelf.snap.svg | 2 +- .../diodes/__snapshots__/sma.snap.svg | 2 +- .../diodes/__snapshots__/smb.snap.svg | 2 +- .../diodes/__snapshots__/smc.snap.svg | 2 +- .../diodes/__snapshots__/sod110.snap.svg | 2 +- .../diodes/__snapshots__/sod123.snap.svg | 2 +- .../diodes/__snapshots__/sod123f.snap.svg | 2 +- .../diodes/__snapshots__/sod123w.snap.svg | 2 +- .../diodes/__snapshots__/sod128.snap.svg | 2 +- .../diodes/__snapshots__/sod323.snap.svg | 2 +- .../diodes/__snapshots__/sod323f.snap.svg | 2 +- .../diodes/__snapshots__/sod523.snap.svg | 2 +- .../diodes/__snapshots__/sod882.snap.svg | 2 +- .../diodes/__snapshots__/sod882d.snap.svg | 2 +- .../diodes/__snapshots__/sod923.snap.svg | 2 +- tests/melf.test.ts | 31 ++++ tests/micromelf.test.ts | 42 +++++ tests/minimelf.test.ts | 21 +++ tests/sma.test.ts | 36 ++++ tests/smb.test.ts | 36 ++++ tests/smbf.test.ts | 21 +++ tests/smc.test.ts | 31 ++++ tests/smf.test.ts | 21 +++ tests/sod110.test.ts | 21 +++ tests/sod123.test.ts | 47 +++++ tests/sod123f.test.ts | 21 +++ tests/sod123fl.test.ts | 21 +++ tests/sod123w.test.ts | 21 +++ tests/sod128.test.ts | 22 +++ tests/sod323.test.ts | 38 ++++ tests/sod323f.test.ts | 38 ++++ tests/sod323fl.test.ts | 22 +++ tests/sod323w.test.ts | 22 +++ tests/sod523.test.ts | 22 +++ tests/sod80.test.ts | 21 +++ tests/sod882.test.ts | 14 ++ tests/sod882d.test.ts | 34 ++++ tests/sod923.test.ts | 45 +++++ 112 files changed, 4433 insertions(+), 267 deletions(-) delete mode 100644 src/helpers/diode-fabrication-notes.ts diff --git a/src/fn/melf.ts b/src/fn/melf.ts index 80cb7edd..5c985692 100644 --- a/src/fn/melf.ts +++ b/src/fn/melf.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) + const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.075, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const melf_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const melf = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = melf_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/micromelf.ts b/src/fn/micromelf.ts index f91ab7d7..20af346b 100644 --- a/src/fn/micromelf.ts +++ b/src/fn/micromelf.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.2 - tightPitchBoost * 0.04, 0.17, 0.2) + const cathodeBarRatio = clamp(0.12 - tightPitchBoost * 0.02, 0.1, 0.12) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.27 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.34 + tightPitchBoost * 0.08), + ), + 0.12, + provisionalBodyHeight * (0.36 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const micromelf_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const micromelf = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = micromelf_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/minimelf.ts b/src/fn/minimelf.ts index bdcf4c9d..6f450753 100644 --- a/src/fn/minimelf.ts +++ b/src/fn/minimelf.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) + const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const minimelf_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const minimelf = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = minimelf_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sma.ts b/src/fn/sma.ts index 0ed8c75a..8b94e388 100644 --- a/src/fn/sma.ts +++ b/src/fn/sma.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.2, 0.24) + const cathodeBarRatio = clamp(0.16 - tightPitchBoost * 0.02, 0.12, 0.16) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.26 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.31 + tightPitchBoost * 0.08), + ), + 0.11, + provisionalBodyHeight * (0.35 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.075, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sma_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const sma = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sma_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/smb.ts b/src/fn/smb.ts index 71b24f4d..0dc8619d 100644 --- a/src/fn/smb.ts +++ b/src/fn/smb.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.2, 0.24) + const cathodeBarRatio = clamp(0.16 - tightPitchBoost * 0.02, 0.12, 0.16) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.26 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.31 + tightPitchBoost * 0.08), + ), + 0.11, + provisionalBodyHeight * (0.35 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.075, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const smb_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const smb = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = smb_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/smbf.ts b/src/fn/smbf.ts index 0dde53d0..803802dc 100644 --- a/src/fn/smbf.ts +++ b/src/fn/smbf.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) + const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const smbf_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const smbf = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = smbf_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/smc.ts b/src/fn/smc.ts index 677c6fe0..d3e84095 100644 --- a/src/fn/smc.ts +++ b/src/fn/smc.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) + const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.075, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const smc_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const smc = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = smc_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/smf.ts b/src/fn/smf.ts index 81fd5ce5..53efabee 100644 --- a/src/fn/smf.ts +++ b/src/fn/smf.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(-Math.min(padWidth, padHeight) * 0.03, -0.04, -0.02) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) + const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const smf_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const smf = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = smf_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sod110.ts b/src/fn/sod110.ts index 09550bc8..31d0f25b 100644 --- a/src/fn/sod110.ts +++ b/src/fn/sod110.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.3 - tightPitchBoost * 0.03, 0.24, 0.3) + const cathodeBarRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.18, 0.24) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const sod110 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, diff --git a/src/fn/sod123.ts b/src/fn/sod123.ts index aaff7689..754f1f0f 100644 --- a/src/fn/sod123.ts +++ b/src/fn/sod123.ts @@ -1,11 +1,159 @@ -import type { AnyCircuitElement, PcbCourtyardRect } from "circuit-json" +import type { + AnyCircuitElement, + PcbCourtyardRect, + PcbFabricationNotePath, +} from "circuit-json" import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" import { length } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.31 - tightPitchBoost * 0.03, 0.25, 0.31) + const cathodeBarRatio = clamp(0.25 - tightPitchBoost * 0.03, 0.19, 0.25) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -21,11 +169,13 @@ export const sod123 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, diff --git a/src/fn/sod123f.ts b/src/fn/sod123f.ts index 70505d42..290ad006 100644 --- a/src/fn/sod123f.ts +++ b/src/fn/sod123f.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.3 - tightPitchBoost * 0.03, 0.24, 0.3) + const cathodeBarRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.18, 0.24) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const sod123f = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sod123fl.ts b/src/fn/sod123fl.ts index 541710f5..aef2ada8 100644 --- a/src/fn/sod123fl.ts +++ b/src/fn/sod123fl.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.3 - tightPitchBoost * 0.03, 0.24, 0.3) + const cathodeBarRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.18, 0.24) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod123FL_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const sod123fl = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod123FL_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sod123w.ts b/src/fn/sod123w.ts index 180464f5..dc15ca97 100644 --- a/src/fn/sod123w.ts +++ b/src/fn/sod123w.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.3 - tightPitchBoost * 0.03, 0.24, 0.3) + const cathodeBarRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.18, 0.24) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const sod123w = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sod128.ts b/src/fn/sod128.ts index d008f46a..be596de8 100644 --- a/src/fn/sod128.ts +++ b/src/fn/sod128.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) + const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const sod128 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sod323.ts b/src/fn/sod323.ts index e2587215..7620f61f 100644 --- a/src/fn/sod323.ts +++ b/src/fn/sod323.ts @@ -6,10 +6,161 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const symbolLeadInsetX = clamp(padDistance * 0.16, 0.14, 0.36) + const symbolLeadLeftX = leadLeftX + direction * symbolLeadInsetX + const symbolLeadRightX = leadRightX - direction * symbolLeadInsetX + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max( + 0.14, + Math.abs(symbolLeadRightX - symbolLeadLeftX), + ) + const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) + const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) + const arrowBaseX = + symbolLeadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + symbolLeadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: symbolLeadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: symbolLeadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +176,13 @@ export const sod323 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sod323f.ts b/src/fn/sod323f.ts index 5ffab823..1b6a4b49 100644 --- a/src/fn/sod323f.ts +++ b/src/fn/sod323f.ts @@ -6,10 +6,161 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const symbolLeadInsetX = clamp(padDistance * 0.16, 0.14, 0.36) + const symbolLeadLeftX = leadLeftX + direction * symbolLeadInsetX + const symbolLeadRightX = leadRightX - direction * symbolLeadInsetX + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max( + 0.14, + Math.abs(symbolLeadRightX - symbolLeadLeftX), + ) + const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) + const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) + const arrowBaseX = + symbolLeadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + symbolLeadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: symbolLeadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: symbolLeadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +176,13 @@ export const sod323f = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.pad_spacing) / 2, pin2PadX: length.parse(parameters.pad_spacing) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sod323fl.ts b/src/fn/sod323fl.ts index 9a02e058..2188bbc3 100644 --- a/src/fn/sod323fl.ts +++ b/src/fn/sod323fl.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.26 - tightPitchBoost * 0.03, 0.2, 0.26) + const cathodeBarRatio = clamp(0.2 - tightPitchBoost * 0.03, 0.14, 0.2) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod323FL_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const sod323fl = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod323FL_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.pad_spacing) / 2, pin2PadX: length.parse(parameters.pad_spacing) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sod323w.ts b/src/fn/sod323w.ts index 97f54994..e8afdbc2 100644 --- a/src/fn/sod323w.ts +++ b/src/fn/sod323w.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.26 - tightPitchBoost * 0.03, 0.2, 0.26) + const cathodeBarRatio = clamp(0.2 - tightPitchBoost * 0.03, 0.14, 0.2) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod323w_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const sod323w = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod323w_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.pad_spacing) / 2, pin2PadX: length.parse(parameters.pad_spacing) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sod523.ts b/src/fn/sod523.ts index f2887e77..cbd24a33 100644 --- a/src/fn/sod523.ts +++ b/src/fn/sod523.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.26 - tightPitchBoost * 0.03, 0.2, 0.26) + const cathodeBarRatio = clamp(0.2 - tightPitchBoost * 0.03, 0.14, 0.2) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const sod523 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sod80.ts b/src/fn/sod80.ts index 5531e712..8e982843 100644 --- a/src/fn/sod80.ts +++ b/src/fn/sod80.ts @@ -6,10 +6,154 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.3 - tightPitchBoost * 0.03, 0.24, 0.3) + const cathodeBarRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.18, 0.24) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod80_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +169,13 @@ export const sod80 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod80_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sod882.ts b/src/fn/sod882.ts index a1e06c0e..5696bb02 100644 --- a/src/fn/sod882.ts +++ b/src/fn/sod882.ts @@ -6,10 +6,155 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.14 - tightPitchBoost * 0.06, 0.06, 0.14) + const cathodeBarRatio = clamp(0.08 - tightPitchBoost * 0.03, 0.03, 0.08) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const baseBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const finalBodyHeight = baseBodyHeight * (2 / 3) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +170,13 @@ export const sod882 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sod882d.ts b/src/fn/sod882d.ts index e8fa557b..248ff147 100644 --- a/src/fn/sod882d.ts +++ b/src/fn/sod882d.ts @@ -6,10 +6,155 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.17 - tightPitchBoost * 0.05, 0.12, 0.17) + const cathodeBarRatio = clamp(0.1 - tightPitchBoost * 0.02, 0.07, 0.1) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const baseBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const finalBodyHeight = baseBodyHeight * (2 / 3) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -25,11 +170,13 @@ export const sod882d = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) // Define silkscreen reference text diff --git a/src/fn/sod923.ts b/src/fn/sod923.ts index 227d482f..91194049 100644 --- a/src/fn/sod923.ts +++ b/src/fn/sod923.ts @@ -6,11 +6,155 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { createDiodeFabricationNotes } from "../helpers/diode-fabrication-notes" -import { length } from "circuit-json" +import { length, PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" import { createRectUnionOutline } from "src/helpers/rect-union-outline" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const arrowBaseRatio = clamp(0.29 - tightPitchBoost * 0.02, 0.26, 0.3) + const cathodeBarRatio = clamp(0.23 - tightPitchBoost * 0.02, 0.2, 0.24) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -26,11 +170,13 @@ export const sod923 = ( ): { circuitJson: AnyCircuitElement[]; parameters: any } => { const parameters = sod_def.parse(raw_params) - const fabricationNotes = createDiodeFabricationNotes({ + const fabricationNotes = createManualDiodeFabricationNotes({ pin1PadX: -length.parse(parameters.p) / 2, pin2PadX: length.parse(parameters.p) / 2, padWidth: length.parse(parameters.pl), padHeight: length.parse(parameters.pw), + bodyWidth: length.parse(parameters.w), + bodyHeight: length.parse(parameters.h), }) const w = length.parse(parameters.w) const h = length.parse(parameters.h) diff --git a/src/helpers/diode-fabrication-notes.ts b/src/helpers/diode-fabrication-notes.ts deleted file mode 100644 index 23850d1d..00000000 --- a/src/helpers/diode-fabrication-notes.ts +++ /dev/null @@ -1,129 +0,0 @@ -import type { - AnyCircuitElement, - PcbFabricationNotePath, -} from "circuit-json" - -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -export const createDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const centerX = (pin1PadX + pin2PadX) / 2 - const padDistance = Math.abs(pin2PadX - pin1PadX) - - // KiCad-like fab body rectangle that overlaps the pad area a bit. - const bodyWidth = Math.max(padDistance + padWidth * 0.3, padWidth * 1.8) - const bodyHeight = Math.max(padHeight * 1.35, 0.9) - - const leftX = centerX - bodyWidth / 2 - const rightX = centerX + bodyWidth / 2 - const topY = y + bodyHeight / 2 - const bottomY = y - bodyHeight / 2 - - // Build the symbol from the inner pad-facing edges so it never starts on top of pads. - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * 0.22 - const cathodeBarX = leadRightX - direction * usableSymbolWidth * 0.16 - const symbolHalfHeight = clamp( - Math.min(bodyHeight * 0.3, usableSymbolWidth * 0.46), - 0.12, - bodyHeight * 0.36, - ) - - const strokeWidth = clamp( - Math.min(bodyHeight * 0.055, bodyWidth * 0.035), - 0.025, - 0.06, - ) - - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - - // Diode triangle / arrow - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - - // Cathode bar - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - - // Cathode side lead - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [ ...fabPaths] -} diff --git a/src/helpers/passive-fn.ts b/src/helpers/passive-fn.ts index b5dbcfaa..3309b703 100644 --- a/src/helpers/passive-fn.ts +++ b/src/helpers/passive-fn.ts @@ -7,11 +7,173 @@ import { rectpad } from "../helpers/rectpad" import mm from "@tscircuit/mm" import { platedhole } from "./platedhole" import { z } from "zod" -import { length, distance } from "circuit-json" +import { length, distance, PcbFabricationNotePath } from "circuit-json" import { type SilkscreenRef, silkscreenRef } from "./silkscreenRef" -import { createDiodeFabricationNotes } from "./diode-fabrication-notes" import { base_def } from "./zod/base_def" +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +const createManualDiodeFabricationNotes = (params: { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + footprintSize?: string + layer?: "top" | "bottom" + y?: number +}): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + footprintSize, + layer = "top", + y = 0, + } = params + + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) + const usesSlightlyNarrower0201Symbol = footprintSize === "0201" + const usesSlightlyNarrower0402Symbol = footprintSize === "0402" + const arrowBaseRatio = + footprintSize === "2512" + ? clamp(0.3 - tightPitchBoost * 0.03, 0.27, 0.3) + : usesSlightlyNarrower0201Symbol + ? clamp(0.18 - tightPitchBoost * 0.055, 0.12, 0.18) + : usesSlightlyNarrower0402Symbol + ? clamp(0.16 - tightPitchBoost * 0.06, 0.1, 0.16) + : clamp(0.14 - tightPitchBoost * 0.06, 0.06, 0.14) + const cathodeBarRatio = + footprintSize === "2512" + ? clamp(0.22 - tightPitchBoost * 0.02, 0.2, 0.22) + : usesSlightlyNarrower0201Symbol + ? clamp(0.11 - tightPitchBoost * 0.03, 0.07, 0.11) + : usesSlightlyNarrower0402Symbol + ? clamp(0.1 - tightPitchBoost * 0.03, 0.06, 0.1) + : clamp(0.08 - tightPitchBoost * 0.03, 0.03, 0.08) + const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + leadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), + ), + 0.1, + provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), + ) + const finalBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const topY = y + finalBodyHeight / 2 + const bottomY = y - finalBodyHeight / 2 + + const strokeWidth = clamp( + Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), + 0.025, + 0.06, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_outline", + pcb_component_id: "", + layer, + route: [ + { x: leftX, y: topY }, + { x: rightX, y: topY }, + { x: rightX, y: bottomY }, + { x: leftX, y: bottomY }, + { x: leftX, y: topY }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_in", + pcb_component_id: "", + layer, + route: [ + { x: leadLeftX, y }, + { x: arrowBaseX, y }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_arrow", + pcb_component_id: "", + layer, + route: [ + { x: arrowBaseX, y: y - symbolHalfHeight }, + { x: cathodeBarX, y }, + { x: arrowBaseX, y: y + symbolHalfHeight }, + { x: arrowBaseX, y: y - symbolHalfHeight }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", + pcb_component_id: "pin_2", + layer, + route: [ + { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, + { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, + ], + stroke_width: strokeWidth, + }, + { + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id: "diode_symbol_lead_out", + pcb_component_id: "", + layer, + route: [ + { x: cathodeBarX, y }, + { x: leadRightX, y }, + ], + stroke_width: strokeWidth, + }, + ] + + return [...fabPaths] +} + type StandardSize = { imperial: string metric: string @@ -337,11 +499,14 @@ export const passive = (params: PassiveDef): AnyCircuitElement[] => { : null const fabricationNotes = fn === "diode" && sz?.imperial !== "01005" - ? createDiodeFabricationNotes({ + ? createManualDiodeFabricationNotes({ pin1PadX: -p / 2, pin2PadX: p / 2, padWidth: pw, padHeight: ph, + bodyWidth: w, + bodyHeight: h, + footprintSize: sz?.imperial, }) : [] diff --git a/tests/__snapshots__/diode.snap.svg b/tests/__snapshots__/diode.snap.svg index f99f6aa4..99c73e86 100644 --- a/tests/__snapshots__/diode.snap.svg +++ b/tests/__snapshots__/diode.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/diode0201.snap.svg b/tests/__snapshots__/diode0201.snap.svg index f37d8491..624163b5 100644 --- a/tests/__snapshots__/diode0201.snap.svg +++ b/tests/__snapshots__/diode0201.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/diode0603.snap.svg b/tests/__snapshots__/diode0603.snap.svg index 3fde5433..ee8a3bcd 100644 --- a/tests/__snapshots__/diode0603.snap.svg +++ b/tests/__snapshots__/diode0603.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/diode1210.snap.svg b/tests/__snapshots__/diode1210.snap.svg index aeaad62b..4ac6655b 100644 --- a/tests/__snapshots__/diode1210.snap.svg +++ b/tests/__snapshots__/diode1210.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/diode2512.snap.svg b/tests/__snapshots__/diode2512.snap.svg index aba079f0..1a6646be 100644 --- a/tests/__snapshots__/diode2512.snap.svg +++ b/tests/__snapshots__/diode2512.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/melf.snap.svg b/tests/__snapshots__/melf.snap.svg index bfc35276..b71ccc95 100644 --- a/tests/__snapshots__/melf.snap.svg +++ b/tests/__snapshots__/melf.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/micromelf.snap.svg b/tests/__snapshots__/micromelf.snap.svg index beab40d1..ccb76934 100644 --- a/tests/__snapshots__/micromelf.snap.svg +++ b/tests/__snapshots__/micromelf.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/minimelf.snap.svg b/tests/__snapshots__/minimelf.snap.svg index a87b2631..98bcb51a 100644 --- a/tests/__snapshots__/minimelf.snap.svg +++ b/tests/__snapshots__/minimelf.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sma.snap.svg b/tests/__snapshots__/sma.snap.svg index e9a7f1d8..b78ad431 100644 --- a/tests/__snapshots__/sma.snap.svg +++ b/tests/__snapshots__/sma.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/smb.snap.svg b/tests/__snapshots__/smb.snap.svg index 57085ab6..f7315138 100644 --- a/tests/__snapshots__/smb.snap.svg +++ b/tests/__snapshots__/smb.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/smbf.snap.svg b/tests/__snapshots__/smbf.snap.svg index ee8249e9..14d29775 100644 --- a/tests/__snapshots__/smbf.snap.svg +++ b/tests/__snapshots__/smbf.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/smc.snap.svg b/tests/__snapshots__/smc.snap.svg index a134abe8..3acdf598 100644 --- a/tests/__snapshots__/smc.snap.svg +++ b/tests/__snapshots__/smc.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/smf.snap.svg b/tests/__snapshots__/smf.snap.svg index 36d33300..0af3c1ce 100644 --- a/tests/__snapshots__/smf.snap.svg +++ b/tests/__snapshots__/smf.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod110.snap.svg b/tests/__snapshots__/sod110.snap.svg index 3edc9b26..fd2c9be1 100644 --- a/tests/__snapshots__/sod110.snap.svg +++ b/tests/__snapshots__/sod110.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod123.snap.svg b/tests/__snapshots__/sod123.snap.svg index e48752cc..2b78f0d1 100644 --- a/tests/__snapshots__/sod123.snap.svg +++ b/tests/__snapshots__/sod123.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod123f.snap.svg b/tests/__snapshots__/sod123f.snap.svg index 6e20f2dd..4571ec10 100644 --- a/tests/__snapshots__/sod123f.snap.svg +++ b/tests/__snapshots__/sod123f.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod123fl.snap.svg b/tests/__snapshots__/sod123fl.snap.svg index e4e132ee..5b32d050 100644 --- a/tests/__snapshots__/sod123fl.snap.svg +++ b/tests/__snapshots__/sod123fl.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod123w.snap.svg b/tests/__snapshots__/sod123w.snap.svg index 8ca5ec22..0e651a4d 100644 --- a/tests/__snapshots__/sod123w.snap.svg +++ b/tests/__snapshots__/sod123w.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod128.snap.svg b/tests/__snapshots__/sod128.snap.svg index 03097d01..72f22bee 100644 --- a/tests/__snapshots__/sod128.snap.svg +++ b/tests/__snapshots__/sod128.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod323.snap.svg b/tests/__snapshots__/sod323.snap.svg index 80c07666..2e46f72c 100644 --- a/tests/__snapshots__/sod323.snap.svg +++ b/tests/__snapshots__/sod323.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod323f.snap.svg b/tests/__snapshots__/sod323f.snap.svg index 17a53909..2fde59fb 100644 --- a/tests/__snapshots__/sod323f.snap.svg +++ b/tests/__snapshots__/sod323f.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod323fl.snap.svg b/tests/__snapshots__/sod323fl.snap.svg index dae02ea2..2a2bf663 100644 --- a/tests/__snapshots__/sod323fl.snap.svg +++ b/tests/__snapshots__/sod323fl.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod323w.snap.svg b/tests/__snapshots__/sod323w.snap.svg index 64cf89c3..bed26a3c 100644 --- a/tests/__snapshots__/sod323w.snap.svg +++ b/tests/__snapshots__/sod323w.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod523.snap.svg b/tests/__snapshots__/sod523.snap.svg index 75b5c4f2..2e03870a 100644 --- a/tests/__snapshots__/sod523.snap.svg +++ b/tests/__snapshots__/sod523.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod80.snap.svg b/tests/__snapshots__/sod80.snap.svg index 4ad4c71a..44af238d 100644 --- a/tests/__snapshots__/sod80.snap.svg +++ b/tests/__snapshots__/sod80.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod882.snap.svg b/tests/__snapshots__/sod882.snap.svg index 730cb80b..9ef1a9b6 100644 --- a/tests/__snapshots__/sod882.snap.svg +++ b/tests/__snapshots__/sod882.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod882d.snap.svg b/tests/__snapshots__/sod882d.snap.svg index cde1be50..c46888f5 100644 --- a/tests/__snapshots__/sod882d.snap.svg +++ b/tests/__snapshots__/sod882d.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod923.snap.svg b/tests/__snapshots__/sod923.snap.svg index 291147d2..3e0880d4 100644 --- a/tests/__snapshots__/sod923.snap.svg +++ b/tests/__snapshots__/sod923.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/diode.test.ts b/tests/diode.test.ts index d9ae3b7b..7ce9f073 100644 --- a/tests/diode.test.ts +++ b/tests/diode.test.ts @@ -1,5 +1,5 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" +import type { AnyCircuitElement, PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -45,6 +45,26 @@ test("diode2512", () => { expect(svgContent).toMatchSvgSnapshot(import.meta.path, "diode2512") }) +test("diode2512 fabrication uses a narrower symbol", () => { + const circuitJson = fp().diode().imperial("2512").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.4, + ) +}) + test("diode fabrication notes include polarity guidance and cathode direction", () => { const circuitJson = fp().diode().imperial("0603").circuitJson() const pad1 = circuitJson.find( @@ -74,12 +94,96 @@ test("diode fabrication notes include polarity guidance and cathode direction", ) expect(fabricationNotePaths).toHaveLength(5) expect(outlinePath?.route).toHaveLength(5) - expect(leadInPath?.route[0]?.x).toBeGreaterThan(pad1.x + pad1.width / 2) - expect(cathodeBar?.route[0]?.x).toBeLessThan(pad2.x - pad2.width / 2) + expect(leadInPath?.route[0]?.x).toBeGreaterThan(pad1.x) + expect(leadInPath?.route[0]?.x).toBeLessThan(0) + expect(cathodeBar?.route[0]?.x).toBeLessThan(pad2.x) expect(arrowPath?.route[1]?.x).toBeGreaterThan(arrowPath?.route[0]?.x ?? 0) expect(cathodeBar?.route[0]?.x).toBeGreaterThan(0) }) +test("diode fabrication outline reaches pad centers and slightly exceeds pad height", () => { + const circuitJson = fp().diode().imperial("0603").circuitJson() + const pad1 = circuitJson.find( + (element) => + element.type === "pcb_smtpad" && element.port_hints?.[0] === "1", + )! + const pad2 = circuitJson.find( + (element) => + element.type === "pcb_smtpad" && element.port_hints?.[0] === "2", + )! + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + + const xs = outlinePath.route.map((point) => point.x) + const ys = outlinePath.route.map((point) => point.y) + + expect(Math.min(...xs)).toBeCloseTo(pad1.x) + expect(Math.max(...xs)).toBeCloseTo(pad2.x) + expect(Math.max(...ys) - Math.min(...ys)).toBeGreaterThan(pad1.height) + expect(Math.max(...ys) - Math.min(...ys)).toBeLessThan(pad1.height + 0.5) +}) + +test("small-pitch diode fabrication uses more of the available width", () => { + const smallPitchCircuit = fp().diode().imperial("0201").circuitJson() + const regularPitchCircuit = fp().diode().imperial("0603").circuitJson() + + const getSymbolOccupancy = (circuitJson: AnyCircuitElement[]) => { + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + return ( + (Math.max(...arrowXs) - Math.min(...arrowXs)) / + (Math.max(...outlineXs) - Math.min(...outlineXs)) + ) + } + + expect(getSymbolOccupancy(smallPitchCircuit)).toBeGreaterThan( + getSymbolOccupancy(regularPitchCircuit), + ) +}) + +test("small diode fabrication symbols stay slightly narrower", () => { + const getSymbolOccupancy = (circuitJson: AnyCircuitElement[]) => { + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + return ( + (Math.max(...arrowXs) - Math.min(...arrowXs)) / + (Math.max(...outlineXs) - Math.min(...outlineXs)) + ) + } + + expect( + getSymbolOccupancy(fp().diode().imperial("0402").circuitJson()), + ).toBeLessThan(0.445) + expect( + getSymbolOccupancy(fp().diode().imperial("0201").circuitJson()), + ).toBeLessThan(0.575) +}) + test("diode01005 does not include fabrication notes", () => { const circuitJson = fp().diode().imperial("01005").circuitJson() const fabricationNotePaths = circuitJson.filter( diff --git a/tests/kicad-parity/__snapshots__/melf.snap.svg b/tests/kicad-parity/__snapshots__/melf.snap.svg index 0762018b..8393b3ea 100644 --- a/tests/kicad-parity/__snapshots__/melf.snap.svg +++ b/tests/kicad-parity/__snapshots__/melf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/micromelf.snap.svg b/tests/kicad-parity/__snapshots__/micromelf.snap.svg index 51a2897c..4d8a8513 100644 --- a/tests/kicad-parity/__snapshots__/micromelf.snap.svg +++ b/tests/kicad-parity/__snapshots__/micromelf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/minimelf.snap.svg b/tests/kicad-parity/__snapshots__/minimelf.snap.svg index 11af8dc8..765ebe4b 100644 --- a/tests/kicad-parity/__snapshots__/minimelf.snap.svg +++ b/tests/kicad-parity/__snapshots__/minimelf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sma.snap.svg b/tests/kicad-parity/__snapshots__/sma.snap.svg index 988c6b8c..29049756 100644 --- a/tests/kicad-parity/__snapshots__/sma.snap.svg +++ b/tests/kicad-parity/__snapshots__/sma.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/smb.snap.svg b/tests/kicad-parity/__snapshots__/smb.snap.svg index 52ee09e6..3d79c16e 100644 --- a/tests/kicad-parity/__snapshots__/smb.snap.svg +++ b/tests/kicad-parity/__snapshots__/smb.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/smc.snap.svg b/tests/kicad-parity/__snapshots__/smc.snap.svg index fc38cfb0..f47b51bb 100644 --- a/tests/kicad-parity/__snapshots__/smc.snap.svg +++ b/tests/kicad-parity/__snapshots__/smc.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod110.snap.svg b/tests/kicad-parity/__snapshots__/sod110.snap.svg index 6b224a0b..dc7002b9 100644 --- a/tests/kicad-parity/__snapshots__/sod110.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod110.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod123.snap.svg b/tests/kicad-parity/__snapshots__/sod123.snap.svg index a9d0d9ce..feabf377 100644 --- a/tests/kicad-parity/__snapshots__/sod123.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod123.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod123f.snap.svg b/tests/kicad-parity/__snapshots__/sod123f.snap.svg index 9d520ead..10cea2b7 100644 --- a/tests/kicad-parity/__snapshots__/sod123f.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod123f.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod123w.snap.svg b/tests/kicad-parity/__snapshots__/sod123w.snap.svg index 6e43d980..ff81d9a9 100644 --- a/tests/kicad-parity/__snapshots__/sod123w.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod123w.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod128.snap.svg b/tests/kicad-parity/__snapshots__/sod128.snap.svg index 85d7a05f..bbf8b22a 100644 --- a/tests/kicad-parity/__snapshots__/sod128.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod128.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod323.snap.svg b/tests/kicad-parity/__snapshots__/sod323.snap.svg index bdc71bd2..73d0fd42 100644 --- a/tests/kicad-parity/__snapshots__/sod323.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod323.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod323f.snap.svg b/tests/kicad-parity/__snapshots__/sod323f.snap.svg index c33de7b3..42924254 100644 --- a/tests/kicad-parity/__snapshots__/sod323f.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod323f.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod523.snap.svg b/tests/kicad-parity/__snapshots__/sod523.snap.svg index cb5ad740..2aec6862 100644 --- a/tests/kicad-parity/__snapshots__/sod523.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod523.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod882.snap.svg b/tests/kicad-parity/__snapshots__/sod882.snap.svg index b8bdb98d..100254e4 100644 --- a/tests/kicad-parity/__snapshots__/sod882.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod882.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod882d.snap.svg b/tests/kicad-parity/__snapshots__/sod882d.snap.svg index 378b53f5..372f35ea 100644 --- a/tests/kicad-parity/__snapshots__/sod882d.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod882d.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod923.snap.svg b/tests/kicad-parity/__snapshots__/sod923.snap.svg index af342cac..d97b5c2f 100644 --- a/tests/kicad-parity/__snapshots__/sod923.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod923.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/d_0201_0603metric.snap.svg b/tests/kicad-parity/diodes/__snapshots__/d_0201_0603metric.snap.svg index 619e43c8..bb3fee3b 100644 --- a/tests/kicad-parity/diodes/__snapshots__/d_0201_0603metric.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/d_0201_0603metric.snap.svg @@ -1 +1 @@ -{REF}REF** \ No newline at end of file +{REF}REF** \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/melf.snap.svg b/tests/kicad-parity/diodes/__snapshots__/melf.snap.svg index 0762018b..8393b3ea 100644 --- a/tests/kicad-parity/diodes/__snapshots__/melf.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/melf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg b/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg index 51a2897c..4d8a8513 100644 --- a/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/minimelf.snap.svg b/tests/kicad-parity/diodes/__snapshots__/minimelf.snap.svg index 11af8dc8..765ebe4b 100644 --- a/tests/kicad-parity/diodes/__snapshots__/minimelf.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/minimelf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sma.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sma.snap.svg index 988c6b8c..29049756 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sma.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sma.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/smb.snap.svg b/tests/kicad-parity/diodes/__snapshots__/smb.snap.svg index 52ee09e6..3d79c16e 100644 --- a/tests/kicad-parity/diodes/__snapshots__/smb.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/smb.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/smc.snap.svg b/tests/kicad-parity/diodes/__snapshots__/smc.snap.svg index fc38cfb0..f47b51bb 100644 --- a/tests/kicad-parity/diodes/__snapshots__/smc.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/smc.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod110.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod110.snap.svg index 6b224a0b..dc7002b9 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod110.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod110.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod123.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod123.snap.svg index a9d0d9ce..feabf377 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod123.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod123.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod123f.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod123f.snap.svg index 9d520ead..10cea2b7 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod123f.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod123f.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod123w.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod123w.snap.svg index 6e43d980..ff81d9a9 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod123w.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod123w.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod128.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod128.snap.svg index 85d7a05f..bbf8b22a 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod128.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod128.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod323.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod323.snap.svg index bdc71bd2..73d0fd42 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod323.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod323.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod323f.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod323f.snap.svg index c33de7b3..42924254 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod323f.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod323f.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod523.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod523.snap.svg index cb5ad740..2aec6862 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod523.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod523.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod882.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod882.snap.svg index b8bdb98d..100254e4 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod882.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod882.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod882d.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod882d.snap.svg index 378b53f5..372f35ea 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod882d.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod882d.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod923.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod923.snap.svg index af342cac..d97b5c2f 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod923.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod923.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/melf.test.ts b/tests/melf.test.ts index cd0f29a2..0de65451 100644 --- a/tests/melf.test.ts +++ b/tests/melf.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -7,3 +8,33 @@ test("melf", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "melf") }) + +test("melf fabrication uses a narrower symbol", () => { + const circuitJson = fp.string("melf").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.28, + ) +}) + +test("melf fabrication uses a thicker stroke", () => { + const circuitJson = fp.string("melf").circuitJson() + const fabricationPaths = circuitJson.filter( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path", + ) + + expect(fabricationPaths[0]?.stroke_width).toBeGreaterThan(0.07) +}) diff --git a/tests/micromelf.test.ts b/tests/micromelf.test.ts index 91441b1d..1ae006ef 100644 --- a/tests/micromelf.test.ts +++ b/tests/micromelf.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -7,3 +8,44 @@ test("micromelf", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "micromelf") }) + +test("micromelf fabrication uses a slightly taller symbol with longer leads", () => { + const circuitJson = fp.string("micromelf").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const leadInPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_lead_in", + )! + const leadOutPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_lead_out", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const outlineYs = outlinePath.route.map((point) => point.y) + const arrowXs = arrowPath.route.map((point) => point.x) + const arrowYs = arrowPath.route.map((point) => point.y) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, + ) + expect(Math.max(...arrowYs) - Math.min(...arrowYs)).toBeGreaterThan( + (Math.max(...outlineYs) - Math.min(...outlineYs)) * 0.3, + ) + expect( + Math.abs(leadInPath.route[1]!.x - leadInPath.route[0]!.x), + ).toBeGreaterThan(0.14) + expect( + Math.abs(leadOutPath.route[1]!.x - leadOutPath.route[0]!.x), + ).toBeGreaterThan(0.08) +}) diff --git a/tests/minimelf.test.ts b/tests/minimelf.test.ts index 74a2c0d7..634f3b94 100644 --- a/tests/minimelf.test.ts +++ b/tests/minimelf.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -7,3 +8,23 @@ test("minimelf", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "minimelf") }) + +test("minimelf fabrication uses a narrower symbol", () => { + const circuitJson = fp.string("minimelf").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.28, + ) +}) diff --git a/tests/sma.test.ts b/tests/sma.test.ts index b546b0c5..44e87f1f 100644 --- a/tests/sma.test.ts +++ b/tests/sma.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,38 @@ test("sma", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sma") }) + +test("sma fabrication uses a narrower, slightly taller symbol", () => { + const circuitJson = fp.string("sma").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const outlineYs = outlinePath.route.map((point) => point.y) + const arrowXs = arrowPath.route.map((point) => point.x) + const arrowYs = arrowPath.route.map((point) => point.y) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.25, + ) + expect(Math.max(...arrowYs) - Math.min(...arrowYs)).toBeGreaterThan( + (Math.max(...outlineYs) - Math.min(...outlineYs)) * 0.38, + ) +}) + +test("sma fabrication uses a thicker stroke", () => { + const circuitJson = fp.string("sma").circuitJson() + const fabricationPaths = circuitJson.filter( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path", + ) + + expect(fabricationPaths[0]?.stroke_width).toBeGreaterThan(0.07) +}) diff --git a/tests/smb.test.ts b/tests/smb.test.ts index 6096d83d..9944d7b7 100644 --- a/tests/smb.test.ts +++ b/tests/smb.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,38 @@ test("smb", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "smb") }) + +test("smb fabrication uses a narrower, slightly taller symbol", () => { + const circuitJson = fp.string("smb").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const outlineYs = outlinePath.route.map((point) => point.y) + const arrowXs = arrowPath.route.map((point) => point.x) + const arrowYs = arrowPath.route.map((point) => point.y) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.25, + ) + expect(Math.max(...arrowYs) - Math.min(...arrowYs)).toBeGreaterThan( + (Math.max(...outlineYs) - Math.min(...outlineYs)) * 0.38, + ) +}) + +test("smb fabrication uses a thicker stroke", () => { + const circuitJson = fp.string("smb").circuitJson() + const fabricationPaths = circuitJson.filter( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path", + ) + + expect(fabricationPaths[0]?.stroke_width).toBeGreaterThan(0.07) +}) diff --git a/tests/smbf.test.ts b/tests/smbf.test.ts index 0a03e328..bed1cc47 100644 --- a/tests/smbf.test.ts +++ b/tests/smbf.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,23 @@ test("smbf", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "smbf") }) + +test("smbf fabrication uses a narrower symbol", () => { + const circuitJson = fp.string("smbf").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.28, + ) +}) diff --git a/tests/smc.test.ts b/tests/smc.test.ts index e5079872..87e0eac6 100644 --- a/tests/smc.test.ts +++ b/tests/smc.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -7,3 +8,33 @@ test("smc", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "smc") }) + +test("smc fabrication uses a narrower symbol", () => { + const circuitJson = fp.string("smc").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.28, + ) +}) + +test("smc fabrication uses a thicker stroke", () => { + const circuitJson = fp.string("smc").circuitJson() + const fabricationPaths = circuitJson.filter( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path", + ) + + expect(fabricationPaths[0]?.stroke_width).toBeGreaterThan(0.07) +}) diff --git a/tests/smf.test.ts b/tests/smf.test.ts index 7ce631c0..0af5be5c 100644 --- a/tests/smf.test.ts +++ b/tests/smf.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -7,3 +8,23 @@ test("smf", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "smf") }) + +test("smf fabrication uses a narrower symbol", () => { + const circuitJson = fp.string("smf").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.28, + ) +}) diff --git a/tests/sod110.test.ts b/tests/sod110.test.ts index cf0d88f7..8a17185e 100644 --- a/tests/sod110.test.ts +++ b/tests/sod110.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,23 @@ test("sod110", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod110") }) + +test("sod110 fabrication uses a narrower symbol", () => { + const circuitJson = fp.string("sod110").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, + ) +}) diff --git a/tests/sod123.test.ts b/tests/sod123.test.ts index d3028e48..a0f30977 100644 --- a/tests/sod123.test.ts +++ b/tests/sod123.test.ts @@ -31,3 +31,50 @@ test("sod123 fabrication notes include cathode direction symbol", () => { expect(arrowPath?.route[1]?.x).toBeGreaterThan(arrowPath?.route[0]?.x ?? 0) expect(cathodeBar?.route[0]?.x).toBeGreaterThan(0) }) + +test("sod123 fabrication outline reaches pad centers and slightly exceeds pad height", () => { + const circuitJson = fp.string("sod123").circuitJson() + const pad1 = circuitJson.find( + (element) => + element.type === "pcb_smtpad" && element.port_hints?.[0] === "1", + )! + const pad2 = circuitJson.find( + (element) => + element.type === "pcb_smtpad" && element.port_hints?.[0] === "2", + )! + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + + const xs = outlinePath.route.map((point) => point.x) + const ys = outlinePath.route.map((point) => point.y) + + expect(Math.min(...xs)).toBeCloseTo(pad1.x) + expect(Math.max(...xs)).toBeCloseTo(pad2.x) + expect(Math.max(...ys) - Math.min(...ys)).toBeGreaterThan(pad1.height) + expect(Math.max(...ys) - Math.min(...ys)).toBeLessThanOrEqual( + pad1.height + 0.4, + ) +}) + +test("sod123 fabrication uses a narrower symbol", () => { + const circuitJson = fp.string("sod123").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, + ) +}) diff --git a/tests/sod123f.test.ts b/tests/sod123f.test.ts index bf4e5127..3bf5f36e 100644 --- a/tests/sod123f.test.ts +++ b/tests/sod123f.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -7,3 +8,23 @@ test("sod123f", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod123f") }) + +test("sod123f fabrication uses a narrower symbol", () => { + const circuitJson = fp.string("sod123f").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, + ) +}) diff --git a/tests/sod123fl.test.ts b/tests/sod123fl.test.ts index 53f89670..da133bc4 100644 --- a/tests/sod123fl.test.ts +++ b/tests/sod123fl.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,23 @@ test("sod123fl", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod123fl") }) + +test("sod123fl fabrication uses a narrower symbol", () => { + const circuitJson = fp.string("sod123fl").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, + ) +}) diff --git a/tests/sod123w.test.ts b/tests/sod123w.test.ts index f586a2c7..0b8614f5 100644 --- a/tests/sod123w.test.ts +++ b/tests/sod123w.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,23 @@ test("sod123w", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod123w") }) + +test("sod123w fabrication uses a narrower symbol", () => { + const circuitJson = fp.string("sod123w").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, + ) +}) diff --git a/tests/sod128.test.ts b/tests/sod128.test.ts index 6ecb31c8..824d08c3 100644 --- a/tests/sod128.test.ts +++ b/tests/sod128.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,24 @@ test("sod128", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod128") }) + +test("sod128 fabrication keeps the outline width but halves the symbol width", () => { + const circuitJson = fp.string("sod128").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) + const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) + + expect(arrowWidth).toBeLessThan(outlineWidth * 0.3) +}) diff --git a/tests/sod323.test.ts b/tests/sod323.test.ts index 26acd625..1c3233bb 100644 --- a/tests/sod323.test.ts +++ b/tests/sod323.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,40 @@ test("sod323", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod323") }) + +test("sod323 fabrication keeps the outline width but halves the symbol width", () => { + const circuitJson = fp.string("sod323").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const leadInPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_lead_in", + )! + const leadOutPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_lead_out", + )! + + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) + const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) + const leadInWidth = Math.abs(leadInPath.route[1]!.x - leadInPath.route[0]!.x) + const leadOutWidth = Math.abs( + leadOutPath.route[1]!.x - leadOutPath.route[0]!.x, + ) + + expect(arrowWidth).toBeLessThan(outlineWidth * 0.18) + expect(leadInWidth).toBeLessThan(outlineWidth * 0.18) + expect(leadOutWidth).toBeLessThan(outlineWidth * 0.16) +}) diff --git a/tests/sod323f.test.ts b/tests/sod323f.test.ts index 35ae1e61..8ad1f8f9 100644 --- a/tests/sod323f.test.ts +++ b/tests/sod323f.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,40 @@ test("sod323f", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod323f") }) + +test("sod323f fabrication keeps the outline width but halves the symbol width", () => { + const circuitJson = fp.string("sod323f").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const leadInPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_lead_in", + )! + const leadOutPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_lead_out", + )! + + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) + const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) + const leadInWidth = Math.abs(leadInPath.route[1]!.x - leadInPath.route[0]!.x) + const leadOutWidth = Math.abs( + leadOutPath.route[1]!.x - leadOutPath.route[0]!.x, + ) + + expect(arrowWidth).toBeLessThan(outlineWidth * 0.18) + expect(leadInWidth).toBeLessThan(outlineWidth * 0.18) + expect(leadOutWidth).toBeLessThan(outlineWidth * 0.16) +}) diff --git a/tests/sod323fl.test.ts b/tests/sod323fl.test.ts index c8d5d0e9..9091db8d 100644 --- a/tests/sod323fl.test.ts +++ b/tests/sod323fl.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,24 @@ test("sod323fl", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod323fl") }) + +test("sod323fl fabrication keeps the outline width but uses a narrower symbol", () => { + const circuitJson = fp.string("sod323fl").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) + const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) + + expect(arrowWidth).toBeLessThan(outlineWidth * 0.35) +}) diff --git a/tests/sod323w.test.ts b/tests/sod323w.test.ts index 7ee63cf9..7837e54e 100644 --- a/tests/sod323w.test.ts +++ b/tests/sod323w.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,24 @@ test("sod323w", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod323w") }) + +test("sod323w fabrication keeps the outline width but uses a narrower symbol", () => { + const circuitJson = fp.string("sod323w").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) + const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) + + expect(arrowWidth).toBeLessThan(outlineWidth * 0.3) +}) diff --git a/tests/sod523.test.ts b/tests/sod523.test.ts index c3421943..ad50b847 100644 --- a/tests/sod523.test.ts +++ b/tests/sod523.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -7,3 +8,24 @@ test("sod523", () => { const svgContent = convertCircuitJsonToPcbSvg(soup, { showCourtyards: true }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod523") }) + +test("sod523 fabrication keeps the outline width but uses a narrower symbol", () => { + const circuitJson = fp.string("sod523").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) + const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) + + expect(arrowWidth).toBeLessThan(outlineWidth * 0.3) +}) diff --git a/tests/sod80.test.ts b/tests/sod80.test.ts index db66602c..cbeccb47 100644 --- a/tests/sod80.test.ts +++ b/tests/sod80.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,23 @@ test("sod80", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod80") }) + +test("sod80 fabrication uses a narrower symbol", () => { + const circuitJson = fp.string("sod80").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, + ) +}) diff --git a/tests/sod882.test.ts b/tests/sod882.test.ts index d271569f..f7446f51 100644 --- a/tests/sod882.test.ts +++ b/tests/sod882.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,16 @@ test("sod882", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod882") }) + +test("sod882 fabrication outline height is reduced to about two-thirds", () => { + const circuitJson = fp.string("sod882").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const ys = outlinePath.route.map((point) => point.y) + const outlineHeight = Math.max(...ys) - Math.min(...ys) + + expect(outlineHeight).toBeCloseTo(0.6827, 3) +}) diff --git a/tests/sod882d.test.ts b/tests/sod882d.test.ts index f28de450..2afe9c59 100644 --- a/tests/sod882d.test.ts +++ b/tests/sod882d.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -9,3 +10,36 @@ test("sod882d", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod882d") }) + +test("sod882d fabrication outline height is reduced to about two-thirds", () => { + const circuitJson = fp.string("sod882d").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const ys = outlinePath.route.map((point) => point.y) + const outlineHeight = Math.max(...ys) - Math.min(...ys) + + expect(outlineHeight).toBeCloseTo(0.7093, 3) +}) + +test("sod882d fabrication uses a slightly narrower symbol", () => { + const circuitJson = fp.string("sod882d").circuitJson() + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const arrowPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + const outlineXs = outlinePath.route.map((point) => point.x) + const arrowXs = arrowPath.route.map((point) => point.x) + + expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( + (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.52, + ) +}) diff --git a/tests/sod923.test.ts b/tests/sod923.test.ts index 517b7883..820bc072 100644 --- a/tests/sod923.test.ts +++ b/tests/sod923.test.ts @@ -1,4 +1,5 @@ import { test, expect } from "bun:test" +import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -7,3 +8,47 @@ test("sod923", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod923") }) + +test("sod923 fabrication keeps full outline width but uses a narrower symbol", () => { + const circuitJson = fp.string("sod923").circuitJson() + const pad1 = circuitJson.find( + (element) => + element.type === "pcb_smtpad" && element.port_hints?.[0] === "1", + )! + const pad2 = circuitJson.find( + (element) => + element.type === "pcb_smtpad" && element.port_hints?.[0] === "2", + )! + const outlinePath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_outline", + )! + const leadInPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_lead_in", + )! + const leadOutPath = circuitJson.find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_lead_out", + )! + + const outlineXs = outlinePath.route.map((point) => point.x) + const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) + const padCenterSpan = Math.abs(pad2.x - pad1.x) + const arrowXs = circuitJson + .find( + (element): element is PcbFabricationNotePath => + element.type === "pcb_fabrication_note_path" && + element.pcb_fabrication_note_path_id === "diode_symbol_arrow", + )! + .route.map((point) => point.x) + const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) + + expect(outlineWidth).toBeCloseTo(padCenterSpan) + expect(Math.min(...outlineXs)).toBeLessThanOrEqual(leadInPath.route[0]!.x) + expect(Math.max(...outlineXs)).toBeGreaterThanOrEqual(leadOutPath.route[1]!.x) + expect(arrowWidth).toBeLessThan(outlineWidth * 0.42) +}) From 8d4e58e30a5e82a3305224245874271bd611f8cb Mon Sep 17 00:00:00 2001 From: techmannih Date: Fri, 3 Jul 2026 20:17:51 +0530 Subject: [PATCH 3/9] update --- src/fn/micromelf.ts | 15 ++++++++------- tests/__snapshots__/micromelf.snap.svg | 2 +- .../kicad-parity/__snapshots__/micromelf.snap.svg | 2 +- .../diodes/__snapshots__/micromelf.snap.svg | 2 +- tests/micromelf.test.ts | 9 +++++---- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/fn/micromelf.ts b/src/fn/micromelf.ts index 20af346b..ed7770fb 100644 --- a/src/fn/micromelf.ts +++ b/src/fn/micromelf.ts @@ -58,8 +58,8 @@ const createManualDiodeFabricationNotes = (params: { ) const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.2 - tightPitchBoost * 0.04, 0.17, 0.2) - const cathodeBarRatio = clamp(0.12 - tightPitchBoost * 0.02, 0.1, 0.12) + const arrowBaseRatio = clamp(0.22 - tightPitchBoost * 0.04, 0.19, 0.22) + const cathodeBarRatio = clamp(0.14 - tightPitchBoost * 0.02, 0.12, 0.14) const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio const cathodeBarX = leadRightX - direction * usableSymbolWidth * cathodeBarRatio @@ -69,16 +69,17 @@ const createManualDiodeFabricationNotes = (params: { const symbolHalfHeight = clamp( Math.min( - provisionalBodyHeight * (0.27 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.34 + tightPitchBoost * 0.08), + provisionalBodyHeight * (0.28 + tightPitchBoost * 0.05), + usableSymbolWidth * (0.38 + tightPitchBoost * 0.08), ), - 0.12, - provisionalBodyHeight * (0.36 + tightPitchBoost * 0.04), + 0.13, + provisionalBodyHeight * (0.38 + tightPitchBoost * 0.04), ) - const finalBodyHeight = Math.max( + const baseBodyHeight = Math.max( provisionalBodyHeight, symbolHalfHeight * 2 + verticalMargin * 2, ) + const finalBodyHeight = baseBodyHeight * (2 / 3) const topY = y + finalBodyHeight / 2 const bottomY = y - finalBodyHeight / 2 diff --git a/tests/__snapshots__/micromelf.snap.svg b/tests/__snapshots__/micromelf.snap.svg index ccb76934..2c3caa56 100644 --- a/tests/__snapshots__/micromelf.snap.svg +++ b/tests/__snapshots__/micromelf.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/micromelf.snap.svg b/tests/kicad-parity/__snapshots__/micromelf.snap.svg index 4d8a8513..27cbf269 100644 --- a/tests/kicad-parity/__snapshots__/micromelf.snap.svg +++ b/tests/kicad-parity/__snapshots__/micromelf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg b/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg index 4d8a8513..27cbf269 100644 --- a/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/micromelf.test.ts b/tests/micromelf.test.ts index 1ae006ef..c942f78e 100644 --- a/tests/micromelf.test.ts +++ b/tests/micromelf.test.ts @@ -9,7 +9,7 @@ test("micromelf", () => { expect(svgContent).toMatchSvgSnapshot(import.meta.path, "micromelf") }) -test("micromelf fabrication uses a slightly taller symbol with longer leads", () => { +test("micromelf fabrication uses a taller symbol with longer leads and a shorter outline", () => { const circuitJson = fp.string("micromelf").circuitJson() const outlinePath = circuitJson.find( (element): element is PcbFabricationNotePath => @@ -40,12 +40,13 @@ test("micromelf fabrication uses a slightly taller symbol with longer leads", () (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, ) expect(Math.max(...arrowYs) - Math.min(...arrowYs)).toBeGreaterThan( - (Math.max(...outlineYs) - Math.min(...outlineYs)) * 0.3, + (Math.max(...outlineYs) - Math.min(...outlineYs)) * 0.5, ) expect( Math.abs(leadInPath.route[1]!.x - leadInPath.route[0]!.x), - ).toBeGreaterThan(0.14) + ).toBeGreaterThan(0.15) expect( Math.abs(leadOutPath.route[1]!.x - leadOutPath.route[0]!.x), - ).toBeGreaterThan(0.08) + ).toBeGreaterThan(0.09) + expect(Math.max(...outlineYs) - Math.min(...outlineYs)).toBeCloseTo(1.0667, 3) }) From 93ee7dd318094c05f8aeec6e8e51ac66696a0b4d Mon Sep 17 00:00:00 2001 From: techmannih Date: Fri, 3 Jul 2026 20:21:32 +0530 Subject: [PATCH 4/9] update --- src/fn/melf.ts | 2 +- src/fn/micromelf.ts | 2 +- src/fn/minimelf.ts | 2 +- src/fn/sma.ts | 2 +- src/fn/smb.ts | 2 +- src/fn/smbf.ts | 2 +- src/fn/smc.ts | 2 +- src/fn/smf.ts | 2 +- src/fn/sod110.ts | 2 +- src/fn/sod123f.ts | 2 +- src/fn/sod123fl.ts | 2 +- src/fn/sod123w.ts | 2 +- src/fn/sod128.ts | 2 +- src/fn/sod323.ts | 2 +- src/fn/sod323f.ts | 2 +- src/fn/sod323fl.ts | 2 +- src/fn/sod323w.ts | 2 +- src/fn/sod523.ts | 2 +- src/fn/sod80.ts | 2 +- src/fn/sod882.ts | 2 +- src/fn/sod882d.ts | 2 +- src/fn/sod923.ts | 2 +- src/helpers/passive-fn.ts | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/fn/melf.ts b/src/fn/melf.ts index 5c985692..8d303b13 100644 --- a/src/fn/melf.ts +++ b/src/fn/melf.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/micromelf.ts b/src/fn/micromelf.ts index ed7770fb..b00becf0 100644 --- a/src/fn/micromelf.ts +++ b/src/fn/micromelf.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/minimelf.ts b/src/fn/minimelf.ts index 6f450753..337aaf64 100644 --- a/src/fn/minimelf.ts +++ b/src/fn/minimelf.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sma.ts b/src/fn/sma.ts index 8b94e388..59c22b1c 100644 --- a/src/fn/sma.ts +++ b/src/fn/sma.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/smb.ts b/src/fn/smb.ts index 0dc8619d..ae11e802 100644 --- a/src/fn/smb.ts +++ b/src/fn/smb.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/smbf.ts b/src/fn/smbf.ts index 803802dc..962cc486 100644 --- a/src/fn/smbf.ts +++ b/src/fn/smbf.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/smc.ts b/src/fn/smc.ts index d3e84095..1f3d2ec5 100644 --- a/src/fn/smc.ts +++ b/src/fn/smc.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/smf.ts b/src/fn/smf.ts index 53efabee..4de049b9 100644 --- a/src/fn/smf.ts +++ b/src/fn/smf.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod110.ts b/src/fn/sod110.ts index 31d0f25b..d9be5f51 100644 --- a/src/fn/sod110.ts +++ b/src/fn/sod110.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod123f.ts b/src/fn/sod123f.ts index 290ad006..4815c9c2 100644 --- a/src/fn/sod123f.ts +++ b/src/fn/sod123f.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod123fl.ts b/src/fn/sod123fl.ts index aef2ada8..596a7155 100644 --- a/src/fn/sod123fl.ts +++ b/src/fn/sod123fl.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod123w.ts b/src/fn/sod123w.ts index dc15ca97..17c002e4 100644 --- a/src/fn/sod123w.ts +++ b/src/fn/sod123w.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod128.ts b/src/fn/sod128.ts index be596de8..918040fc 100644 --- a/src/fn/sod128.ts +++ b/src/fn/sod128.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod323.ts b/src/fn/sod323.ts index 7620f61f..96c9dcd2 100644 --- a/src/fn/sod323.ts +++ b/src/fn/sod323.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod323f.ts b/src/fn/sod323f.ts index 1b6a4b49..638a8f6e 100644 --- a/src/fn/sod323f.ts +++ b/src/fn/sod323f.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod323fl.ts b/src/fn/sod323fl.ts index 2188bbc3..2d4e1f8f 100644 --- a/src/fn/sod323fl.ts +++ b/src/fn/sod323fl.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod323w.ts b/src/fn/sod323w.ts index e8afdbc2..95c06a0c 100644 --- a/src/fn/sod323w.ts +++ b/src/fn/sod323w.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod523.ts b/src/fn/sod523.ts index cbd24a33..a21b5089 100644 --- a/src/fn/sod523.ts +++ b/src/fn/sod523.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod80.ts b/src/fn/sod80.ts index 8e982843..432b04de 100644 --- a/src/fn/sod80.ts +++ b/src/fn/sod80.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod882.ts b/src/fn/sod882.ts index 5696bb02..0fdfb308 100644 --- a/src/fn/sod882.ts +++ b/src/fn/sod882.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod882d.ts b/src/fn/sod882d.ts index 248ff147..cd0816dd 100644 --- a/src/fn/sod882d.ts +++ b/src/fn/sod882d.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" const clamp = (value: number, min: number, max: number) => diff --git a/src/fn/sod923.ts b/src/fn/sod923.ts index 91194049..7d4a0ebb 100644 --- a/src/fn/sod923.ts +++ b/src/fn/sod923.ts @@ -6,7 +6,7 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, PcbFabricationNotePath } from "circuit-json" +import { length, type PcbFabricationNotePath } from "circuit-json" import { base_def } from "../helpers/zod/base_def" import { createRectUnionOutline } from "src/helpers/rect-union-outline" diff --git a/src/helpers/passive-fn.ts b/src/helpers/passive-fn.ts index 3309b703..95fcdc1e 100644 --- a/src/helpers/passive-fn.ts +++ b/src/helpers/passive-fn.ts @@ -7,7 +7,7 @@ import { rectpad } from "../helpers/rectpad" import mm from "@tscircuit/mm" import { platedhole } from "./platedhole" import { z } from "zod" -import { length, distance, PcbFabricationNotePath } from "circuit-json" +import { length, distance, type PcbFabricationNotePath } from "circuit-json" import { type SilkscreenRef, silkscreenRef } from "./silkscreenRef" import { base_def } from "./zod/base_def" From 15faeb31a98f709cb03a6b9bebe92960fd828c6d Mon Sep 17 00:00:00 2001 From: techmannih Date: Fri, 3 Jul 2026 20:26:25 +0530 Subject: [PATCH 5/9] up --- src/fn/sod923.ts | 4 ++-- tests/__snapshots__/sod923.snap.svg | 2 +- tests/kicad-parity/__snapshots__/sod923.snap.svg | 2 +- tests/kicad-parity/diodes/__snapshots__/sod923.snap.svg | 2 +- tests/sod923.test.ts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/fn/sod923.ts b/src/fn/sod923.ts index 7d4a0ebb..03305c4c 100644 --- a/src/fn/sod923.ts +++ b/src/fn/sod923.ts @@ -59,8 +59,8 @@ const createManualDiodeFabricationNotes = (params: { ) const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.29 - tightPitchBoost * 0.02, 0.26, 0.3) - const cathodeBarRatio = clamp(0.23 - tightPitchBoost * 0.02, 0.2, 0.24) + const arrowBaseRatio = clamp(0.31 - tightPitchBoost * 0.02, 0.28, 0.31) + const cathodeBarRatio = clamp(0.25 - tightPitchBoost * 0.02, 0.22, 0.25) const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio const cathodeBarX = leadRightX - direction * usableSymbolWidth * cathodeBarRatio diff --git a/tests/__snapshots__/sod923.snap.svg b/tests/__snapshots__/sod923.snap.svg index 3e0880d4..b33ccd7e 100644 --- a/tests/__snapshots__/sod923.snap.svg +++ b/tests/__snapshots__/sod923.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod923.snap.svg b/tests/kicad-parity/__snapshots__/sod923.snap.svg index d97b5c2f..7d617587 100644 --- a/tests/kicad-parity/__snapshots__/sod923.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod923.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod923.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod923.snap.svg index d97b5c2f..7d617587 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod923.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod923.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/sod923.test.ts b/tests/sod923.test.ts index 820bc072..1ed65455 100644 --- a/tests/sod923.test.ts +++ b/tests/sod923.test.ts @@ -50,5 +50,5 @@ test("sod923 fabrication keeps full outline width but uses a narrower symbol", ( expect(outlineWidth).toBeCloseTo(padCenterSpan) expect(Math.min(...outlineXs)).toBeLessThanOrEqual(leadInPath.route[0]!.x) expect(Math.max(...outlineXs)).toBeGreaterThanOrEqual(leadOutPath.route[1]!.x) - expect(arrowWidth).toBeLessThan(outlineWidth * 0.42) + expect(arrowWidth).toBeLessThan(outlineWidth * 0.36) }) From f889a18d97ca26c77d9bee9189fa7adda5ae4535 Mon Sep 17 00:00:00 2001 From: techmannih Date: Fri, 3 Jul 2026 20:50:19 +0530 Subject: [PATCH 6/9] up --- package.json | 1 + src/fn/melf.ts | 152 +------ src/fn/micromelf.ts | 153 +------ src/fn/minimelf.ts | 152 +------ src/fn/sma.ts | 152 +------ src/fn/smb.ts | 152 +------ src/fn/smbf.ts | 152 +------ src/fn/smc.ts | 152 +------ src/fn/smf.ts | 152 +------ src/fn/sod110.ts | 152 +------ src/fn/sod123.ts | 156 +------ src/fn/sod123f.ts | 152 +------ src/fn/sod123fl.ts | 152 +------ src/fn/sod123w.ts | 152 +------ src/fn/sod128.ts | 152 +------ src/fn/sod323.ts | 159 +------ src/fn/sod323f.ts | 159 +------ src/fn/sod323fl.ts | 152 +------ src/fn/sod323w.ts | 152 +------ src/fn/sod523.ts | 152 +------ src/fn/sod80.ts | 152 +------ src/fn/sod882.ts | 153 +------ src/fn/sod882d.ts | 153 +------ src/fn/sod923.ts | 152 +------ src/helpers/manual-diode-fabrication.ts | 537 ++++++++++++++++++++++++ src/helpers/passive-fn.ts | 218 +++------- 26 files changed, 733 insertions(+), 3540 deletions(-) create mode 100644 src/helpers/manual-diode-fabrication.ts diff --git a/package.json b/package.json index 6a3a66ba..2b319404 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ }, "dependencies": { "@tscircuit/mm": "^0.0.8", + "transformation-matrix": "^2.16.1", "zod": "^3.23.8" }, "peerDependencies": { diff --git a/src/fn/melf.ts b/src/fn/melf.ts index 8d303b13..f89ab566 100644 --- a/src/fn/melf.ts +++ b/src/fn/melf.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) - const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.075, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const melf_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const melf = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.wideThickStroke, }) // Define silkscreen reference text diff --git a/src/fn/micromelf.ts b/src/fn/micromelf.ts index b00becf0..6ed7bf60 100644 --- a/src/fn/micromelf.ts +++ b/src/fn/micromelf.ts @@ -6,155 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.22 - tightPitchBoost * 0.04, 0.19, 0.22) - const cathodeBarRatio = clamp(0.14 - tightPitchBoost * 0.02, 0.12, 0.14) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.28 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.38 + tightPitchBoost * 0.08), - ), - 0.13, - provisionalBodyHeight * (0.38 + tightPitchBoost * 0.04), - ) - const baseBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const finalBodyHeight = baseBodyHeight * (2 / 3) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const micromelf_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -177,6 +35,7 @@ export const micromelf = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.micromelfCompact, }) // Define silkscreen reference text diff --git a/src/fn/minimelf.ts b/src/fn/minimelf.ts index 337aaf64..ffdecd44 100644 --- a/src/fn/minimelf.ts +++ b/src/fn/minimelf.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) - const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const minimelf_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const minimelf = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.wide, }) // Define silkscreen reference text diff --git a/src/fn/sma.ts b/src/fn/sma.ts index 59c22b1c..0ba93305 100644 --- a/src/fn/sma.ts +++ b/src/fn/sma.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.2, 0.24) - const cathodeBarRatio = clamp(0.16 - tightPitchBoost * 0.02, 0.12, 0.16) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.26 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.31 + tightPitchBoost * 0.08), - ), - 0.11, - provisionalBodyHeight * (0.35 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.075, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sma_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const sma = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.smaLike, }) // Define silkscreen reference text diff --git a/src/fn/smb.ts b/src/fn/smb.ts index ae11e802..48f906c7 100644 --- a/src/fn/smb.ts +++ b/src/fn/smb.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.2, 0.24) - const cathodeBarRatio = clamp(0.16 - tightPitchBoost * 0.02, 0.12, 0.16) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.26 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.31 + tightPitchBoost * 0.08), - ), - 0.11, - provisionalBodyHeight * (0.35 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.075, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const smb_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const smb = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.smaLike, }) // Define silkscreen reference text diff --git a/src/fn/smbf.ts b/src/fn/smbf.ts index 962cc486..ad8d6462 100644 --- a/src/fn/smbf.ts +++ b/src/fn/smbf.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) - const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const smbf_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const smbf = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.wide, }) // Define silkscreen reference text diff --git a/src/fn/smc.ts b/src/fn/smc.ts index 1f3d2ec5..7b7e5ce3 100644 --- a/src/fn/smc.ts +++ b/src/fn/smc.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) - const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.075, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const smc_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const smc = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.wideThickStroke, }) // Define silkscreen reference text diff --git a/src/fn/smf.ts b/src/fn/smf.ts index 4de049b9..e195848c 100644 --- a/src/fn/smf.ts +++ b/src/fn/smf.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(-Math.min(padWidth, padHeight) * 0.03, -0.04, -0.02) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) - const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const smf_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const smf = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.smf, }) // Define silkscreen reference text diff --git a/src/fn/sod110.ts b/src/fn/sod110.ts index d9be5f51..c96ad0ad 100644 --- a/src/fn/sod110.ts +++ b/src/fn/sod110.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.3 - tightPitchBoost * 0.03, 0.24, 0.3) - const cathodeBarRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.18, 0.24) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const sod110 = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod123Wide, }) const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, diff --git a/src/fn/sod123.ts b/src/fn/sod123.ts index 754f1f0f..2ae609a5 100644 --- a/src/fn/sod123.ts +++ b/src/fn/sod123.ts @@ -1,159 +1,14 @@ -import type { - AnyCircuitElement, - PcbCourtyardRect, - PcbFabricationNotePath, -} from "circuit-json" +import type { AnyCircuitElement, PcbCourtyardRect } from "circuit-json" import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.31 - tightPitchBoost * 0.03, 0.25, 0.31) - const cathodeBarRatio = clamp(0.25 - tightPitchBoost * 0.03, 0.19, 0.25) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +31,7 @@ export const sod123 = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod123, }) const silkscreenRefText: SilkscreenRef = silkscreenRef( 0, diff --git a/src/fn/sod123f.ts b/src/fn/sod123f.ts index 4815c9c2..42d441db 100644 --- a/src/fn/sod123f.ts +++ b/src/fn/sod123f.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.3 - tightPitchBoost * 0.03, 0.24, 0.3) - const cathodeBarRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.18, 0.24) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const sod123f = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod123Wide, }) // Define silkscreen reference text diff --git a/src/fn/sod123fl.ts b/src/fn/sod123fl.ts index 596a7155..bc0dd969 100644 --- a/src/fn/sod123fl.ts +++ b/src/fn/sod123fl.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.3 - tightPitchBoost * 0.03, 0.24, 0.3) - const cathodeBarRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.18, 0.24) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod123FL_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const sod123fl = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod123Wide, }) // Define silkscreen reference text diff --git a/src/fn/sod123w.ts b/src/fn/sod123w.ts index 17c002e4..0961b9ee 100644 --- a/src/fn/sod123w.ts +++ b/src/fn/sod123w.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.3 - tightPitchBoost * 0.03, 0.24, 0.3) - const cathodeBarRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.18, 0.24) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const sod123w = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod123Wide, }) // Define silkscreen reference text diff --git a/src/fn/sod128.ts b/src/fn/sod128.ts index 918040fc..e778887f 100644 --- a/src/fn/sod128.ts +++ b/src/fn/sod128.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) - const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const sod128 = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.wide, }) // Define silkscreen reference text diff --git a/src/fn/sod323.ts b/src/fn/sod323.ts index 96c9dcd2..c9aa00e7 100644 --- a/src/fn/sod323.ts +++ b/src/fn/sod323.ts @@ -6,161 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const symbolLeadInsetX = clamp(padDistance * 0.16, 0.14, 0.36) - const symbolLeadLeftX = leadLeftX + direction * symbolLeadInsetX - const symbolLeadRightX = leadRightX - direction * symbolLeadInsetX - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max( - 0.14, - Math.abs(symbolLeadRightX - symbolLeadLeftX), - ) - const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) - const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) - const arrowBaseX = - symbolLeadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - symbolLeadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: symbolLeadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: symbolLeadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -183,6 +35,7 @@ export const sod323 = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod323InsetWide, }) // Define silkscreen reference text diff --git a/src/fn/sod323f.ts b/src/fn/sod323f.ts index 638a8f6e..feaaf162 100644 --- a/src/fn/sod323f.ts +++ b/src/fn/sod323f.ts @@ -6,161 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const symbolLeadInsetX = clamp(padDistance * 0.16, 0.14, 0.36) - const symbolLeadLeftX = leadLeftX + direction * symbolLeadInsetX - const symbolLeadRightX = leadRightX - direction * symbolLeadInsetX - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max( - 0.14, - Math.abs(symbolLeadRightX - symbolLeadLeftX), - ) - const arrowBaseRatio = clamp(0.34 - tightPitchBoost * 0.02, 0.3, 0.34) - const cathodeBarRatio = clamp(0.28 - tightPitchBoost * 0.02, 0.24, 0.28) - const arrowBaseX = - symbolLeadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - symbolLeadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: symbolLeadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: symbolLeadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -183,6 +35,7 @@ export const sod323f = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod323InsetWide, }) // Define silkscreen reference text diff --git a/src/fn/sod323fl.ts b/src/fn/sod323fl.ts index 2d4e1f8f..498a04f6 100644 --- a/src/fn/sod323fl.ts +++ b/src/fn/sod323fl.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.26 - tightPitchBoost * 0.03, 0.2, 0.26) - const cathodeBarRatio = clamp(0.2 - tightPitchBoost * 0.03, 0.14, 0.2) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod323FL_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const sod323fl = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod323Compact, }) // Define silkscreen reference text diff --git a/src/fn/sod323w.ts b/src/fn/sod323w.ts index 95c06a0c..03076450 100644 --- a/src/fn/sod323w.ts +++ b/src/fn/sod323w.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.26 - tightPitchBoost * 0.03, 0.2, 0.26) - const cathodeBarRatio = clamp(0.2 - tightPitchBoost * 0.03, 0.14, 0.2) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod323w_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const sod323w = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod323Compact, }) // Define silkscreen reference text diff --git a/src/fn/sod523.ts b/src/fn/sod523.ts index a21b5089..7c8479d5 100644 --- a/src/fn/sod523.ts +++ b/src/fn/sod523.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.26 - tightPitchBoost * 0.03, 0.2, 0.26) - const cathodeBarRatio = clamp(0.2 - tightPitchBoost * 0.03, 0.14, 0.2) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const sod523 = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod323Compact, }) // Define silkscreen reference text diff --git a/src/fn/sod80.ts b/src/fn/sod80.ts index 432b04de..5a661c89 100644 --- a/src/fn/sod80.ts +++ b/src/fn/sod80.ts @@ -6,154 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.3 - tightPitchBoost * 0.03, 0.24, 0.3) - const cathodeBarRatio = clamp(0.24 - tightPitchBoost * 0.03, 0.18, 0.24) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod80_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -176,6 +35,7 @@ export const sod80 = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod123Wide, }) // Define silkscreen reference text diff --git a/src/fn/sod882.ts b/src/fn/sod882.ts index 0fdfb308..f6f157e2 100644 --- a/src/fn/sod882.ts +++ b/src/fn/sod882.ts @@ -6,155 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.14 - tightPitchBoost * 0.06, 0.06, 0.14) - const cathodeBarRatio = clamp(0.08 - tightPitchBoost * 0.03, 0.03, 0.08) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const baseBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const finalBodyHeight = baseBodyHeight * (2 / 3) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -177,6 +35,7 @@ export const sod882 = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod882Compact, }) // Define silkscreen reference text diff --git a/src/fn/sod882d.ts b/src/fn/sod882d.ts index cd0816dd..3c20bff3 100644 --- a/src/fn/sod882d.ts +++ b/src/fn/sod882d.ts @@ -6,155 +6,13 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.17 - tightPitchBoost * 0.05, 0.12, 0.17) - const cathodeBarRatio = clamp(0.1 - tightPitchBoost * 0.02, 0.07, 0.1) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const baseBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const finalBodyHeight = baseBodyHeight * (2 / 3) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -177,6 +35,7 @@ export const sod882d = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod882dCompact, }) // Define silkscreen reference text diff --git a/src/fn/sod923.ts b/src/fn/sod923.ts index 03305c4c..53ffd79a 100644 --- a/src/fn/sod923.ts +++ b/src/fn/sod923.ts @@ -6,155 +6,14 @@ import type { import { z } from "zod" import { rectpad } from "../helpers/rectpad" import { silkscreenRef, type SilkscreenRef } from "src/helpers/silkscreenRef" -import { length, type PcbFabricationNotePath } from "circuit-json" +import { length } from "circuit-json" +import { + createManualDiodeFabricationNotes, + diodeFabricationTuningPresets, +} from "../helpers/manual-diode-fabrication" import { base_def } from "../helpers/zod/base_def" import { createRectUnionOutline } from "src/helpers/rect-union-outline" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const arrowBaseRatio = clamp(0.31 - tightPitchBoost * 0.02, 0.28, 0.31) - const cathodeBarRatio = clamp(0.25 - tightPitchBoost * 0.02, 0.22, 0.25) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) - - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] - - return [...fabPaths] -} - export const sod_def = base_def.extend({ fn: z.string(), num_pins: z.literal(2).default(2), @@ -177,6 +36,7 @@ export const sod923 = ( padHeight: length.parse(parameters.pw), bodyWidth: length.parse(parameters.w), bodyHeight: length.parse(parameters.h), + tuning: diodeFabricationTuningPresets.sod923, }) const w = length.parse(parameters.w) const h = length.parse(parameters.h) diff --git a/src/helpers/manual-diode-fabrication.ts b/src/helpers/manual-diode-fabrication.ts new file mode 100644 index 00000000..a01bb260 --- /dev/null +++ b/src/helpers/manual-diode-fabrication.ts @@ -0,0 +1,537 @@ +import type { AnyCircuitElement, PcbFabricationNotePath } from "circuit-json" +import { + applyToPoint, + compose, + scale, + type Matrix, + translate, +} from "transformation-matrix" + +const clamp = (value: number, min: number, max: number) => + Math.min(max, Math.max(min, value)) + +const lerp = (from: number, to: number, amount: number) => + from + (to - from) * amount + +type RatioTuning = { + base: number + tightPitchFactor: number + min: number + max: number +} + +type SymbolHalfHeightTuning = { + bodyBase: number + bodyBoost: number + widthBase: number + widthBoost: number + min: number + maxBase: number + maxBoost: number +} + +type StrokeWidthTuning = { + heightFactor: number + widthFactor: number + min: number + max: number +} + +type RoutePoint = { + x: number + y: number +} + +type ResolvedManualDiodeFabricationNoteTuning = { + leadGap: NonNullable + leadInsetFromCenter: NonNullable< + ManualDiodeFabricationNoteTuning["leadInsetFromCenter"] + > + symbolLeadInset: ManualDiodeFabricationNoteTuning["symbolLeadInset"] + usableSymbolWidthMin: number + arrowBaseRatio: RatioTuning + cathodeBarRatio: RatioTuning + symbolHalfHeight: SymbolHalfHeightTuning + outlineHeightScale: number + strokeWidth: StrokeWidthTuning +} + +export type ManualDiodeFabricationNoteTuning = { + leadGap?: { + scale: number + min: number + max: number + } + leadInsetFromCenter?: { + scale: number + min: number + maxScale: number + } + symbolLeadInset?: { + scale: number + min: number + max: number + } + usableSymbolWidthMin?: number + arrowBaseRatio?: RatioTuning + cathodeBarRatio?: RatioTuning + symbolHalfHeight?: SymbolHalfHeightTuning + outlineHeightScale?: number + strokeWidth?: StrokeWidthTuning +} + +export type ManualDiodeFabricationNoteParams = { + pin1PadX: number + pin2PadX: number + padWidth: number + padHeight: number + bodyWidth?: number + bodyHeight?: number + layer?: "top" | "bottom" + y?: number + tuning?: ManualDiodeFabricationNoteTuning +} + +const defaultTuning = { + leadGap: { + scale: 0.05, + min: 0.01, + max: 0.04, + }, + leadInsetFromCenter: { + scale: 0.16, + min: 0.04, + maxScale: 0.32, + }, + usableSymbolWidthMin: 0.2, + arrowBaseRatio: { + base: 0.14, + tightPitchFactor: 0.06, + min: 0.06, + max: 0.14, + }, + cathodeBarRatio: { + base: 0.08, + tightPitchFactor: 0.03, + min: 0.03, + max: 0.08, + }, + symbolHalfHeight: { + bodyBase: 0.24, + bodyBoost: 0.05, + widthBase: 0.28, + widthBoost: 0.08, + min: 0.1, + maxBase: 0.32, + maxBoost: 0.04, + }, + outlineHeightScale: 1, + strokeWidth: { + heightFactor: 0.055, + widthFactor: 0.035, + min: 0.025, + max: 0.06, + }, +} satisfies Omit + +const resolveTuning = ( + tuning?: ManualDiodeFabricationNoteTuning, +): ResolvedManualDiodeFabricationNoteTuning => ({ + leadGap: { ...defaultTuning.leadGap, ...tuning?.leadGap }, + leadInsetFromCenter: { + ...defaultTuning.leadInsetFromCenter, + ...tuning?.leadInsetFromCenter, + }, + symbolLeadInset: tuning?.symbolLeadInset, + usableSymbolWidthMin: + tuning?.usableSymbolWidthMin ?? defaultTuning.usableSymbolWidthMin, + arrowBaseRatio: { + ...defaultTuning.arrowBaseRatio, + ...tuning?.arrowBaseRatio, + }, + cathodeBarRatio: { + ...defaultTuning.cathodeBarRatio, + ...tuning?.cathodeBarRatio, + }, + symbolHalfHeight: { + ...defaultTuning.symbolHalfHeight, + ...tuning?.symbolHalfHeight, + }, + outlineHeightScale: + tuning?.outlineHeightScale ?? defaultTuning.outlineHeightScale, + strokeWidth: { ...defaultTuning.strokeWidth, ...tuning?.strokeWidth }, +}) + +const ratioTuning = ( + base: number, + tightPitchFactor: number, + min: number, + max: number, +): RatioTuning => ({ + base, + tightPitchFactor, + min, + max, +}) + +const symbolHalfHeightTuning = ( + bodyBase: number, + bodyBoost: number, + widthBase: number, + widthBoost: number, + min: number, + maxBase: number, + maxBoost: number, +): SymbolHalfHeightTuning => ({ + bodyBase, + bodyBoost, + widthBase, + widthBoost, + min, + maxBase, + maxBoost, +}) + +const wideRatios = { + arrowBaseRatio: ratioTuning(0.34, 0.02, 0.3, 0.34), + cathodeBarRatio: ratioTuning(0.28, 0.02, 0.24, 0.28), +} satisfies Pick< + ManualDiodeFabricationNoteTuning, + "arrowBaseRatio" | "cathodeBarRatio" +> + +const smaLikeSymbolHalfHeight = { + symbolHalfHeight: symbolHalfHeightTuning( + 0.26, + 0.05, + 0.31, + 0.08, + 0.11, + 0.35, + 0.04, + ), +} satisfies Pick + +const compactOutline = { + outlineHeightScale: 2 / 3, +} satisfies Pick + +const thickStroke = { + strokeWidth: { + max: 0.075, + }, +} satisfies Pick + +const centeredOutlineTemplate: RoutePoint[] = [ + { x: -0.5, y: 0.5 }, + { x: 0.5, y: 0.5 }, + { x: 0.5, y: -0.5 }, + { x: -0.5, y: -0.5 }, + { x: -0.5, y: 0.5 }, +] + +const normalizedLeadTemplate: RoutePoint[] = [ + { x: 0, y: 0 }, + { x: 1, y: 0 }, +] + +const normalizedArrowTemplate: RoutePoint[] = [ + { x: 0, y: -1 }, + { x: 1, y: 0 }, + { x: 0, y: 1 }, + { x: 0, y: -1 }, +] + +const normalizedCathodeBarTemplate: RoutePoint[] = [ + { x: 0, y: -1.15 }, + { x: 0, y: 1.15 }, +] + +const transformRoute = (matrix: Matrix, route: RoutePoint[]): RoutePoint[] => + route.map((point) => applyToPoint(matrix, point)) + +const createFabPath = ( + pcb_fabrication_note_path_id: string, + route: RoutePoint[], + stroke_width: number, + layer: "top" | "bottom", + pcb_component_id = "", +): PcbFabricationNotePath => ({ + type: "pcb_fabrication_note_path", + pcb_fabrication_note_path_id, + pcb_component_id, + layer, + route, + stroke_width, +}) + +const createTransformedFabPath = ( + pcb_fabrication_note_path_id: string, + template: RoutePoint[], + matrix: Matrix, + stroke_width: number, + layer: "top" | "bottom", + pcb_component_id = "", +): PcbFabricationNotePath => + createFabPath( + pcb_fabrication_note_path_id, + transformRoute(matrix, template), + stroke_width, + layer, + pcb_component_id, + ) + +const createScaledFabPath = ( + pcb_fabrication_note_path_id: string, + template: RoutePoint[], + x: number, + y: number, + scaleX: number, + scaleY: number, + stroke_width: number, + layer: "top" | "bottom", + pcb_component_id = "", +): PcbFabricationNotePath => + createTransformedFabPath( + pcb_fabrication_note_path_id, + template, + compose(translate(x, y), scale(scaleX, scaleY)), + stroke_width, + layer, + pcb_component_id, + ) + +export const diodeFabricationTuningPresets = { + wide: wideRatios, + wideThickStroke: { + ...wideRatios, + ...thickStroke, + }, + smf: { + leadGap: { + scale: -0.03, + min: -0.04, + max: -0.02, + }, + ...wideRatios, + }, + smaLike: { + arrowBaseRatio: ratioTuning(0.24, 0.03, 0.2, 0.24), + cathodeBarRatio: ratioTuning(0.16, 0.02, 0.12, 0.16), + ...smaLikeSymbolHalfHeight, + ...thickStroke, + }, + sod323Compact: { + arrowBaseRatio: ratioTuning(0.26, 0.03, 0.2, 0.26), + cathodeBarRatio: ratioTuning(0.2, 0.03, 0.14, 0.2), + }, + sod323InsetWide: { + symbolLeadInset: { + scale: 0.16, + min: 0.14, + max: 0.36, + }, + usableSymbolWidthMin: 0.14, + ...wideRatios, + }, + sod123Wide: { + arrowBaseRatio: ratioTuning(0.3, 0.03, 0.24, 0.3), + cathodeBarRatio: ratioTuning(0.24, 0.03, 0.18, 0.24), + }, + sod123: { + arrowBaseRatio: ratioTuning(0.31, 0.03, 0.25, 0.31), + cathodeBarRatio: ratioTuning(0.25, 0.03, 0.19, 0.25), + }, + sod923: { + arrowBaseRatio: ratioTuning(0.31, 0.02, 0.28, 0.31), + cathodeBarRatio: ratioTuning(0.25, 0.02, 0.22, 0.25), + }, + sod882Compact: compactOutline, + sod882dCompact: { + arrowBaseRatio: ratioTuning(0.17, 0.05, 0.12, 0.17), + cathodeBarRatio: ratioTuning(0.1, 0.02, 0.07, 0.1), + ...compactOutline, + }, + micromelfCompact: { + arrowBaseRatio: ratioTuning(0.22, 0.04, 0.19, 0.22), + cathodeBarRatio: ratioTuning(0.14, 0.02, 0.12, 0.14), + symbolHalfHeight: symbolHalfHeightTuning( + 0.28, + 0.05, + 0.38, + 0.08, + 0.13, + 0.38, + 0.04, + ), + ...compactOutline, + }, +} satisfies Record + +export const createManualDiodeFabricationNotes = ( + params: ManualDiodeFabricationNoteParams, +): AnyCircuitElement[] => { + const { + pin1PadX, + pin2PadX, + padWidth, + padHeight, + bodyHeight, + layer = "top", + y = 0, + tuning, + } = params + + const resolvedTuning = resolveTuning(tuning) + const direction = pin2PadX >= pin1PadX ? 1 : -1 + const padDistance = Math.abs(pin2PadX - pin1PadX) + const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) + + const leadGap = clamp( + Math.min(padWidth, padHeight) * resolvedTuning.leadGap.scale, + resolvedTuning.leadGap.min, + resolvedTuning.leadGap.max, + ) + const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) + const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) + const leadInsetFromCenter = clamp( + padWidth * resolvedTuning.leadInsetFromCenter.scale, + resolvedTuning.leadInsetFromCenter.min, + padWidth * resolvedTuning.leadInsetFromCenter.maxScale, + ) + const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter + const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter + const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) + const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) + + let symbolLeadLeftX = leadLeftX + let symbolLeadRightX = leadRightX + if (resolvedTuning.symbolLeadInset) { + const symbolLeadInsetX = clamp( + padDistance * resolvedTuning.symbolLeadInset.scale, + resolvedTuning.symbolLeadInset.min, + resolvedTuning.symbolLeadInset.max, + ) + symbolLeadLeftX = leadLeftX + direction * symbolLeadInsetX + symbolLeadRightX = leadRightX - direction * symbolLeadInsetX + } + + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) + const verticalMargin = clamp( + Math.min( + padHeight * (0.18 + tightPitchBoost * 0.12), + (bodyHeight ?? computedBodyHeight) * 0.18, + ), + 0.03, + 0.2, + ) + const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) + const usableSymbolWidth = Math.max( + resolvedTuning.usableSymbolWidthMin, + Math.abs(symbolLeadRightX - symbolLeadLeftX), + ) + const arrowBaseRatio = clamp( + resolvedTuning.arrowBaseRatio.base - + tightPitchBoost * resolvedTuning.arrowBaseRatio.tightPitchFactor, + resolvedTuning.arrowBaseRatio.min, + resolvedTuning.arrowBaseRatio.max, + ) + const cathodeBarRatio = clamp( + resolvedTuning.cathodeBarRatio.base - + tightPitchBoost * resolvedTuning.cathodeBarRatio.tightPitchFactor, + resolvedTuning.cathodeBarRatio.min, + resolvedTuning.cathodeBarRatio.max, + ) + const arrowBaseX = + symbolLeadLeftX + direction * usableSymbolWidth * arrowBaseRatio + const cathodeBarX = + symbolLeadRightX - direction * usableSymbolWidth * cathodeBarRatio + const leftX = Math.min(pin1PadX, pin2PadX) + const rightX = Math.max(pin1PadX, pin2PadX) + const finalBodyWidth = rightX - leftX + + const symbolHalfHeight = clamp( + Math.min( + provisionalBodyHeight * + (resolvedTuning.symbolHalfHeight.bodyBase + + tightPitchBoost * resolvedTuning.symbolHalfHeight.bodyBoost), + usableSymbolWidth * + (resolvedTuning.symbolHalfHeight.widthBase + + tightPitchBoost * resolvedTuning.symbolHalfHeight.widthBoost), + ), + resolvedTuning.symbolHalfHeight.min, + provisionalBodyHeight * + (resolvedTuning.symbolHalfHeight.maxBase + + tightPitchBoost * resolvedTuning.symbolHalfHeight.maxBoost), + ) + const baseBodyHeight = Math.max( + provisionalBodyHeight, + symbolHalfHeight * 2 + verticalMargin * 2, + ) + const finalBodyHeight = baseBodyHeight * resolvedTuning.outlineHeightScale + + const strokeWidth = clamp( + Math.min( + finalBodyHeight * resolvedTuning.strokeWidth.heightFactor, + finalBodyWidth * resolvedTuning.strokeWidth.widthFactor, + ), + resolvedTuning.strokeWidth.min, + resolvedTuning.strokeWidth.max, + ) + + const fabPaths: PcbFabricationNotePath[] = [ + createScaledFabPath( + "diode_symbol_outline", + centeredOutlineTemplate, + (leftX + rightX) / 2, + y, + finalBodyWidth, + finalBodyHeight, + strokeWidth, + layer, + ), + createScaledFabPath( + "diode_symbol_lead_in", + normalizedLeadTemplate, + symbolLeadLeftX, + y, + arrowBaseX - symbolLeadLeftX, + 1, + strokeWidth, + layer, + ), + createScaledFabPath( + "diode_symbol_arrow", + normalizedArrowTemplate, + arrowBaseX, + y, + cathodeBarX - arrowBaseX, + symbolHalfHeight, + strokeWidth, + layer, + ), + createScaledFabPath( + "diode_symbol_cathode_bar", + normalizedCathodeBarTemplate, + cathodeBarX, + y, + 1, + symbolHalfHeight, + strokeWidth, + layer, + "pin_2", + ), + createScaledFabPath( + "diode_symbol_lead_out", + normalizedLeadTemplate, + cathodeBarX, + y, + symbolLeadRightX - cathodeBarX, + 1, + strokeWidth, + layer, + ), + ] + + return [...fabPaths] +} diff --git a/src/helpers/passive-fn.ts b/src/helpers/passive-fn.ts index 95fcdc1e..bb09b184 100644 --- a/src/helpers/passive-fn.ts +++ b/src/helpers/passive-fn.ts @@ -7,171 +7,67 @@ import { rectpad } from "../helpers/rectpad" import mm from "@tscircuit/mm" import { platedhole } from "./platedhole" import { z } from "zod" -import { length, distance, type PcbFabricationNotePath } from "circuit-json" +import { length, distance } from "circuit-json" import { type SilkscreenRef, silkscreenRef } from "./silkscreenRef" +import { + createManualDiodeFabricationNotes, + type ManualDiodeFabricationNoteTuning, +} from "./manual-diode-fabrication" import { base_def } from "./zod/base_def" -const clamp = (value: number, min: number, max: number) => - Math.min(max, Math.max(min, value)) - -const lerp = (from: number, to: number, amount: number) => - from + (to - from) * amount - -const createManualDiodeFabricationNotes = (params: { - pin1PadX: number - pin2PadX: number - padWidth: number - padHeight: number - bodyWidth?: number - bodyHeight?: number - footprintSize?: string - layer?: "top" | "bottom" - y?: number -}): AnyCircuitElement[] => { - const { - pin1PadX, - pin2PadX, - padWidth, - padHeight, - bodyHeight, - footprintSize, - layer = "top", - y = 0, - } = params - - const direction = pin2PadX >= pin1PadX ? 1 : -1 - const padDistance = Math.abs(pin2PadX - pin1PadX) - const tightPitchBoost = clamp((1.3 - padDistance) / 0.75, 0, 1) - - const leadGap = clamp(Math.min(padWidth, padHeight) * 0.05, 0.01, 0.04) - const leadEdgeLeftX = pin1PadX + direction * (padWidth / 2 + leadGap) - const leadEdgeRightX = pin2PadX - direction * (padWidth / 2 + leadGap) - const leadInsetFromCenter = clamp(padWidth * 0.16, 0.04, padWidth * 0.32) - const leadHalfPadLeftX = pin1PadX + direction * leadInsetFromCenter - const leadHalfPadRightX = pin2PadX - direction * leadInsetFromCenter - const leadLeftX = lerp(leadEdgeLeftX, leadHalfPadLeftX, tightPitchBoost) - const leadRightX = lerp(leadEdgeRightX, leadHalfPadRightX, tightPitchBoost) - const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) - const verticalMargin = clamp( - Math.min( - padHeight * (0.18 + tightPitchBoost * 0.12), - (bodyHeight ?? computedBodyHeight) * 0.18, - ), - 0.03, - 0.2, - ) - const provisionalBodyHeight = Math.max(padHeight + verticalMargin * 2, 0.18) - const usableSymbolWidth = Math.max(0.2, Math.abs(leadRightX - leadLeftX)) - const usesSlightlyNarrower0201Symbol = footprintSize === "0201" - const usesSlightlyNarrower0402Symbol = footprintSize === "0402" - const arrowBaseRatio = - footprintSize === "2512" - ? clamp(0.3 - tightPitchBoost * 0.03, 0.27, 0.3) - : usesSlightlyNarrower0201Symbol - ? clamp(0.18 - tightPitchBoost * 0.055, 0.12, 0.18) - : usesSlightlyNarrower0402Symbol - ? clamp(0.16 - tightPitchBoost * 0.06, 0.1, 0.16) - : clamp(0.14 - tightPitchBoost * 0.06, 0.06, 0.14) - const cathodeBarRatio = - footprintSize === "2512" - ? clamp(0.22 - tightPitchBoost * 0.02, 0.2, 0.22) - : usesSlightlyNarrower0201Symbol - ? clamp(0.11 - tightPitchBoost * 0.03, 0.07, 0.11) - : usesSlightlyNarrower0402Symbol - ? clamp(0.1 - tightPitchBoost * 0.03, 0.06, 0.1) - : clamp(0.08 - tightPitchBoost * 0.03, 0.03, 0.08) - const arrowBaseX = leadLeftX + direction * usableSymbolWidth * arrowBaseRatio - const cathodeBarX = - leadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) - const finalBodyWidth = rightX - leftX - - const symbolHalfHeight = clamp( - Math.min( - provisionalBodyHeight * (0.24 + tightPitchBoost * 0.05), - usableSymbolWidth * (0.28 + tightPitchBoost * 0.08), - ), - 0.1, - provisionalBodyHeight * (0.32 + tightPitchBoost * 0.04), - ) - const finalBodyHeight = Math.max( - provisionalBodyHeight, - symbolHalfHeight * 2 + verticalMargin * 2, - ) - const topY = y + finalBodyHeight / 2 - const bottomY = y - finalBodyHeight / 2 - - const strokeWidth = clamp( - Math.min(finalBodyHeight * 0.055, finalBodyWidth * 0.035), - 0.025, - 0.06, - ) +const getPassiveDiodeFabricationTuning = ( + footprintSize?: string, +): ManualDiodeFabricationNoteTuning | undefined => { + if (footprintSize === "2512") { + return { + arrowBaseRatio: { + base: 0.3, + tightPitchFactor: 0.03, + min: 0.27, + max: 0.3, + }, + cathodeBarRatio: { + base: 0.22, + tightPitchFactor: 0.02, + min: 0.2, + max: 0.22, + }, + } + } - const fabPaths: PcbFabricationNotePath[] = [ - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_outline", - pcb_component_id: "", - layer, - route: [ - { x: leftX, y: topY }, - { x: rightX, y: topY }, - { x: rightX, y: bottomY }, - { x: leftX, y: bottomY }, - { x: leftX, y: topY }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_in", - pcb_component_id: "", - layer, - route: [ - { x: leadLeftX, y }, - { x: arrowBaseX, y }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_arrow", - pcb_component_id: "", - layer, - route: [ - { x: arrowBaseX, y: y - symbolHalfHeight }, - { x: cathodeBarX, y }, - { x: arrowBaseX, y: y + symbolHalfHeight }, - { x: arrowBaseX, y: y - symbolHalfHeight }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_cathode_bar", - pcb_component_id: "pin_2", - layer, - route: [ - { x: cathodeBarX, y: y - symbolHalfHeight * 1.15 }, - { x: cathodeBarX, y: y + symbolHalfHeight * 1.15 }, - ], - stroke_width: strokeWidth, - }, - { - type: "pcb_fabrication_note_path", - pcb_fabrication_note_path_id: "diode_symbol_lead_out", - pcb_component_id: "", - layer, - route: [ - { x: cathodeBarX, y }, - { x: leadRightX, y }, - ], - stroke_width: strokeWidth, - }, - ] + if (footprintSize === "0201") { + return { + arrowBaseRatio: { + base: 0.18, + tightPitchFactor: 0.055, + min: 0.12, + max: 0.18, + }, + cathodeBarRatio: { + base: 0.11, + tightPitchFactor: 0.03, + min: 0.07, + max: 0.11, + }, + } + } - return [...fabPaths] + if (footprintSize === "0402") { + return { + arrowBaseRatio: { + base: 0.16, + tightPitchFactor: 0.06, + min: 0.1, + max: 0.16, + }, + cathodeBarRatio: { + base: 0.1, + tightPitchFactor: 0.03, + min: 0.06, + max: 0.1, + }, + } + } } type StandardSize = { @@ -506,7 +402,7 @@ export const passive = (params: PassiveDef): AnyCircuitElement[] => { padHeight: ph, bodyWidth: w, bodyHeight: h, - footprintSize: sz?.imperial, + tuning: getPassiveDiodeFabricationTuning(sz?.imperial), }) : [] From f9eb67e41591e80c4e77f6493c1ae49c8f4e356d Mon Sep 17 00:00:00 2001 From: techmannih Date: Fri, 3 Jul 2026 20:56:09 +0530 Subject: [PATCH 7/9] up --- tests/diode.test.ts | 150 ---------------------------------------- tests/melf.test.ts | 31 --------- tests/micromelf.test.ts | 43 ------------ tests/minimelf.test.ts | 21 ------ tests/sma.test.ts | 36 ---------- tests/smb.test.ts | 36 ---------- tests/smbf.test.ts | 21 ------ tests/smc.test.ts | 31 --------- tests/smf.test.ts | 21 ------ tests/sod110.test.ts | 21 ------ tests/sod123.test.ts | 71 ------------------- tests/sod123f.test.ts | 21 ------ tests/sod123fl.test.ts | 21 ------ tests/sod123w.test.ts | 21 ------ tests/sod128.test.ts | 22 ------ tests/sod323.test.ts | 38 ---------- tests/sod323f.test.ts | 38 ---------- tests/sod323fl.test.ts | 22 ------ tests/sod323w.test.ts | 22 ------ tests/sod523.test.ts | 22 ------ tests/sod723.test.ts | 11 --- tests/sod80.test.ts | 21 ------ tests/sod882.test.ts | 14 ---- tests/sod882d.test.ts | 34 --------- tests/sod923.test.ts | 45 ------------ 25 files changed, 834 deletions(-) diff --git a/tests/diode.test.ts b/tests/diode.test.ts index 7ce9f073..f0281745 100644 --- a/tests/diode.test.ts +++ b/tests/diode.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { AnyCircuitElement, PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -44,152 +43,3 @@ test("diode2512", () => { const svgContent = convertCircuitJsonToPcbSvg(soup) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "diode2512") }) - -test("diode2512 fabrication uses a narrower symbol", () => { - const circuitJson = fp().diode().imperial("2512").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.4, - ) -}) - -test("diode fabrication notes include polarity guidance and cathode direction", () => { - const circuitJson = fp().diode().imperial("0603").circuitJson() - const pad1 = circuitJson.find( - (element) => - element.type === "pcb_smtpad" && element.port_hints?.[0] === "1", - )! - const pad2 = circuitJson.find( - (element) => - element.type === "pcb_smtpad" && element.port_hints?.[0] === "2", - )! - - const fabricationNotePaths = circuitJson.filter( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path", - ) - const arrowPath = fabricationNotePaths.find( - (path) => path.pcb_fabrication_note_path_id === "diode_symbol_arrow", - ) - const cathodeBar = fabricationNotePaths.find( - (path) => path.pcb_fabrication_note_path_id === "diode_symbol_cathode_bar", - ) - const outlinePath = fabricationNotePaths.find( - (path) => path.pcb_fabrication_note_path_id === "diode_symbol_outline", - ) - const leadInPath = fabricationNotePaths.find( - (path) => path.pcb_fabrication_note_path_id === "diode_symbol_lead_in", - ) - expect(fabricationNotePaths).toHaveLength(5) - expect(outlinePath?.route).toHaveLength(5) - expect(leadInPath?.route[0]?.x).toBeGreaterThan(pad1.x) - expect(leadInPath?.route[0]?.x).toBeLessThan(0) - expect(cathodeBar?.route[0]?.x).toBeLessThan(pad2.x) - expect(arrowPath?.route[1]?.x).toBeGreaterThan(arrowPath?.route[0]?.x ?? 0) - expect(cathodeBar?.route[0]?.x).toBeGreaterThan(0) -}) - -test("diode fabrication outline reaches pad centers and slightly exceeds pad height", () => { - const circuitJson = fp().diode().imperial("0603").circuitJson() - const pad1 = circuitJson.find( - (element) => - element.type === "pcb_smtpad" && element.port_hints?.[0] === "1", - )! - const pad2 = circuitJson.find( - (element) => - element.type === "pcb_smtpad" && element.port_hints?.[0] === "2", - )! - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - - const xs = outlinePath.route.map((point) => point.x) - const ys = outlinePath.route.map((point) => point.y) - - expect(Math.min(...xs)).toBeCloseTo(pad1.x) - expect(Math.max(...xs)).toBeCloseTo(pad2.x) - expect(Math.max(...ys) - Math.min(...ys)).toBeGreaterThan(pad1.height) - expect(Math.max(...ys) - Math.min(...ys)).toBeLessThan(pad1.height + 0.5) -}) - -test("small-pitch diode fabrication uses more of the available width", () => { - const smallPitchCircuit = fp().diode().imperial("0201").circuitJson() - const regularPitchCircuit = fp().diode().imperial("0603").circuitJson() - - const getSymbolOccupancy = (circuitJson: AnyCircuitElement[]) => { - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - return ( - (Math.max(...arrowXs) - Math.min(...arrowXs)) / - (Math.max(...outlineXs) - Math.min(...outlineXs)) - ) - } - - expect(getSymbolOccupancy(smallPitchCircuit)).toBeGreaterThan( - getSymbolOccupancy(regularPitchCircuit), - ) -}) - -test("small diode fabrication symbols stay slightly narrower", () => { - const getSymbolOccupancy = (circuitJson: AnyCircuitElement[]) => { - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - return ( - (Math.max(...arrowXs) - Math.min(...arrowXs)) / - (Math.max(...outlineXs) - Math.min(...outlineXs)) - ) - } - - expect( - getSymbolOccupancy(fp().diode().imperial("0402").circuitJson()), - ).toBeLessThan(0.445) - expect( - getSymbolOccupancy(fp().diode().imperial("0201").circuitJson()), - ).toBeLessThan(0.575) -}) - -test("diode01005 does not include fabrication notes", () => { - const circuitJson = fp().diode().imperial("01005").circuitJson() - const fabricationNotePaths = circuitJson.filter( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path", - ) - - expect(fabricationNotePaths).toHaveLength(0) -}) diff --git a/tests/melf.test.ts b/tests/melf.test.ts index 0de65451..cd0f29a2 100644 --- a/tests/melf.test.ts +++ b/tests/melf.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -8,33 +7,3 @@ test("melf", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "melf") }) - -test("melf fabrication uses a narrower symbol", () => { - const circuitJson = fp.string("melf").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.28, - ) -}) - -test("melf fabrication uses a thicker stroke", () => { - const circuitJson = fp.string("melf").circuitJson() - const fabricationPaths = circuitJson.filter( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path", - ) - - expect(fabricationPaths[0]?.stroke_width).toBeGreaterThan(0.07) -}) diff --git a/tests/micromelf.test.ts b/tests/micromelf.test.ts index c942f78e..91441b1d 100644 --- a/tests/micromelf.test.ts +++ b/tests/micromelf.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -8,45 +7,3 @@ test("micromelf", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "micromelf") }) - -test("micromelf fabrication uses a taller symbol with longer leads and a shorter outline", () => { - const circuitJson = fp.string("micromelf").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const leadInPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_lead_in", - )! - const leadOutPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_lead_out", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const outlineYs = outlinePath.route.map((point) => point.y) - const arrowXs = arrowPath.route.map((point) => point.x) - const arrowYs = arrowPath.route.map((point) => point.y) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, - ) - expect(Math.max(...arrowYs) - Math.min(...arrowYs)).toBeGreaterThan( - (Math.max(...outlineYs) - Math.min(...outlineYs)) * 0.5, - ) - expect( - Math.abs(leadInPath.route[1]!.x - leadInPath.route[0]!.x), - ).toBeGreaterThan(0.15) - expect( - Math.abs(leadOutPath.route[1]!.x - leadOutPath.route[0]!.x), - ).toBeGreaterThan(0.09) - expect(Math.max(...outlineYs) - Math.min(...outlineYs)).toBeCloseTo(1.0667, 3) -}) diff --git a/tests/minimelf.test.ts b/tests/minimelf.test.ts index 634f3b94..74a2c0d7 100644 --- a/tests/minimelf.test.ts +++ b/tests/minimelf.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -8,23 +7,3 @@ test("minimelf", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "minimelf") }) - -test("minimelf fabrication uses a narrower symbol", () => { - const circuitJson = fp.string("minimelf").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.28, - ) -}) diff --git a/tests/sma.test.ts b/tests/sma.test.ts index 44e87f1f..b546b0c5 100644 --- a/tests/sma.test.ts +++ b/tests/sma.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,38 +9,3 @@ test("sma", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sma") }) - -test("sma fabrication uses a narrower, slightly taller symbol", () => { - const circuitJson = fp.string("sma").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const outlineYs = outlinePath.route.map((point) => point.y) - const arrowXs = arrowPath.route.map((point) => point.x) - const arrowYs = arrowPath.route.map((point) => point.y) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.25, - ) - expect(Math.max(...arrowYs) - Math.min(...arrowYs)).toBeGreaterThan( - (Math.max(...outlineYs) - Math.min(...outlineYs)) * 0.38, - ) -}) - -test("sma fabrication uses a thicker stroke", () => { - const circuitJson = fp.string("sma").circuitJson() - const fabricationPaths = circuitJson.filter( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path", - ) - - expect(fabricationPaths[0]?.stroke_width).toBeGreaterThan(0.07) -}) diff --git a/tests/smb.test.ts b/tests/smb.test.ts index 9944d7b7..6096d83d 100644 --- a/tests/smb.test.ts +++ b/tests/smb.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,38 +9,3 @@ test("smb", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "smb") }) - -test("smb fabrication uses a narrower, slightly taller symbol", () => { - const circuitJson = fp.string("smb").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const outlineYs = outlinePath.route.map((point) => point.y) - const arrowXs = arrowPath.route.map((point) => point.x) - const arrowYs = arrowPath.route.map((point) => point.y) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.25, - ) - expect(Math.max(...arrowYs) - Math.min(...arrowYs)).toBeGreaterThan( - (Math.max(...outlineYs) - Math.min(...outlineYs)) * 0.38, - ) -}) - -test("smb fabrication uses a thicker stroke", () => { - const circuitJson = fp.string("smb").circuitJson() - const fabricationPaths = circuitJson.filter( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path", - ) - - expect(fabricationPaths[0]?.stroke_width).toBeGreaterThan(0.07) -}) diff --git a/tests/smbf.test.ts b/tests/smbf.test.ts index bed1cc47..0a03e328 100644 --- a/tests/smbf.test.ts +++ b/tests/smbf.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,23 +9,3 @@ test("smbf", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "smbf") }) - -test("smbf fabrication uses a narrower symbol", () => { - const circuitJson = fp.string("smbf").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.28, - ) -}) diff --git a/tests/smc.test.ts b/tests/smc.test.ts index 87e0eac6..e5079872 100644 --- a/tests/smc.test.ts +++ b/tests/smc.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -8,33 +7,3 @@ test("smc", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "smc") }) - -test("smc fabrication uses a narrower symbol", () => { - const circuitJson = fp.string("smc").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.28, - ) -}) - -test("smc fabrication uses a thicker stroke", () => { - const circuitJson = fp.string("smc").circuitJson() - const fabricationPaths = circuitJson.filter( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path", - ) - - expect(fabricationPaths[0]?.stroke_width).toBeGreaterThan(0.07) -}) diff --git a/tests/smf.test.ts b/tests/smf.test.ts index 0af5be5c..7ce631c0 100644 --- a/tests/smf.test.ts +++ b/tests/smf.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -8,23 +7,3 @@ test("smf", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "smf") }) - -test("smf fabrication uses a narrower symbol", () => { - const circuitJson = fp.string("smf").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.28, - ) -}) diff --git a/tests/sod110.test.ts b/tests/sod110.test.ts index 8a17185e..cf0d88f7 100644 --- a/tests/sod110.test.ts +++ b/tests/sod110.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,23 +9,3 @@ test("sod110", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod110") }) - -test("sod110 fabrication uses a narrower symbol", () => { - const circuitJson = fp.string("sod110").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, - ) -}) diff --git a/tests/sod123.test.ts b/tests/sod123.test.ts index a0f30977..fd2b7ad1 100644 --- a/tests/sod123.test.ts +++ b/tests/sod123.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -8,73 +7,3 @@ test("sod123", () => { const svgContent = convertCircuitJsonToPcbSvg(soup) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod123") }) - -test("sod123 fabrication notes include cathode direction symbol", () => { - const circuitJson = fp.string("sod123").circuitJson() - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - ) - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - ) - const cathodeBar = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_cathode_bar", - ) - - expect(outlinePath?.route).toHaveLength(5) - expect(arrowPath?.route[1]?.x).toBeGreaterThan(arrowPath?.route[0]?.x ?? 0) - expect(cathodeBar?.route[0]?.x).toBeGreaterThan(0) -}) - -test("sod123 fabrication outline reaches pad centers and slightly exceeds pad height", () => { - const circuitJson = fp.string("sod123").circuitJson() - const pad1 = circuitJson.find( - (element) => - element.type === "pcb_smtpad" && element.port_hints?.[0] === "1", - )! - const pad2 = circuitJson.find( - (element) => - element.type === "pcb_smtpad" && element.port_hints?.[0] === "2", - )! - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - - const xs = outlinePath.route.map((point) => point.x) - const ys = outlinePath.route.map((point) => point.y) - - expect(Math.min(...xs)).toBeCloseTo(pad1.x) - expect(Math.max(...xs)).toBeCloseTo(pad2.x) - expect(Math.max(...ys) - Math.min(...ys)).toBeGreaterThan(pad1.height) - expect(Math.max(...ys) - Math.min(...ys)).toBeLessThanOrEqual( - pad1.height + 0.4, - ) -}) - -test("sod123 fabrication uses a narrower symbol", () => { - const circuitJson = fp.string("sod123").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, - ) -}) diff --git a/tests/sod123f.test.ts b/tests/sod123f.test.ts index 3bf5f36e..bf4e5127 100644 --- a/tests/sod123f.test.ts +++ b/tests/sod123f.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -8,23 +7,3 @@ test("sod123f", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod123f") }) - -test("sod123f fabrication uses a narrower symbol", () => { - const circuitJson = fp.string("sod123f").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, - ) -}) diff --git a/tests/sod123fl.test.ts b/tests/sod123fl.test.ts index da133bc4..53f89670 100644 --- a/tests/sod123fl.test.ts +++ b/tests/sod123fl.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,23 +9,3 @@ test("sod123fl", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod123fl") }) - -test("sod123fl fabrication uses a narrower symbol", () => { - const circuitJson = fp.string("sod123fl").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, - ) -}) diff --git a/tests/sod123w.test.ts b/tests/sod123w.test.ts index 0b8614f5..f586a2c7 100644 --- a/tests/sod123w.test.ts +++ b/tests/sod123w.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,23 +9,3 @@ test("sod123w", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod123w") }) - -test("sod123w fabrication uses a narrower symbol", () => { - const circuitJson = fp.string("sod123w").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, - ) -}) diff --git a/tests/sod128.test.ts b/tests/sod128.test.ts index 824d08c3..6ecb31c8 100644 --- a/tests/sod128.test.ts +++ b/tests/sod128.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,24 +9,3 @@ test("sod128", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod128") }) - -test("sod128 fabrication keeps the outline width but halves the symbol width", () => { - const circuitJson = fp.string("sod128").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) - const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) - - expect(arrowWidth).toBeLessThan(outlineWidth * 0.3) -}) diff --git a/tests/sod323.test.ts b/tests/sod323.test.ts index 1c3233bb..26acd625 100644 --- a/tests/sod323.test.ts +++ b/tests/sod323.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,40 +9,3 @@ test("sod323", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod323") }) - -test("sod323 fabrication keeps the outline width but halves the symbol width", () => { - const circuitJson = fp.string("sod323").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const leadInPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_lead_in", - )! - const leadOutPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_lead_out", - )! - - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) - const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) - const leadInWidth = Math.abs(leadInPath.route[1]!.x - leadInPath.route[0]!.x) - const leadOutWidth = Math.abs( - leadOutPath.route[1]!.x - leadOutPath.route[0]!.x, - ) - - expect(arrowWidth).toBeLessThan(outlineWidth * 0.18) - expect(leadInWidth).toBeLessThan(outlineWidth * 0.18) - expect(leadOutWidth).toBeLessThan(outlineWidth * 0.16) -}) diff --git a/tests/sod323f.test.ts b/tests/sod323f.test.ts index 8ad1f8f9..35ae1e61 100644 --- a/tests/sod323f.test.ts +++ b/tests/sod323f.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,40 +9,3 @@ test("sod323f", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod323f") }) - -test("sod323f fabrication keeps the outline width but halves the symbol width", () => { - const circuitJson = fp.string("sod323f").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const leadInPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_lead_in", - )! - const leadOutPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_lead_out", - )! - - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) - const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) - const leadInWidth = Math.abs(leadInPath.route[1]!.x - leadInPath.route[0]!.x) - const leadOutWidth = Math.abs( - leadOutPath.route[1]!.x - leadOutPath.route[0]!.x, - ) - - expect(arrowWidth).toBeLessThan(outlineWidth * 0.18) - expect(leadInWidth).toBeLessThan(outlineWidth * 0.18) - expect(leadOutWidth).toBeLessThan(outlineWidth * 0.16) -}) diff --git a/tests/sod323fl.test.ts b/tests/sod323fl.test.ts index 9091db8d..c8d5d0e9 100644 --- a/tests/sod323fl.test.ts +++ b/tests/sod323fl.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,24 +9,3 @@ test("sod323fl", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod323fl") }) - -test("sod323fl fabrication keeps the outline width but uses a narrower symbol", () => { - const circuitJson = fp.string("sod323fl").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) - const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) - - expect(arrowWidth).toBeLessThan(outlineWidth * 0.35) -}) diff --git a/tests/sod323w.test.ts b/tests/sod323w.test.ts index 7837e54e..7ee63cf9 100644 --- a/tests/sod323w.test.ts +++ b/tests/sod323w.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,24 +9,3 @@ test("sod323w", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod323w") }) - -test("sod323w fabrication keeps the outline width but uses a narrower symbol", () => { - const circuitJson = fp.string("sod323w").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) - const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) - - expect(arrowWidth).toBeLessThan(outlineWidth * 0.3) -}) diff --git a/tests/sod523.test.ts b/tests/sod523.test.ts index ad50b847..c3421943 100644 --- a/tests/sod523.test.ts +++ b/tests/sod523.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -8,24 +7,3 @@ test("sod523", () => { const svgContent = convertCircuitJsonToPcbSvg(soup, { showCourtyards: true }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod523") }) - -test("sod523 fabrication keeps the outline width but uses a narrower symbol", () => { - const circuitJson = fp.string("sod523").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) - const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) - - expect(arrowWidth).toBeLessThan(outlineWidth * 0.3) -}) diff --git a/tests/sod723.test.ts b/tests/sod723.test.ts index d56642d5..b546611c 100644 --- a/tests/sod723.test.ts +++ b/tests/sod723.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,13 +9,3 @@ test("sod723", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod723") }) - -test("sod723 does not include fabrication notes", () => { - const circuitJson = fp.string("sod723").circuitJson() - const fabricationNotePaths = circuitJson.filter( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path", - ) - - expect(fabricationNotePaths).toHaveLength(0) -}) diff --git a/tests/sod80.test.ts b/tests/sod80.test.ts index cbeccb47..db66602c 100644 --- a/tests/sod80.test.ts +++ b/tests/sod80.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,23 +9,3 @@ test("sod80", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod80") }) - -test("sod80 fabrication uses a narrower symbol", () => { - const circuitJson = fp.string("sod80").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.34, - ) -}) diff --git a/tests/sod882.test.ts b/tests/sod882.test.ts index f7446f51..d271569f 100644 --- a/tests/sod882.test.ts +++ b/tests/sod882.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,16 +9,3 @@ test("sod882", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod882") }) - -test("sod882 fabrication outline height is reduced to about two-thirds", () => { - const circuitJson = fp.string("sod882").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const ys = outlinePath.route.map((point) => point.y) - const outlineHeight = Math.max(...ys) - Math.min(...ys) - - expect(outlineHeight).toBeCloseTo(0.6827, 3) -}) diff --git a/tests/sod882d.test.ts b/tests/sod882d.test.ts index 2afe9c59..f28de450 100644 --- a/tests/sod882d.test.ts +++ b/tests/sod882d.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -10,36 +9,3 @@ test("sod882d", () => { }) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod882d") }) - -test("sod882d fabrication outline height is reduced to about two-thirds", () => { - const circuitJson = fp.string("sod882d").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const ys = outlinePath.route.map((point) => point.y) - const outlineHeight = Math.max(...ys) - Math.min(...ys) - - expect(outlineHeight).toBeCloseTo(0.7093, 3) -}) - -test("sod882d fabrication uses a slightly narrower symbol", () => { - const circuitJson = fp.string("sod882d").circuitJson() - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const arrowPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - const outlineXs = outlinePath.route.map((point) => point.x) - const arrowXs = arrowPath.route.map((point) => point.x) - - expect(Math.max(...arrowXs) - Math.min(...arrowXs)).toBeLessThan( - (Math.max(...outlineXs) - Math.min(...outlineXs)) * 0.52, - ) -}) diff --git a/tests/sod923.test.ts b/tests/sod923.test.ts index 1ed65455..517b7883 100644 --- a/tests/sod923.test.ts +++ b/tests/sod923.test.ts @@ -1,5 +1,4 @@ import { test, expect } from "bun:test" -import type { PcbFabricationNotePath } from "circuit-json" import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" import { fp } from "../src/footprinter" @@ -8,47 +7,3 @@ test("sod923", () => { const svgContent = convertCircuitJsonToPcbSvg(circuitJson) expect(svgContent).toMatchSvgSnapshot(import.meta.path, "sod923") }) - -test("sod923 fabrication keeps full outline width but uses a narrower symbol", () => { - const circuitJson = fp.string("sod923").circuitJson() - const pad1 = circuitJson.find( - (element) => - element.type === "pcb_smtpad" && element.port_hints?.[0] === "1", - )! - const pad2 = circuitJson.find( - (element) => - element.type === "pcb_smtpad" && element.port_hints?.[0] === "2", - )! - const outlinePath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_outline", - )! - const leadInPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_lead_in", - )! - const leadOutPath = circuitJson.find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_lead_out", - )! - - const outlineXs = outlinePath.route.map((point) => point.x) - const outlineWidth = Math.max(...outlineXs) - Math.min(...outlineXs) - const padCenterSpan = Math.abs(pad2.x - pad1.x) - const arrowXs = circuitJson - .find( - (element): element is PcbFabricationNotePath => - element.type === "pcb_fabrication_note_path" && - element.pcb_fabrication_note_path_id === "diode_symbol_arrow", - )! - .route.map((point) => point.x) - const arrowWidth = Math.max(...arrowXs) - Math.min(...arrowXs) - - expect(outlineWidth).toBeCloseTo(padCenterSpan) - expect(Math.min(...outlineXs)).toBeLessThanOrEqual(leadInPath.route[0]!.x) - expect(Math.max(...outlineXs)).toBeGreaterThanOrEqual(leadOutPath.route[1]!.x) - expect(arrowWidth).toBeLessThan(outlineWidth * 0.36) -}) From e4e8d2913c9ad1d69e5e5c89e1f5fa4f2af147c6 Mon Sep 17 00:00:00 2001 From: techmannih Date: Fri, 3 Jul 2026 20:56:13 +0530 Subject: [PATCH 8/9] up --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b319404..b856db5f 100644 --- a/package.json +++ b/package.json @@ -35,13 +35,13 @@ "react": "^19.0.0", "react-dom": "^19.0.0", "schematic-symbols": "^0.0.224", + "transformation-matrix": "^2.16.1", "ts-node": "^10.9.2", "tsup": "^8.0.2", "typescript": "^5.4.5" }, "dependencies": { "@tscircuit/mm": "^0.0.8", - "transformation-matrix": "^2.16.1", "zod": "^3.23.8" }, "peerDependencies": { From 3f71e8707750d3314502dd97daf6e4ca17ae135b Mon Sep 17 00:00:00 2001 From: techmannih Date: Fri, 3 Jul 2026 21:15:21 +0530 Subject: [PATCH 9/9] up --- src/helpers/manual-diode-fabrication.ts | 56 +++++++++++++++++-- src/helpers/passive-fn.ts | 5 ++ tests/__snapshots__/diode0201.snap.svg | 2 +- tests/__snapshots__/micromelf.snap.svg | 2 +- tests/__snapshots__/sma.snap.svg | 2 +- tests/__snapshots__/smb.snap.svg | 2 +- tests/__snapshots__/sod882.snap.svg | 2 +- tests/__snapshots__/sod882d.snap.svg | 2 +- .../__snapshots__/micromelf.snap.svg | 2 +- tests/kicad-parity/__snapshots__/sma.snap.svg | 2 +- tests/kicad-parity/__snapshots__/smb.snap.svg | 2 +- .../__snapshots__/sod882.snap.svg | 2 +- .../__snapshots__/sod882d.snap.svg | 2 +- .../__snapshots__/d_0201_0603metric.snap.svg | 2 +- .../diodes/__snapshots__/micromelf.snap.svg | 2 +- .../diodes/__snapshots__/sma.snap.svg | 2 +- .../diodes/__snapshots__/smb.snap.svg | 2 +- .../diodes/__snapshots__/sod882.snap.svg | 2 +- .../diodes/__snapshots__/sod882d.snap.svg | 2 +- tsup.config.ts | 9 +++ 20 files changed, 81 insertions(+), 23 deletions(-) create mode 100644 tsup.config.ts diff --git a/src/helpers/manual-diode-fabrication.ts b/src/helpers/manual-diode-fabrication.ts index a01bb260..e510c665 100644 --- a/src/helpers/manual-diode-fabrication.ts +++ b/src/helpers/manual-diode-fabrication.ts @@ -37,6 +37,12 @@ type StrokeWidthTuning = { max: number } +type LeadLineExtensionTuning = { + scale: number + min: number + max: number +} + type RoutePoint = { x: number y: number @@ -48,6 +54,7 @@ type ResolvedManualDiodeFabricationNoteTuning = { ManualDiodeFabricationNoteTuning["leadInsetFromCenter"] > symbolLeadInset: ManualDiodeFabricationNoteTuning["symbolLeadInset"] + leadLineExtension: LeadLineExtensionTuning usableSymbolWidthMin: number arrowBaseRatio: RatioTuning cathodeBarRatio: RatioTuning @@ -72,6 +79,11 @@ export type ManualDiodeFabricationNoteTuning = { min: number max: number } + leadLineExtension?: { + scale: number + min: number + max: number + } usableSymbolWidthMin?: number arrowBaseRatio?: RatioTuning cathodeBarRatio?: RatioTuning @@ -103,6 +115,11 @@ const defaultTuning = { min: 0.04, maxScale: 0.32, }, + leadLineExtension: { + scale: 0, + min: 0, + max: 0, + }, usableSymbolWidthMin: 0.2, arrowBaseRatio: { base: 0.14, @@ -143,6 +160,10 @@ const resolveTuning = ( ...tuning?.leadInsetFromCenter, }, symbolLeadInset: tuning?.symbolLeadInset, + leadLineExtension: { + ...defaultTuning.leadLineExtension, + ...tuning?.leadLineExtension, + }, usableSymbolWidthMin: tuning?.usableSymbolWidthMin ?? defaultTuning.usableSymbolWidthMin, arrowBaseRatio: { @@ -222,6 +243,15 @@ const thickStroke = { }, } satisfies Pick +const extendLeadLines = (scaleFactor: number, min: number, max: number) => + ({ + leadLineExtension: { + scale: scaleFactor, + min, + max, + }, + }) satisfies Pick + const centeredOutlineTemplate: RoutePoint[] = [ { x: -0.5, y: 0.5 }, { x: 0.5, y: 0.5 }, @@ -319,6 +349,7 @@ export const diodeFabricationTuningPresets = { arrowBaseRatio: ratioTuning(0.24, 0.03, 0.2, 0.24), cathodeBarRatio: ratioTuning(0.16, 0.02, 0.12, 0.16), ...smaLikeSymbolHalfHeight, + ...extendLeadLines(0.12, 0.22, 0.3), ...thickStroke, }, sod323Compact: { @@ -346,11 +377,15 @@ export const diodeFabricationTuningPresets = { arrowBaseRatio: ratioTuning(0.31, 0.02, 0.28, 0.31), cathodeBarRatio: ratioTuning(0.25, 0.02, 0.22, 0.25), }, - sod882Compact: compactOutline, + sod882Compact: { + ...compactOutline, + ...extendLeadLines(0.18, 0.05, 0.07), + }, sod882dCompact: { arrowBaseRatio: ratioTuning(0.17, 0.05, 0.12, 0.17), cathodeBarRatio: ratioTuning(0.1, 0.02, 0.07, 0.1), ...compactOutline, + ...extendLeadLines(0.18, 0.04, 0.06), }, micromelfCompact: { arrowBaseRatio: ratioTuning(0.22, 0.04, 0.19, 0.22), @@ -365,6 +400,7 @@ export const diodeFabricationTuningPresets = { 0.04, ), ...compactOutline, + ...extendLeadLines(0.12, 0.05, 0.08), }, } satisfies Record @@ -416,6 +452,14 @@ export const createManualDiodeFabricationNotes = ( symbolLeadRightX = leadRightX - direction * symbolLeadInsetX } + const leadLineExtensionX = clamp( + padWidth * resolvedTuning.leadLineExtension.scale, + resolvedTuning.leadLineExtension.min, + resolvedTuning.leadLineExtension.max, + ) + const leadLineLeftX = symbolLeadLeftX - direction * leadLineExtensionX + const leadLineRightX = symbolLeadRightX + direction * leadLineExtensionX + const computedBodyHeight = Math.max(padHeight * 1.35, 0.9) const verticalMargin = clamp( Math.min( @@ -446,8 +490,8 @@ export const createManualDiodeFabricationNotes = ( symbolLeadLeftX + direction * usableSymbolWidth * arrowBaseRatio const cathodeBarX = symbolLeadRightX - direction * usableSymbolWidth * cathodeBarRatio - const leftX = Math.min(pin1PadX, pin2PadX) - const rightX = Math.max(pin1PadX, pin2PadX) + const leftX = Math.min(pin1PadX, pin2PadX) - leadLineExtensionX + const rightX = Math.max(pin1PadX, pin2PadX) + leadLineExtensionX const finalBodyWidth = rightX - leftX const symbolHalfHeight = clamp( @@ -493,9 +537,9 @@ export const createManualDiodeFabricationNotes = ( createScaledFabPath( "diode_symbol_lead_in", normalizedLeadTemplate, - symbolLeadLeftX, + leadLineLeftX, y, - arrowBaseX - symbolLeadLeftX, + arrowBaseX - leadLineLeftX, 1, strokeWidth, layer, @@ -526,7 +570,7 @@ export const createManualDiodeFabricationNotes = ( normalizedLeadTemplate, cathodeBarX, y, - symbolLeadRightX - cathodeBarX, + leadLineRightX - cathodeBarX, 1, strokeWidth, layer, diff --git a/src/helpers/passive-fn.ts b/src/helpers/passive-fn.ts index bb09b184..5f89abf8 100644 --- a/src/helpers/passive-fn.ts +++ b/src/helpers/passive-fn.ts @@ -49,6 +49,11 @@ const getPassiveDiodeFabricationTuning = ( min: 0.07, max: 0.11, }, + leadLineExtension: { + scale: 0.18, + min: 0.04, + max: 0.06, + }, } } diff --git a/tests/__snapshots__/diode0201.snap.svg b/tests/__snapshots__/diode0201.snap.svg index 624163b5..93ecf185 100644 --- a/tests/__snapshots__/diode0201.snap.svg +++ b/tests/__snapshots__/diode0201.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/micromelf.snap.svg b/tests/__snapshots__/micromelf.snap.svg index 2c3caa56..96ed40ec 100644 --- a/tests/__snapshots__/micromelf.snap.svg +++ b/tests/__snapshots__/micromelf.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sma.snap.svg b/tests/__snapshots__/sma.snap.svg index b78ad431..3cf67f3b 100644 --- a/tests/__snapshots__/sma.snap.svg +++ b/tests/__snapshots__/sma.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/smb.snap.svg b/tests/__snapshots__/smb.snap.svg index f7315138..97ec03ac 100644 --- a/tests/__snapshots__/smb.snap.svg +++ b/tests/__snapshots__/smb.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod882.snap.svg b/tests/__snapshots__/sod882.snap.svg index 9ef1a9b6..f9d6eea5 100644 --- a/tests/__snapshots__/sod882.snap.svg +++ b/tests/__snapshots__/sod882.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/__snapshots__/sod882d.snap.svg b/tests/__snapshots__/sod882d.snap.svg index c46888f5..24de8e37 100644 --- a/tests/__snapshots__/sod882d.snap.svg +++ b/tests/__snapshots__/sod882d.snap.svg @@ -1 +1 @@ -{REF} \ No newline at end of file +{REF} \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/micromelf.snap.svg b/tests/kicad-parity/__snapshots__/micromelf.snap.svg index 27cbf269..44562e41 100644 --- a/tests/kicad-parity/__snapshots__/micromelf.snap.svg +++ b/tests/kicad-parity/__snapshots__/micromelf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sma.snap.svg b/tests/kicad-parity/__snapshots__/sma.snap.svg index 29049756..d120f8b8 100644 --- a/tests/kicad-parity/__snapshots__/sma.snap.svg +++ b/tests/kicad-parity/__snapshots__/sma.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/smb.snap.svg b/tests/kicad-parity/__snapshots__/smb.snap.svg index 3d79c16e..c462a671 100644 --- a/tests/kicad-parity/__snapshots__/smb.snap.svg +++ b/tests/kicad-parity/__snapshots__/smb.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod882.snap.svg b/tests/kicad-parity/__snapshots__/sod882.snap.svg index 100254e4..dcadcbc2 100644 --- a/tests/kicad-parity/__snapshots__/sod882.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod882.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/__snapshots__/sod882d.snap.svg b/tests/kicad-parity/__snapshots__/sod882d.snap.svg index 372f35ea..49ce0f8d 100644 --- a/tests/kicad-parity/__snapshots__/sod882d.snap.svg +++ b/tests/kicad-parity/__snapshots__/sod882d.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/d_0201_0603metric.snap.svg b/tests/kicad-parity/diodes/__snapshots__/d_0201_0603metric.snap.svg index bb3fee3b..67061052 100644 --- a/tests/kicad-parity/diodes/__snapshots__/d_0201_0603metric.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/d_0201_0603metric.snap.svg @@ -1 +1 @@ -{REF}REF** \ No newline at end of file +{REF}REF** \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg b/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg index 27cbf269..44562e41 100644 --- a/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/micromelf.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sma.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sma.snap.svg index 29049756..d120f8b8 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sma.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sma.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/smb.snap.svg b/tests/kicad-parity/diodes/__snapshots__/smb.snap.svg index 3d79c16e..c462a671 100644 --- a/tests/kicad-parity/diodes/__snapshots__/smb.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/smb.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod882.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod882.snap.svg index 100254e4..dcadcbc2 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod882.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod882.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tests/kicad-parity/diodes/__snapshots__/sod882d.snap.svg b/tests/kicad-parity/diodes/__snapshots__/sod882d.snap.svg index 372f35ea..49ce0f8d 100644 --- a/tests/kicad-parity/diodes/__snapshots__/sod882d.snap.svg +++ b/tests/kicad-parity/diodes/__snapshots__/sod882d.snap.svg @@ -1 +1 @@ -{REF}REF**Diff: 0.00% \ No newline at end of file +{REF}REF**Diff: 0.00% \ No newline at end of file diff --git a/tsup.config.ts b/tsup.config.ts new file mode 100644 index 00000000..34d450a4 --- /dev/null +++ b/tsup.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from "tsup" + +export default defineConfig({ + entry: ["src/index.ts"], + format: ["esm"], + dts: true, + sourcemap: true, + noExternal: ["transformation-matrix"], +})