@tscircuit/core 0.0.73 → 0.0.75

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/index.js +9 -4
  2. package/package.json +3 -5
  3. package/index.ts +0 -1
  4. package/lib/Project.ts +0 -131
  5. package/lib/components/base-components/NormalComponent.ts +0 -419
  6. package/lib/components/base-components/PrimitiveComponent.ts +0 -478
  7. package/lib/components/base-components/Renderable.ts +0 -126
  8. package/lib/components/index.ts +0 -25
  9. package/lib/components/normal-components/Board.ts +0 -49
  10. package/lib/components/normal-components/Capacitor.ts +0 -70
  11. package/lib/components/normal-components/Chip.ts +0 -98
  12. package/lib/components/normal-components/Diode.ts +0 -27
  13. package/lib/components/normal-components/Jumper.ts +0 -101
  14. package/lib/components/normal-components/Led.ts +0 -27
  15. package/lib/components/normal-components/Resistor.ts +0 -59
  16. package/lib/components/primitive-components/Constraint.ts +0 -91
  17. package/lib/components/primitive-components/FabricationNotePath.ts +0 -50
  18. package/lib/components/primitive-components/FabricationNoteText.ts +0 -26
  19. package/lib/components/primitive-components/Footprint.ts +0 -239
  20. package/lib/components/primitive-components/Group.ts +0 -42
  21. package/lib/components/primitive-components/Hole.ts +0 -65
  22. package/lib/components/primitive-components/Keepout.ts +0 -58
  23. package/lib/components/primitive-components/Net.ts +0 -171
  24. package/lib/components/primitive-components/PlatedHole.ts +0 -116
  25. package/lib/components/primitive-components/Port.ts +0 -236
  26. package/lib/components/primitive-components/SilkscreenPath.ts +0 -48
  27. package/lib/components/primitive-components/SilkscreenText.ts +0 -25
  28. package/lib/components/primitive-components/SmtPad.ts +0 -162
  29. package/lib/components/primitive-components/Trace.ts +0 -635
  30. package/lib/components/primitive-components/TraceHint.ts +0 -71
  31. package/lib/fiber/catalogue.ts +0 -22
  32. package/lib/fiber/create-instance-from-react-element.ts +0 -179
  33. package/lib/fiber/intrinsic-jsx.ts +0 -48
  34. package/lib/index.ts +0 -5
  35. package/lib/register-catalogue.ts +0 -12
  36. package/lib/soup/underscorifyPinStyles.ts +0 -25
  37. package/lib/soup/underscorifyPortArrangement.ts +0 -51
  38. package/lib/utils/autorouting/SimpleRouteJson.ts +0 -48
  39. package/lib/utils/autorouting/computeObstacleBounds.ts +0 -10
  40. package/lib/utils/autorouting/findPossibleTraceLayerCombinations.ts +0 -102
  41. package/lib/utils/autorouting/mergeRoutes.ts +0 -71
  42. package/lib/utils/components/createNetsFromProps.ts +0 -15
  43. package/lib/utils/constants.ts +0 -35
  44. package/lib/utils/createComponentsFromSoup.ts +0 -79
  45. package/lib/utils/extend-aliases.ts +0 -12
  46. package/lib/utils/get-bounds-of-pcb-components.ts +0 -41
  47. package/lib/utils/get-relative-direction.ts +0 -14
  48. package/lib/utils/getClosest.ts +0 -35
  49. package/lib/utils/getPortFromHints.ts +0 -10
  50. package/lib/utils/pairs.ts +0 -10
  51. package/lib/utils/projectPointInDirection.ts +0 -18
  52. package/lib/utils/range.ts +0 -8
  53. package/lib/utils/schematic/getAllDimensionsForSchematicBox.ts +0 -330
  54. package/lib/utils/schematic/getSizeOfSidesFromPortArrangement.ts +0 -47
  55. package/lib/utils/selector-matching/index.ts +0 -2
  56. package/lib/utils/selector-matching/is-matching-path-selector.ts +0 -32
  57. package/lib/utils/selector-matching/is-matching-selector.ts +0 -64
  58. package/lib/utils/try-now.ts +0 -7
@@ -1,239 +0,0 @@
1
- import type { footprintProps } from "@tscircuit/props"
2
- import { PrimitiveComponent } from "../base-components/PrimitiveComponent"
3
- import type { Constraint } from "./Constraint"
4
- import * as kiwi from "@lume/kiwi"
5
- import Debug from "debug"
6
-
7
- const debug = Debug("tscircuit:core:footprint")
8
-
9
- export class Footprint extends PrimitiveComponent<typeof footprintProps> {
10
- /**
11
- * A footprint is a constrainedlayout, the db elements are adjusted according
12
- * to any constraints that are defined.
13
- */
14
- doInitialPcbFootprintLayout() {
15
- const constraints = this.children.filter(
16
- (child) => child.componentName === "Constraint",
17
- ) as Constraint[]
18
-
19
- if (constraints.length === 0) return
20
-
21
- const involvedComponents = constraints
22
- .flatMap(
23
- (constraint) =>
24
- constraint._getAllReferencedComponents().componentsWithSelectors,
25
- )
26
- .map(({ component, selector, componentSelector, edge }) => ({
27
- component,
28
- selector,
29
- componentSelector,
30
- edge,
31
- bounds: component._getPcbCircuitJsonBounds(),
32
- }))
33
-
34
- if (involvedComponents.some((c) => c.edge)) {
35
- throw new Error(
36
- "edge constraints not implemented yet for footprint layout, contributions welcome!",
37
- )
38
- }
39
-
40
- function getComponentDetails(selector: string) {
41
- return involvedComponents.find(({ selector: s }) => s === selector)
42
- }
43
-
44
- const solver = new kiwi.Solver()
45
-
46
- const kVars: { [varName: string]: kiwi.Variable } = {}
47
- function getKVar(name: string) {
48
- if (!(name in kVars)) {
49
- kVars[name] = new kiwi.Variable(name)
50
- solver.addEditVariable(kVars[name], kiwi.Strength.weak)
51
- }
52
- return kVars[name]
53
- }
54
-
55
- // 1. Create kiwi variables to represent each component's center
56
- for (const { selector, bounds } of involvedComponents) {
57
- const kvx = getKVar(`${selector}_x`)
58
- const kvy = getKVar(`${selector}_y`)
59
- solver.suggestValue(kvx, bounds.center.x)
60
- solver.suggestValue(kvy, bounds.center.y)
61
- }
62
-
63
- // 2. Add kiwi constraints using the parsed constraint properties
64
- for (const constraint of constraints) {
65
- const props = constraint._parsedProps
66
-
67
- if ("xDist" in props) {
68
- const { xDist, left, right, edgeToEdge, centerToCenter } = props
69
- const leftVar = getKVar(`${left}_x`)
70
- const rightVar = getKVar(`${right}_x`)
71
- const leftBounds = getComponentDetails(left)?.bounds!
72
- const rightBounds = getComponentDetails(right)?.bounds!
73
-
74
- if (centerToCenter) {
75
- // right - left = xdist
76
- const expr = new kiwi.Expression(rightVar, [-1, leftVar])
77
- solver.addConstraint(
78
- new kiwi.Constraint(
79
- expr,
80
- kiwi.Operator.Eq,
81
- props.xDist,
82
- kiwi.Strength.required,
83
- ),
84
- )
85
- } else if (edgeToEdge) {
86
- // rightEdge - leftEdge = xdist
87
- // right - rightBounds.width/2 - left - leftBounds.width/2 = xdist
88
- const expr = new kiwi.Expression(
89
- rightVar,
90
- -rightBounds.width / 2,
91
- [-1, leftVar],
92
- -leftBounds.width / 2,
93
- )
94
- solver.addConstraint(
95
- new kiwi.Constraint(
96
- expr,
97
- kiwi.Operator.Eq,
98
- props.xDist,
99
- kiwi.Strength.required,
100
- ),
101
- )
102
- }
103
- } else if ("yDist" in props) {
104
- const { yDist, top, bottom, edgeToEdge, centerToCenter } = props
105
- const topVar = getKVar(`${top}_y`)
106
- const bottomVar = getKVar(`${bottom}_y`)
107
- const topBounds = getComponentDetails(top)?.bounds!
108
- const bottomBounds = getComponentDetails(bottom)?.bounds!
109
-
110
- // Top - Bottom = ydist
111
-
112
- if (centerToCenter) {
113
- // top - bottom = ydist
114
- const expr = new kiwi.Expression(topVar, [-1, bottomVar])
115
- solver.addConstraint(
116
- new kiwi.Constraint(
117
- expr,
118
- kiwi.Operator.Eq,
119
- props.yDist,
120
- kiwi.Strength.required,
121
- ),
122
- )
123
- } else if (edgeToEdge) {
124
- // topElmBottomEdge - bottomElmTopEdge = ydist
125
- // topElmCenterY - topElmHeight/2 - bottomElmCenterY - bottomElmHeight/2 = ydist
126
- const expr = new kiwi.Expression(
127
- topVar,
128
- topBounds.height / 2,
129
- [-1, bottomVar],
130
- -bottomBounds.height / 2,
131
- )
132
- solver.addConstraint(
133
- new kiwi.Constraint(
134
- expr,
135
- kiwi.Operator.Eq,
136
- props.yDist,
137
- kiwi.Strength.required,
138
- ),
139
- )
140
- }
141
- } else if ("sameY" in props) {
142
- const { for: selectors } = props
143
- if (selectors.length < 2) continue
144
- const vars = selectors.map((selector) => getKVar(`${selector}_y`))
145
- const expr = new kiwi.Expression(...vars.slice(1))
146
-
147
- solver.addConstraint(
148
- new kiwi.Constraint(
149
- expr,
150
- kiwi.Operator.Eq,
151
- vars[0],
152
- kiwi.Strength.required,
153
- ),
154
- )
155
- } else if ("sameX" in props) {
156
- const { for: selectors } = props
157
- if (selectors.length < 2) continue
158
- const vars = selectors.map((selector) => getKVar(`${selector}_x`))
159
- const expr = new kiwi.Expression(...vars.slice(1))
160
- solver.addConstraint(
161
- new kiwi.Constraint(
162
- expr,
163
- kiwi.Operator.Eq,
164
- vars[0],
165
- kiwi.Strength.required,
166
- ),
167
- )
168
- }
169
- }
170
-
171
- // 3. Solve the system of equations
172
- solver.updateVariables()
173
- if (debug.enabled) {
174
- console.log("Solution to layout constraints:")
175
- console.table(
176
- Object.entries(kVars).map(([key, kvar]) => ({
177
- var: key,
178
- val: kvar.value(),
179
- })),
180
- )
181
- }
182
-
183
- // 3.1 Compute the global offset. There are different ways to do this:
184
- // - If any component has a fixed position, then that can be used as the
185
- // origin to determine the offset of all other components
186
- // - If no component has a fixed position, then we recenter everything
187
- // using the new bounds of all the involved components
188
-
189
- // TODO determine if there's a fixed component
190
-
191
- // Determine the new bounds all the involved components and compute the
192
- // bounds of this footprint
193
- const bounds = {
194
- left: Infinity,
195
- right: -Infinity,
196
- top: -Infinity,
197
- bottom: Infinity,
198
- }
199
- for (const {
200
- selector,
201
- bounds: { width, height },
202
- } of involvedComponents) {
203
- const kvx = getKVar(`${selector}_x`)
204
- const kvy = getKVar(`${selector}_y`)
205
-
206
- const newLeft = kvx.value() - width / 2
207
- const newRight = kvx.value() + width / 2
208
- const newTop = kvy.value() + height / 2
209
- const newBottom = kvy.value() - height / 2
210
-
211
- bounds.left = Math.min(bounds.left, newLeft)
212
- bounds.right = Math.max(bounds.right, newRight)
213
- bounds.top = Math.max(bounds.top, newTop)
214
- bounds.bottom = Math.min(bounds.bottom, newBottom)
215
- }
216
-
217
- // Compute the global offset, we can use this to recenter each component
218
- const globalOffset = {
219
- x: -(bounds.right + bounds.left) / 2,
220
- y: -(bounds.top + bounds.bottom) / 2,
221
- }
222
-
223
- const containerPos =
224
- this.getPrimitiveContainer()!._getGlobalPcbPositionBeforeLayout()
225
-
226
- globalOffset.x += containerPos.x
227
- globalOffset.y += containerPos.y
228
-
229
- // 4. Update the component positions
230
- for (const { component, selector } of involvedComponents) {
231
- const kvx = getKVar(`${selector}_x`)
232
- const kvy = getKVar(`${selector}_y`)
233
- component._setPositionFromLayout({
234
- x: kvx.value() + globalOffset.x,
235
- y: kvy.value() + globalOffset.y,
236
- })
237
- }
238
- }
239
- }
@@ -1,42 +0,0 @@
1
- import {
2
- groupProps,
3
- type GroupProps,
4
- type SubcircuitGroupProps,
5
- } from "@tscircuit/props"
6
- import { PrimitiveComponent } from "../base-components/PrimitiveComponent"
7
- import { compose, identity } from "transformation-matrix"
8
- import { z } from "zod"
9
- import { NormalComponent } from "../base-components/NormalComponent"
10
- import { TraceHint } from "./TraceHint"
11
-
12
- export class Group<
13
- Props extends z.ZodType<any, any, any> = typeof groupProps,
14
- > extends NormalComponent<Props> {
15
- get config() {
16
- return {
17
- zodProps: groupProps as unknown as Props,
18
- }
19
- }
20
-
21
- doInitialCreateTraceHintsFromProps(): void {
22
- const { _parsedProps: props } = this
23
- const { db } = this.root!
24
-
25
- const groupProps = props as SubcircuitGroupProps
26
-
27
- if (!this.isSubcircuit) return
28
-
29
- const manualTraceHints = groupProps.layout?.manual_trace_hints
30
-
31
- if (!manualTraceHints) return
32
-
33
- for (const manualTraceHint of manualTraceHints) {
34
- this.add(
35
- new TraceHint({
36
- for: manualTraceHint.pcb_port_selector,
37
- offsets: manualTraceHint.offsets,
38
- }),
39
- )
40
- }
41
- }
42
- }
@@ -1,65 +0,0 @@
1
- import { PrimitiveComponent } from "../base-components/PrimitiveComponent"
2
- import { holeProps } from "@tscircuit/props"
3
- import type { PCBHole } from "@tscircuit/soup"
4
-
5
- export class Hole extends PrimitiveComponent<typeof holeProps> {
6
- pcb_hole_id: string | null = null
7
- isPcbPrimitive = true
8
-
9
- get config() {
10
- return {
11
- zodProps: holeProps,
12
- }
13
- }
14
-
15
- getPcbSize(): { width: number; height: number } {
16
- const { _parsedProps: props } = this
17
- return { width: props.diameter, height: props.diameter }
18
- }
19
-
20
- doInitialPcbPrimitiveRender(): void {
21
- const { db } = this.root!
22
- const { _parsedProps: props } = this
23
- const position = this._getGlobalPcbPositionBeforeLayout()
24
-
25
- const inserted_hole = db.pcb_hole.insert({
26
- hole_shape: "circle",
27
- // @ts-ignore
28
- hole_diameter: props.diameter,
29
- x: position.x,
30
- y: position.y,
31
- })
32
- this.pcb_hole_id = inserted_hole.pcb_hole_id!
33
- }
34
-
35
- _getPcbCircuitJsonBounds(): {
36
- center: { x: number; y: number }
37
- bounds: { left: number; top: number; right: number; bottom: number }
38
- width: number
39
- height: number
40
- } {
41
- const { db } = this.root!
42
- const hole = db.pcb_hole.get(this.pcb_hole_id!)!
43
- const size = this.getPcbSize()
44
-
45
- return {
46
- center: { x: hole.x, y: hole.y },
47
- bounds: {
48
- left: hole.x - size.width / 2,
49
- top: hole.y - size.height / 2,
50
- right: hole.x + size.width / 2,
51
- bottom: hole.y + size.height / 2,
52
- },
53
- width: size.width,
54
- height: size.height,
55
- }
56
- }
57
-
58
- _setPositionFromLayout(newCenter: { x: number; y: number }) {
59
- const { db } = this.root!
60
- db.pcb_hole.update(this.pcb_hole_id!, {
61
- x: newCenter.x,
62
- y: newCenter.y,
63
- })
64
- }
65
- }
@@ -1,58 +0,0 @@
1
- import { PrimitiveComponent } from "../base-components/PrimitiveComponent"
2
- import { pcbKeepoutProps } from "@tscircuit/props"
3
- import type { RenderPhaseFn } from "../base-components/Renderable"
4
- import type { PCBKeepout } from "@tscircuit/soup"
5
- import { decomposeTSR } from "transformation-matrix"
6
-
7
- export class Keepout extends PrimitiveComponent<typeof pcbKeepoutProps> {
8
- pcb_keepout_id: string | null = null
9
-
10
- isPcbPrimitive = true
11
-
12
- get config() {
13
- return {
14
- zodProps: pcbKeepoutProps,
15
- }
16
- }
17
-
18
- doInitialPcbPrimitiveRender(): void {
19
- const { db } = this.root!
20
- const { _parsedProps: props } = this
21
- const position = this._getGlobalPcbPositionBeforeLayout()
22
- const decomposedMat = decomposeTSR(
23
- this._computePcbGlobalTransformBeforeLayout(),
24
- )
25
- const isRotated90 =
26
- Math.abs(decomposedMat.rotation.angle * (180 / Math.PI) - 90) < 0.01
27
-
28
- let pcb_keepout: PCBKeepout | null = null
29
- if (props.shape === "circle") {
30
- pcb_keepout = db.pcb_keepout.insert({
31
- layers: ["top"],
32
- shape: "circle",
33
- // @ts-ignore: no idea why this is triggering
34
- radius: props.radius,
35
- center: {
36
- x: position.x,
37
- y: position.y,
38
- },
39
- })
40
- } else if (props.shape === "rect") {
41
- pcb_keepout = db.pcb_keepout.insert({
42
- layers: ["top"],
43
- shape: "rect",
44
- ...(isRotated90
45
- ? { width: props.height, height: props.width }
46
- : { width: props.width, height: props.height }),
47
- // @ts-ignore: no idea why this is triggering
48
- center: {
49
- x: position.x,
50
- y: position.y,
51
- },
52
- })
53
- }
54
- if (pcb_keepout) {
55
- this.pcb_keepout_id = pcb_keepout.pcb_keepout_id
56
- }
57
- }
58
- }
@@ -1,171 +0,0 @@
1
- import { PrimitiveComponent } from "../base-components/PrimitiveComponent"
2
- import { z } from "zod"
3
- import type { Port } from "./Port"
4
- import type { Trace } from "./Trace"
5
- import { pairs } from "lib/utils/pairs"
6
- import type { AnySoupElement, SourceTrace } from "@tscircuit/soup"
7
- import { autoroute } from "@tscircuit/infgrid-ijump-astar"
8
-
9
- export const netProps = z.object({
10
- name: z.string(),
11
- })
12
-
13
- export class Net extends PrimitiveComponent<typeof netProps> {
14
- source_net_id?: string
15
-
16
- getPortSelector() {
17
- return `net.${this.props.name}`
18
- }
19
-
20
- doInitialSourceRender(): void {
21
- const { db } = this.root!
22
- const { _parsedProps: props } = this
23
-
24
- const net = db.source_net.insert({
25
- name: props.name,
26
- member_source_group_ids: [],
27
- })
28
-
29
- this.source_net_id = net.source_net_id
30
- }
31
-
32
- /**
33
- * Get all ports connected to this net.
34
- *
35
- * TODO currently we're not checking for indirect connections (traces that are
36
- * connected to other traces that are in turn connected to the net)
37
- */
38
- getAllConnectedPorts(): Port[] {
39
- const allPorts = this.getSubcircuit().selectAll("port") as Port[]
40
- const connectedPorts: Port[] = []
41
-
42
- for (const port of allPorts) {
43
- const traces = port._getDirectlyConnectedTraces()
44
-
45
- for (const trace of traces) {
46
- if (trace._isExplicitlyConnectedToNet(this)) {
47
- connectedPorts.push(port)
48
- break
49
- }
50
- }
51
- }
52
-
53
- return connectedPorts
54
- }
55
-
56
- /**
57
- * Get all traces that are directly connected to this net, i.e. they list
58
- * this net in their path, from, or to props
59
- */
60
- _getAllDirectlyConnectedTraces(): Trace[] {
61
- const allTraces = this.getSubcircuit().selectAll("trace") as Trace[]
62
- const connectedTraces: Trace[] = []
63
-
64
- for (const trace of allTraces) {
65
- if (trace._isExplicitlyConnectedToNet(this)) {
66
- connectedTraces.push(trace)
67
- }
68
- }
69
-
70
- return connectedTraces
71
- }
72
-
73
- /**
74
- * Add PCB Traces to connect net islands together. A net island is a set of
75
- * ports that are connected to each other. If a there are multiple net islands
76
- * that means that the net is not fully connected and we need to add traces
77
- * such that the nets are fully connected
78
- */
79
- doInitialPcbRouteNetIslands(): void {
80
- const { db } = this.root!
81
- const { _parsedProps: props } = this
82
-
83
- const traces = this._getAllDirectlyConnectedTraces().filter(
84
- (trace) => (trace._portsRoutedOnPcb?.length ?? 0) > 0,
85
- )
86
-
87
- const islands: Array<{ ports: Port[]; traces: Trace[] }> = []
88
-
89
- for (const trace of traces) {
90
- const tracePorts = trace._portsRoutedOnPcb
91
- const traceIsland = islands.find((island) =>
92
- tracePorts.some((port) => island.ports.includes(port)),
93
- )
94
- if (!traceIsland) {
95
- islands.push({ ports: [...tracePorts], traces: [trace] })
96
- continue
97
- }
98
- traceIsland.traces.push(trace)
99
- traceIsland.ports.push(...tracePorts)
100
- }
101
-
102
- if (islands.length === 0) {
103
- return
104
- }
105
-
106
- // Connect islands together by looking at each pair of islands and adding
107
- // a trace between them
108
- const islandPairs = pairs(islands)
109
- for (const [A, B] of islandPairs) {
110
- // Find two closest ports on the island
111
- const Apositions: Array<{ x: number; y: number }> = A.ports.map((port) =>
112
- port._getGlobalPcbPositionBeforeLayout(),
113
- )
114
- const Bpositions: Array<{ x: number; y: number }> = B.ports.map((port) =>
115
- port._getGlobalPcbPositionBeforeLayout(),
116
- )
117
-
118
- let closestDist = Infinity
119
- let closestPair: [number, number] = [-1, -1]
120
- for (let i = 0; i < Apositions.length; i++) {
121
- const Apos = Apositions[i]
122
- for (let j = 0; j < Bpositions.length; j++) {
123
- const Bpos = Bpositions[j]
124
- const dist = Math.sqrt(
125
- (Apos.x - Bpos.x) ** 2 + (Apos.y - Bpos.y) ** 2,
126
- )
127
- if (dist < closestDist) {
128
- closestDist = dist
129
- closestPair = [i, j]
130
- }
131
- }
132
- }
133
-
134
- const Aport = A.ports[closestPair[0]]
135
- const Bport = B.ports[closestPair[1]]
136
-
137
- const pcbElements: AnySoupElement[] = db
138
- .toArray()
139
- .filter(
140
- (elm) =>
141
- elm.type === "pcb_smtpad" ||
142
- elm.type === "pcb_trace" ||
143
- elm.type === "pcb_plated_hole" ||
144
- elm.type === "pcb_hole" ||
145
- elm.type === "source_port" ||
146
- elm.type === "pcb_port",
147
- )
148
-
149
- const { solution } = autoroute(
150
- pcbElements.concat([
151
- {
152
- type: "source_trace",
153
- source_trace_id: "__net_trace_tmp",
154
- connected_source_port_ids: [
155
- Aport.source_port_id!,
156
- Bport.source_port_id!,
157
- ],
158
- } as SourceTrace,
159
- ]),
160
- )
161
-
162
- const trace = solution[0]
163
- if (!trace) {
164
- this.renderError("Failed to route net islands")
165
- return
166
- }
167
-
168
- db.pcb_trace.insert(trace as any)
169
- }
170
- }
171
- }
@@ -1,116 +0,0 @@
1
- import { PrimitiveComponent } from "../base-components/PrimitiveComponent"
2
- import { platedHoleProps } from "@tscircuit/props"
3
- import type { Port } from "./Port"
4
- import type { PCBPlatedHoleInput } from "@tscircuit/soup"
5
-
6
- export class PlatedHole extends PrimitiveComponent<typeof platedHoleProps> {
7
- pcb_plated_hole_id: string | null = null
8
- matchedPort: Port | null = null
9
- isPcbPrimitive = true
10
-
11
- get config() {
12
- return {
13
- zodProps: platedHoleProps,
14
- }
15
- }
16
-
17
- getAvailablePcbLayers(): string[] {
18
- // TODO use project layerCount
19
- return ["top", "inner1", "inner2", "bottom"]
20
- }
21
-
22
- getPcbSize(): { width: number; height: number } {
23
- const { _parsedProps: props } = this
24
- if (props.shape === "circle") {
25
- return { width: props.outerDiameter, height: props.outerDiameter }
26
- }
27
- if (props.shape === "oval") {
28
- return { width: props.outerWidth, height: props.outerHeight }
29
- }
30
- throw new Error(
31
- `getPcbSize for shape "${(props as any).shape}" not implemented for ${this.componentName}`,
32
- )
33
- }
34
-
35
- _getPcbCircuitJsonBounds(): {
36
- center: { x: number; y: number }
37
- bounds: { left: number; top: number; right: number; bottom: number }
38
- width: number
39
- height: number
40
- } {
41
- const { db } = this.root!
42
- const platedHole = db.pcb_plated_hole.get(this.pcb_plated_hole_id!)!
43
- const size = this.getPcbSize()
44
-
45
- return {
46
- center: { x: platedHole.x, y: platedHole.y },
47
- bounds: {
48
- left: platedHole.x - size.width / 2,
49
- top: platedHole.y - size.height / 2,
50
- right: platedHole.x + size.width / 2,
51
- bottom: platedHole.y + size.height / 2,
52
- },
53
- width: size.width,
54
- height: size.height,
55
- }
56
- }
57
-
58
- _setPositionFromLayout(newCenter: { x: number; y: number }) {
59
- const { db } = this.root!
60
- db.pcb_plated_hole.update(this.pcb_plated_hole_id!, {
61
- x: newCenter.x,
62
- y: newCenter.y,
63
- })
64
- this.matchedPort?._setPositionFromLayout(newCenter)
65
- }
66
-
67
- doInitialPortMatching(): void {
68
- const parentPorts = this.getPrimitiveContainer()?.selectAll(
69
- "port",
70
- ) as Port[]
71
-
72
- if (!this.props.portHints) {
73
- return
74
- }
75
-
76
- for (const port of parentPorts) {
77
- if (port.isMatchingAnyOf(this.props.portHints)) {
78
- this.matchedPort = port
79
- port.registerMatch(this)
80
- return
81
- }
82
- }
83
- }
84
-
85
- doInitialPcbPrimitiveRender(): void {
86
- const { db } = this.root!
87
- const { _parsedProps: props } = this
88
- const position = this._getGlobalPcbPositionBeforeLayout()
89
- const pcb_component_id =
90
- this.parent?.pcb_component_id ??
91
- this.getPrimitiveContainer()?.pcb_component_id!
92
- if (props.shape === "circle") {
93
- const pcb_plated_hole = db.pcb_plated_hole.insert({
94
- pcb_component_id,
95
- pcb_port_id: this.matchedPort?.pcb_port_id!,
96
- // @ts-ignore - some issue with @tscircuit/soup union type
97
- outer_diameter: props.outerDiameter,
98
- hole_diameter: props.holeDiameter,
99
- shape: "circle" as const,
100
- port_hints: this.getNameAndAliases(),
101
- x: position.x,
102
- y: position.y,
103
- layers: ["top", "bottom"],
104
- })
105
-
106
- this.pcb_plated_hole_id = pcb_plated_hole.pcb_plated_hole_id
107
- }
108
- }
109
-
110
- doInitialPcbPortAttachment(): void {
111
- const { db } = this.root!
112
- db.pcb_plated_hole.update(this.pcb_plated_hole_id!, {
113
- pcb_port_id: this.matchedPort?.pcb_port_id!,
114
- })
115
- }
116
- }