@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.
- package/dist/index.js +9 -4
- package/package.json +3 -5
- package/index.ts +0 -1
- package/lib/Project.ts +0 -131
- package/lib/components/base-components/NormalComponent.ts +0 -419
- package/lib/components/base-components/PrimitiveComponent.ts +0 -478
- package/lib/components/base-components/Renderable.ts +0 -126
- package/lib/components/index.ts +0 -25
- package/lib/components/normal-components/Board.ts +0 -49
- package/lib/components/normal-components/Capacitor.ts +0 -70
- package/lib/components/normal-components/Chip.ts +0 -98
- package/lib/components/normal-components/Diode.ts +0 -27
- package/lib/components/normal-components/Jumper.ts +0 -101
- package/lib/components/normal-components/Led.ts +0 -27
- package/lib/components/normal-components/Resistor.ts +0 -59
- package/lib/components/primitive-components/Constraint.ts +0 -91
- package/lib/components/primitive-components/FabricationNotePath.ts +0 -50
- package/lib/components/primitive-components/FabricationNoteText.ts +0 -26
- package/lib/components/primitive-components/Footprint.ts +0 -239
- package/lib/components/primitive-components/Group.ts +0 -42
- package/lib/components/primitive-components/Hole.ts +0 -65
- package/lib/components/primitive-components/Keepout.ts +0 -58
- package/lib/components/primitive-components/Net.ts +0 -171
- package/lib/components/primitive-components/PlatedHole.ts +0 -116
- package/lib/components/primitive-components/Port.ts +0 -236
- package/lib/components/primitive-components/SilkscreenPath.ts +0 -48
- package/lib/components/primitive-components/SilkscreenText.ts +0 -25
- package/lib/components/primitive-components/SmtPad.ts +0 -162
- package/lib/components/primitive-components/Trace.ts +0 -635
- package/lib/components/primitive-components/TraceHint.ts +0 -71
- package/lib/fiber/catalogue.ts +0 -22
- package/lib/fiber/create-instance-from-react-element.ts +0 -179
- package/lib/fiber/intrinsic-jsx.ts +0 -48
- package/lib/index.ts +0 -5
- package/lib/register-catalogue.ts +0 -12
- package/lib/soup/underscorifyPinStyles.ts +0 -25
- package/lib/soup/underscorifyPortArrangement.ts +0 -51
- package/lib/utils/autorouting/SimpleRouteJson.ts +0 -48
- package/lib/utils/autorouting/computeObstacleBounds.ts +0 -10
- package/lib/utils/autorouting/findPossibleTraceLayerCombinations.ts +0 -102
- package/lib/utils/autorouting/mergeRoutes.ts +0 -71
- package/lib/utils/components/createNetsFromProps.ts +0 -15
- package/lib/utils/constants.ts +0 -35
- package/lib/utils/createComponentsFromSoup.ts +0 -79
- package/lib/utils/extend-aliases.ts +0 -12
- package/lib/utils/get-bounds-of-pcb-components.ts +0 -41
- package/lib/utils/get-relative-direction.ts +0 -14
- package/lib/utils/getClosest.ts +0 -35
- package/lib/utils/getPortFromHints.ts +0 -10
- package/lib/utils/pairs.ts +0 -10
- package/lib/utils/projectPointInDirection.ts +0 -18
- package/lib/utils/range.ts +0 -8
- package/lib/utils/schematic/getAllDimensionsForSchematicBox.ts +0 -330
- package/lib/utils/schematic/getSizeOfSidesFromPortArrangement.ts +0 -47
- package/lib/utils/selector-matching/index.ts +0 -2
- package/lib/utils/selector-matching/is-matching-path-selector.ts +0 -32
- package/lib/utils/selector-matching/is-matching-selector.ts +0 -64
- package/lib/utils/try-now.ts +0 -7
package/lib/fiber/catalogue.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
// See CATALOGUE.md for information about the catalogue pattern
|
|
2
|
-
// The catalogue is a registry of all the component constructors, it has a
|
|
3
|
-
// bunch of purposes but importantly it reduces circular dependencies.
|
|
4
|
-
|
|
5
|
-
export type Instance = {
|
|
6
|
-
// Add any universal methods for classes, e.g. ".add"
|
|
7
|
-
} & { [key: string]: any }
|
|
8
|
-
|
|
9
|
-
export interface Catalogue {
|
|
10
|
-
[name: string]: {
|
|
11
|
-
new (...args: any): Instance
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const catalogue: Catalogue = {}
|
|
16
|
-
export const extendCatalogue = (objects: object): void => {
|
|
17
|
-
const altKeys = Object.fromEntries(
|
|
18
|
-
Object.entries(objects).map(([key, v]) => [key.toLowerCase(), v]),
|
|
19
|
-
)
|
|
20
|
-
Object.assign(catalogue, objects)
|
|
21
|
-
Object.assign(catalogue, altKeys)
|
|
22
|
-
}
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import type React from "react"
|
|
2
|
-
import ReactReconciler, { type HostConfig } from "react-reconciler"
|
|
3
|
-
import { type Renderable } from "lib/components/base-components/Renderable"
|
|
4
|
-
import { type NormalComponent } from "lib/components/base-components/NormalComponent"
|
|
5
|
-
import type { ReactElement, ReactNode } from "react"
|
|
6
|
-
import { catalogue, type Instance } from "./catalogue"
|
|
7
|
-
import { identity } from "transformation-matrix"
|
|
8
|
-
|
|
9
|
-
export type ReactSubtree = {
|
|
10
|
-
element: ReactElement // TODO rename to "reactElement"
|
|
11
|
-
component: NormalComponent
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// biome-ignore lint/suspicious/noEmptyInterface: TODO when we have local state
|
|
15
|
-
interface LocalState {}
|
|
16
|
-
|
|
17
|
-
export function prepare<T extends Renderable>(
|
|
18
|
-
object: T,
|
|
19
|
-
state?: Partial<LocalState>,
|
|
20
|
-
): Instance {
|
|
21
|
-
const instance = object as unknown as Instance
|
|
22
|
-
instance.__tsci = {
|
|
23
|
-
...state,
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return object
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Define the host config
|
|
30
|
-
const hostConfig: HostConfig<
|
|
31
|
-
string | NormalComponent,
|
|
32
|
-
any,
|
|
33
|
-
any,
|
|
34
|
-
any,
|
|
35
|
-
any,
|
|
36
|
-
any,
|
|
37
|
-
any,
|
|
38
|
-
any,
|
|
39
|
-
any,
|
|
40
|
-
any,
|
|
41
|
-
any,
|
|
42
|
-
any,
|
|
43
|
-
any
|
|
44
|
-
> = {
|
|
45
|
-
supportsMutation: true,
|
|
46
|
-
createInstance(type: string, props: any) {
|
|
47
|
-
const target = catalogue[type]
|
|
48
|
-
|
|
49
|
-
if (!target) {
|
|
50
|
-
if (Object.keys(catalogue).length === 0) {
|
|
51
|
-
throw new Error(
|
|
52
|
-
"No components registered in catalogue, did you forget to import lib/register-catalogue in your test file?",
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
throw new Error(
|
|
56
|
-
`Unsupported component type (not registered in @tscircuit/core catalogue): "${type}" See CREATING_NEW_COMPONENTS.md`,
|
|
57
|
-
)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const instance = prepare(new target(props) as any, {})
|
|
61
|
-
|
|
62
|
-
return instance
|
|
63
|
-
},
|
|
64
|
-
createTextInstance() {
|
|
65
|
-
// We don't need to handle text nodes for this use case
|
|
66
|
-
return {}
|
|
67
|
-
},
|
|
68
|
-
appendInitialChild(parentInstance: any, child: any) {
|
|
69
|
-
parentInstance.add(child)
|
|
70
|
-
},
|
|
71
|
-
appendChild(parentInstance: any, child: any) {
|
|
72
|
-
parentInstance.add(child)
|
|
73
|
-
},
|
|
74
|
-
appendChildToContainer(container: any, child: any) {
|
|
75
|
-
container.add(child)
|
|
76
|
-
},
|
|
77
|
-
finalizeInitialChildren() {
|
|
78
|
-
return false
|
|
79
|
-
},
|
|
80
|
-
prepareUpdate() {
|
|
81
|
-
return null
|
|
82
|
-
},
|
|
83
|
-
shouldSetTextContent() {
|
|
84
|
-
return false
|
|
85
|
-
},
|
|
86
|
-
getRootHostContext() {
|
|
87
|
-
return {}
|
|
88
|
-
},
|
|
89
|
-
getChildHostContext() {
|
|
90
|
-
return {}
|
|
91
|
-
},
|
|
92
|
-
prepareForCommit() {
|
|
93
|
-
return null
|
|
94
|
-
},
|
|
95
|
-
resetAfterCommit() {},
|
|
96
|
-
commitMount() {},
|
|
97
|
-
commitUpdate() {},
|
|
98
|
-
removeChild() {},
|
|
99
|
-
clearContainer() {},
|
|
100
|
-
supportsPersistence: false,
|
|
101
|
-
getPublicInstance(instance: any) {
|
|
102
|
-
return instance
|
|
103
|
-
},
|
|
104
|
-
preparePortalMount(containerInfo: any): void {
|
|
105
|
-
throw new Error("Function not implemented.")
|
|
106
|
-
},
|
|
107
|
-
scheduleTimeout(fn: (...args: unknown[]) => unknown, delay?: number) {
|
|
108
|
-
throw new Error("Function not implemented.")
|
|
109
|
-
},
|
|
110
|
-
cancelTimeout(id: any): void {
|
|
111
|
-
throw new Error("Function not implemented.")
|
|
112
|
-
},
|
|
113
|
-
noTimeout: undefined,
|
|
114
|
-
isPrimaryRenderer: false,
|
|
115
|
-
getCurrentEventPriority(): ReactReconciler.Lane {
|
|
116
|
-
throw new Error("Function not implemented.")
|
|
117
|
-
},
|
|
118
|
-
getInstanceFromNode(node: any): ReactReconciler.Fiber | null | undefined {
|
|
119
|
-
throw new Error("Function not implemented.")
|
|
120
|
-
},
|
|
121
|
-
beforeActiveInstanceBlur(): void {
|
|
122
|
-
throw new Error("Function not implemented.")
|
|
123
|
-
},
|
|
124
|
-
afterActiveInstanceBlur(): void {
|
|
125
|
-
throw new Error("Function not implemented.")
|
|
126
|
-
},
|
|
127
|
-
prepareScopeUpdate: (scopeInstance: any, instance: any): void => {
|
|
128
|
-
throw new Error("Function not implemented.")
|
|
129
|
-
},
|
|
130
|
-
getInstanceFromScope: (scopeInstance: any) => {
|
|
131
|
-
throw new Error("Function not implemented.")
|
|
132
|
-
},
|
|
133
|
-
detachDeletedInstance: (node: any): void => {
|
|
134
|
-
throw new Error("Function not implemented.")
|
|
135
|
-
},
|
|
136
|
-
supportsHydration: false,
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const reconciler = ReactReconciler(hostConfig as any)
|
|
140
|
-
|
|
141
|
-
export const createInstanceFromReactElement = (
|
|
142
|
-
reactElm: React.ReactElement,
|
|
143
|
-
): NormalComponent => {
|
|
144
|
-
const rootContainer = {
|
|
145
|
-
children: [] as any[],
|
|
146
|
-
props: {
|
|
147
|
-
name: "$root",
|
|
148
|
-
},
|
|
149
|
-
add(instance: any) {
|
|
150
|
-
instance.parent = this
|
|
151
|
-
this.children.push(instance)
|
|
152
|
-
},
|
|
153
|
-
computePcbGlobalTransform() {
|
|
154
|
-
return identity()
|
|
155
|
-
},
|
|
156
|
-
}
|
|
157
|
-
const container = reconciler.createContainer(
|
|
158
|
-
// TODO Replace with store like react-three-fiber
|
|
159
|
-
// https://github.com/pmndrs/react-three-fiber/blob/a457290856f57741bf8beef4f6ff9dbf4879c0a5/packages/fiber/src/core/index.tsx#L172
|
|
160
|
-
// https://github.com/pmndrs/react-three-fiber/blob/master/packages/fiber/src/core/store.ts#L168
|
|
161
|
-
rootContainer,
|
|
162
|
-
0,
|
|
163
|
-
null,
|
|
164
|
-
false,
|
|
165
|
-
null,
|
|
166
|
-
"tsci",
|
|
167
|
-
(error: Error) => {
|
|
168
|
-
console.log("Error in createContainer")
|
|
169
|
-
console.error(error)
|
|
170
|
-
},
|
|
171
|
-
null,
|
|
172
|
-
)
|
|
173
|
-
reconciler.updateContainer(reactElm, container, null, () => {})
|
|
174
|
-
const rootInstance = reconciler.getPublicRootInstance(
|
|
175
|
-
container,
|
|
176
|
-
) as NormalComponent
|
|
177
|
-
if (rootInstance) return rootInstance
|
|
178
|
-
return rootContainer.children[0] as NormalComponent
|
|
179
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import type * as Props from "@tscircuit/props"
|
|
2
|
-
|
|
3
|
-
declare global {
|
|
4
|
-
namespace JSX {
|
|
5
|
-
interface IntrinsicElements {
|
|
6
|
-
resistor: Props.ResistorProps
|
|
7
|
-
capacitor: Props.CapacitorProps
|
|
8
|
-
inductor: Props.InductorProps
|
|
9
|
-
diode: Props.DiodeProps
|
|
10
|
-
led: Props.LedProps
|
|
11
|
-
board: Props.BoardProps
|
|
12
|
-
jumper: Props.JumperProps
|
|
13
|
-
bug: Props.ChipProps
|
|
14
|
-
// TODO use ChipProps once it gets merged in @tscircuit/props
|
|
15
|
-
chip: Props.ChipProps
|
|
16
|
-
powersource: Props.PowerSourceProps
|
|
17
|
-
via: Props.ViaProps
|
|
18
|
-
schematicbox: Props.SchematicBoxProps
|
|
19
|
-
schematicline: Props.SchematicLineProps
|
|
20
|
-
schematicpath: Props.SchematicPathProps
|
|
21
|
-
schematictext: Props.SchematicTextProps
|
|
22
|
-
smtpad: Props.SmtPadProps
|
|
23
|
-
platedhole: Props.PlatedHoleProps
|
|
24
|
-
keepout: Props.PcbKeepoutProps
|
|
25
|
-
hole: Props.HoleProps
|
|
26
|
-
port: Props.PortProps
|
|
27
|
-
group: Props.GroupProps
|
|
28
|
-
netalias: Props.NetAliasProps
|
|
29
|
-
net: Props.NetProps
|
|
30
|
-
trace: Props.TraceProps
|
|
31
|
-
custom: any
|
|
32
|
-
component: Props.ComponentProps
|
|
33
|
-
footprint: any
|
|
34
|
-
silkscreentext: Props.SilkscreenTextProps
|
|
35
|
-
silkscreenpath: Props.SilkscreenPathProps
|
|
36
|
-
silkscreenline: Props.SilkscreenLineProps
|
|
37
|
-
silkscreenrect: Props.SilkscreenRectProps
|
|
38
|
-
silkscreencircle: Props.SilkscreenCircleProps
|
|
39
|
-
tracehint: Props.TraceHintProps
|
|
40
|
-
pcbtrace: Props.PcbTraceProps
|
|
41
|
-
fabricationnotetext: Props.FabricationNoteTextProps
|
|
42
|
-
fabricationnotepath: Props.FabricationNotePathProps
|
|
43
|
-
constraint: Props.ConstraintProps
|
|
44
|
-
constrainedlayout: Props.ConstrainedLayoutProps
|
|
45
|
-
jscad: any
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
package/lib/index.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import * as Components from "./components"
|
|
2
|
-
import { extendCatalogue } from "./fiber/catalogue"
|
|
3
|
-
|
|
4
|
-
// Register all components, generally you don't need to manually
|
|
5
|
-
// register a component, as long as it's exported from lib/components
|
|
6
|
-
// it'll automatically be registered!
|
|
7
|
-
extendCatalogue(Components)
|
|
8
|
-
|
|
9
|
-
// Aliases (only when class name is different than the name of the component)
|
|
10
|
-
extendCatalogue({
|
|
11
|
-
Bug: Components.Chip,
|
|
12
|
-
})
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { SchematicPinStyle } from "@tscircuit/props"
|
|
2
|
-
import { schematic_component } from "@tscircuit/soup"
|
|
3
|
-
import { z } from "zod"
|
|
4
|
-
|
|
5
|
-
type UnderscorePinStyles = z.input<typeof schematic_component>["pin_styles"]
|
|
6
|
-
|
|
7
|
-
export const underscorifyPinStyles = (
|
|
8
|
-
pinStyles: Record<string, SchematicPinStyle> | undefined,
|
|
9
|
-
): UnderscorePinStyles | undefined => {
|
|
10
|
-
if (!pinStyles) return undefined
|
|
11
|
-
const underscorePinStyles: UnderscorePinStyles = {}
|
|
12
|
-
|
|
13
|
-
for (const [pinName, pinStyle] of Object.entries(pinStyles) as Array<
|
|
14
|
-
[string, SchematicPinStyle]
|
|
15
|
-
>) {
|
|
16
|
-
underscorePinStyles[pinName] = {
|
|
17
|
-
bottom_margin: pinStyle.bottomMargin as number,
|
|
18
|
-
left_margin: pinStyle.leftMargin as number,
|
|
19
|
-
right_margin: pinStyle.rightMargin as number,
|
|
20
|
-
top_margin: pinStyle.topMargin as number,
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return underscorePinStyles
|
|
25
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import type { SchematicComponentInput } from "@tscircuit/soup"
|
|
2
|
-
import type { PortArrangement } from "lib/utils/schematic/getAllDimensionsForSchematicBox"
|
|
3
|
-
|
|
4
|
-
export const underscorifyPortArrangement = (
|
|
5
|
-
portArrangement?: PortArrangement | undefined,
|
|
6
|
-
): SchematicComponentInput["port_arrangement"] | undefined => {
|
|
7
|
-
if (!portArrangement) return undefined
|
|
8
|
-
if (
|
|
9
|
-
"leftSide" in portArrangement ||
|
|
10
|
-
"rightSide" in portArrangement ||
|
|
11
|
-
"topSide" in portArrangement ||
|
|
12
|
-
"bottomSide" in portArrangement
|
|
13
|
-
) {
|
|
14
|
-
return {
|
|
15
|
-
left_side: portArrangement.leftSide,
|
|
16
|
-
right_side: portArrangement.rightSide,
|
|
17
|
-
top_side: portArrangement.topSide,
|
|
18
|
-
bottom_side: portArrangement.bottomSide,
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (
|
|
23
|
-
"leftPinCount" in portArrangement ||
|
|
24
|
-
"rightPinCount" in portArrangement ||
|
|
25
|
-
"topPinCount" in portArrangement ||
|
|
26
|
-
"bottomPinCount" in portArrangement
|
|
27
|
-
) {
|
|
28
|
-
return {
|
|
29
|
-
left_size: portArrangement.leftPinCount!,
|
|
30
|
-
right_size: portArrangement.rightPinCount!,
|
|
31
|
-
top_size: portArrangement.topPinCount,
|
|
32
|
-
bottom_size: portArrangement.bottomPinCount,
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if (
|
|
37
|
-
"leftSize" in portArrangement ||
|
|
38
|
-
"rightSize" in portArrangement ||
|
|
39
|
-
"topSize" in portArrangement ||
|
|
40
|
-
"bottomSize" in portArrangement
|
|
41
|
-
) {
|
|
42
|
-
return {
|
|
43
|
-
left_size: portArrangement.leftSize!,
|
|
44
|
-
right_size: portArrangement.rightSize!,
|
|
45
|
-
top_size: portArrangement.topSize,
|
|
46
|
-
bottom_size: portArrangement.bottomSize,
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return undefined
|
|
51
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
export type SimplifiedPcbTrace = {
|
|
2
|
-
type: "pcb_trace"
|
|
3
|
-
pcb_trace_id: string
|
|
4
|
-
route: Array<
|
|
5
|
-
| {
|
|
6
|
-
route_type: "wire"
|
|
7
|
-
x: number
|
|
8
|
-
y: number
|
|
9
|
-
width: number
|
|
10
|
-
layer: string
|
|
11
|
-
}
|
|
12
|
-
| {
|
|
13
|
-
route_type: "via"
|
|
14
|
-
x: number
|
|
15
|
-
y: number
|
|
16
|
-
to_layer: string
|
|
17
|
-
from_layer: string
|
|
18
|
-
}
|
|
19
|
-
>
|
|
20
|
-
}
|
|
21
|
-
export type Obstacle = {
|
|
22
|
-
// TODO include ovals
|
|
23
|
-
type: "rect" // NOTE: most datasets do not contain ovals
|
|
24
|
-
layers: string[]
|
|
25
|
-
center: { x: number; y: number }
|
|
26
|
-
width: number
|
|
27
|
-
height: number
|
|
28
|
-
connectedTo: string[]
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface SimpleRouteConnection {
|
|
32
|
-
name: string
|
|
33
|
-
pointsToConnect: Array<{ x: number; y: number; layer: string }>
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface SimpleRouteJson {
|
|
37
|
-
layerCount: number
|
|
38
|
-
minTraceWidth: number
|
|
39
|
-
obstacles: Obstacle[]
|
|
40
|
-
connections: Array<SimpleRouteConnection>
|
|
41
|
-
bounds: { minX: number; maxX: number; minY: number; maxY: number }
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// declare module "autorouting-dataset" {
|
|
45
|
-
// export type Obstacle = SimpleRouteJson["obstacles"][number]
|
|
46
|
-
// export type SimpleRouteConnection = SimpleRouteJson["connections"][number]
|
|
47
|
-
// export type SimplifiedPcbTrace = SimpleRouteJson["connections"][number]
|
|
48
|
-
// }
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { Obstacle } from "./SimpleRouteJson"
|
|
2
|
-
|
|
3
|
-
export const computeObstacleBounds = (obstacles: Array<Obstacle>) => {
|
|
4
|
-
const minX = Math.min(...obstacles.map((o) => o.center.x))
|
|
5
|
-
const maxX = Math.max(...obstacles.map((o) => o.center.x))
|
|
6
|
-
const minY = Math.min(...obstacles.map((o) => o.center.y))
|
|
7
|
-
const maxY = Math.max(...obstacles.map((o) => o.center.y))
|
|
8
|
-
|
|
9
|
-
return { minX, maxX, minY, maxY }
|
|
10
|
-
}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
interface Hint {
|
|
2
|
-
via?: boolean
|
|
3
|
-
optional_via?: boolean
|
|
4
|
-
layers?: Array<string>
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
const LAYER_SELECTION_PREFERENCE = ["top", "bottom", "inner1", "inner2"]
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* ORDERING OF CANDIDATES: Example:
|
|
11
|
-
* top -> top -> bottom -> bottom
|
|
12
|
-
* bottom -> bottom -> top -> top
|
|
13
|
-
* top -> bottom -> bottom -> top
|
|
14
|
-
* bottom -> top -> top -> bottom
|
|
15
|
-
*/
|
|
16
|
-
export interface CandidateTraceLayerCombination {
|
|
17
|
-
layer_path: string[]
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Given a set of hints that contain layers or indication there should be a via,
|
|
22
|
-
* this function returns all combinations of layers that could be traversed.
|
|
23
|
-
*
|
|
24
|
-
* EXAMPLE 1:
|
|
25
|
-
* INPUT:
|
|
26
|
-
* [top,bottom] -> unspecified -> unspecified/via -> [top, bottom]
|
|
27
|
-
* OUTPUT:
|
|
28
|
-
* top -> top -> bottom -> bottom
|
|
29
|
-
* bottom -> bottom -> top -> top *
|
|
30
|
-
* EXAMPLE 2:
|
|
31
|
-
* INPUT:
|
|
32
|
-
* [top,bottom] -> unspecified -> unspecified/via -> unspecified/via -> [top, bottom]
|
|
33
|
-
* OUTPUT:
|
|
34
|
-
* top -> top -> bottom -> top -> top
|
|
35
|
-
* bottom -> bottom -> top-> bottom -> bottom
|
|
36
|
-
* bottom -> bottom -> inner-1 -> inner-1 -> bottom
|
|
37
|
-
*/
|
|
38
|
-
export const findPossibleTraceLayerCombinations = (
|
|
39
|
-
hints: Hint[],
|
|
40
|
-
layer_path: string[] = [],
|
|
41
|
-
): CandidateTraceLayerCombination[] => {
|
|
42
|
-
const candidates: CandidateTraceLayerCombination[] = []
|
|
43
|
-
if (layer_path.length === 0) {
|
|
44
|
-
const starting_layers = hints[0].layers!
|
|
45
|
-
for (const layer of starting_layers) {
|
|
46
|
-
candidates.push(
|
|
47
|
-
...findPossibleTraceLayerCombinations(hints.slice(1), [layer]),
|
|
48
|
-
)
|
|
49
|
-
}
|
|
50
|
-
return candidates
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (hints.length === 0) return []
|
|
54
|
-
const current_hint = hints[0]
|
|
55
|
-
const is_possibly_via = current_hint.via || current_hint.optional_via
|
|
56
|
-
const last_layer = layer_path[layer_path.length - 1]
|
|
57
|
-
|
|
58
|
-
if (hints.length === 1) {
|
|
59
|
-
const last_hint = current_hint
|
|
60
|
-
if (last_hint.layers && is_possibly_via) {
|
|
61
|
-
return last_hint.layers.map((layer) => ({
|
|
62
|
-
layer_path: [...layer_path, layer],
|
|
63
|
-
}))
|
|
64
|
-
}
|
|
65
|
-
if (last_hint.layers?.includes(last_layer)) {
|
|
66
|
-
return [{ layer_path: [...layer_path, last_layer] }]
|
|
67
|
-
}
|
|
68
|
-
return []
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!is_possibly_via) {
|
|
72
|
-
if (current_hint.layers) {
|
|
73
|
-
if (!current_hint.layers.includes(last_layer)) {
|
|
74
|
-
return []
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return findPossibleTraceLayerCombinations(
|
|
79
|
-
hints.slice(1),
|
|
80
|
-
layer_path.concat([last_layer]),
|
|
81
|
-
)
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
const candidate_next_layers = (
|
|
85
|
-
current_hint.optional_via
|
|
86
|
-
? LAYER_SELECTION_PREFERENCE
|
|
87
|
-
: LAYER_SELECTION_PREFERENCE.filter((layer) => layer !== last_layer)
|
|
88
|
-
).filter(
|
|
89
|
-
(layer) => !current_hint.layers || current_hint.layers?.includes(layer),
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
for (const candidate_next_layer of candidate_next_layers) {
|
|
93
|
-
candidates.push(
|
|
94
|
-
...findPossibleTraceLayerCombinations(
|
|
95
|
-
hints.slice(1),
|
|
96
|
-
layer_path.concat(candidate_next_layer),
|
|
97
|
-
),
|
|
98
|
-
)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return candidates
|
|
102
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import type { PCBTrace } from "@tscircuit/soup"
|
|
2
|
-
|
|
3
|
-
function pdist(a: any, b: any) {
|
|
4
|
-
return Math.hypot(a.x - b.x, a.y - b.y)
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Merge multiple routes into a single route.
|
|
9
|
-
*
|
|
10
|
-
* If the end of the next route is closer to the end of the previous route,
|
|
11
|
-
* reverse the next route and append it to the previous route.
|
|
12
|
-
*/
|
|
13
|
-
export const mergeRoutes = (routes: PCBTrace["route"][]) => {
|
|
14
|
-
if (routes.length === 1) return routes[0]
|
|
15
|
-
// routes = routes.filter((route) => route.length > 0)
|
|
16
|
-
if (routes.some((r) => r.length === 0)) {
|
|
17
|
-
throw new Error("Cannot merge routes with zero length")
|
|
18
|
-
}
|
|
19
|
-
// for (const route of routes) {
|
|
20
|
-
// console.table(route)
|
|
21
|
-
// }
|
|
22
|
-
const merged: PCBTrace["route"] = []
|
|
23
|
-
// const reverse_log: boolean[] = []
|
|
24
|
-
|
|
25
|
-
// Determine if the first route should be reversed
|
|
26
|
-
const first_route_fp = routes[0][0]
|
|
27
|
-
const first_route_lp = routes[0][routes[0].length - 1]
|
|
28
|
-
|
|
29
|
-
const second_route_fp = routes[1][0]
|
|
30
|
-
const second_route_lp = routes[1][routes[1].length - 1]
|
|
31
|
-
|
|
32
|
-
const best_reverse_dist = Math.min(
|
|
33
|
-
pdist(first_route_fp, second_route_fp),
|
|
34
|
-
pdist(first_route_fp, second_route_lp),
|
|
35
|
-
)
|
|
36
|
-
|
|
37
|
-
const best_normal_dist = Math.min(
|
|
38
|
-
pdist(first_route_lp, second_route_fp),
|
|
39
|
-
pdist(first_route_lp, second_route_lp),
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
if (best_reverse_dist < best_normal_dist) {
|
|
43
|
-
merged.push(...routes[0].reverse())
|
|
44
|
-
// reverse_log.push(true)
|
|
45
|
-
} else {
|
|
46
|
-
merged.push(...routes[0])
|
|
47
|
-
// reverse_log.push(false)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
for (let i = 1; i < routes.length; i++) {
|
|
51
|
-
const last_merged_point = merged[merged.length - 1]
|
|
52
|
-
const next_route = routes[i]
|
|
53
|
-
|
|
54
|
-
const next_first_point = next_route[0]
|
|
55
|
-
const next_last_point = next_route[next_route.length - 1]
|
|
56
|
-
|
|
57
|
-
const distance_to_first = pdist(last_merged_point, next_first_point)
|
|
58
|
-
const distance_to_last = pdist(last_merged_point, next_last_point)
|
|
59
|
-
|
|
60
|
-
if (distance_to_first < distance_to_last) {
|
|
61
|
-
// reverse_log.push(false)
|
|
62
|
-
merged.push(...next_route)
|
|
63
|
-
} else {
|
|
64
|
-
// reverse_log.push(true)
|
|
65
|
-
merged.push(...next_route.reverse())
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
// console.log(reverse_log)
|
|
69
|
-
// console.table(merged)
|
|
70
|
-
return merged
|
|
71
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { PrimitiveComponent } from "lib/components/base-components/PrimitiveComponent"
|
|
2
|
-
import { Net } from "lib/components/primitive-components/Net"
|
|
3
|
-
|
|
4
|
-
export const createNetsFromProps = (
|
|
5
|
-
component: PrimitiveComponent,
|
|
6
|
-
props: (string | undefined | null)[],
|
|
7
|
-
) => {
|
|
8
|
-
for (const prop of props) {
|
|
9
|
-
if (typeof prop === "string" && prop.startsWith("net.")) {
|
|
10
|
-
if (!component.getSubcircuit().selectOne(prop)) {
|
|
11
|
-
component.getSubcircuit().add(new Net({ name: prop.split("net.")[1] }))
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
package/lib/utils/constants.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import type { AnySourceComponent } from "@tscircuit/soup"
|
|
2
|
-
import type { BaseSymbolName } from "schematic-symbols"
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* This is just a proxy to make autocomplete easier, it just returns whatever
|
|
6
|
-
* key you pass in. It's helpful when you want to make it a bit more obvious
|
|
7
|
-
* how to select the key you want to use without obscuring the actual key.
|
|
8
|
-
*/
|
|
9
|
-
const stringProxy = new Proxy(
|
|
10
|
-
{},
|
|
11
|
-
{
|
|
12
|
-
get: (target, prop) => prop,
|
|
13
|
-
},
|
|
14
|
-
) as any
|
|
15
|
-
|
|
16
|
-
export type Ftype = AnySourceComponent["ftype"]
|
|
17
|
-
|
|
18
|
-
export const FTYPE: {
|
|
19
|
-
[T in AnySourceComponent["ftype"]]: T
|
|
20
|
-
} = stringProxy
|
|
21
|
-
|
|
22
|
-
export const SYMBOL: {
|
|
23
|
-
[T in BaseSymbolName]: T
|
|
24
|
-
} = stringProxy
|
|
25
|
-
|
|
26
|
-
export type TwoPinPorts = "pin1" | "pin2"
|
|
27
|
-
export type PassivePorts = TwoPinPorts
|
|
28
|
-
export type PolarizedPassivePorts =
|
|
29
|
-
| PassivePorts
|
|
30
|
-
| "anode"
|
|
31
|
-
| "cathode"
|
|
32
|
-
| "pos"
|
|
33
|
-
| "neg"
|
|
34
|
-
|
|
35
|
-
export type { BaseSymbolName }
|