circuit-json-to-connectivity-map 0.0.13 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +3 -1
- package/dist/index.js +59 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ declare class ConnectivityMap {
|
|
|
7
7
|
netMap: Record<string, string[]>;
|
|
8
8
|
idToNetMap: Record<string, string>;
|
|
9
9
|
constructor(netMap: Record<string, string[]>);
|
|
10
|
+
addConnections(connections: string[][]): void;
|
|
10
11
|
getIdsConnectedToNet(netId: string): string[];
|
|
11
12
|
getNetConnectedToId(id: string): string | undefined;
|
|
12
13
|
areIdsConnected(id1: string, id2: string): boolean;
|
|
@@ -29,10 +30,11 @@ declare class PcbConnectivityMap {
|
|
|
29
30
|
traceIdToElm: Map<string, PCBTrace>;
|
|
30
31
|
portIdToElm: Map<string, PCBPort>;
|
|
31
32
|
connMap: ConnectivityMap;
|
|
32
|
-
constructor(circuitJson
|
|
33
|
+
constructor(circuitJson?: AnyCircuitElement[]);
|
|
33
34
|
private _buildPortMap;
|
|
34
35
|
private _buildTraceMap;
|
|
35
36
|
private _buildTraceConnectivityMap;
|
|
37
|
+
addTrace(trace: PCBTrace): void;
|
|
36
38
|
_arePcbTracesConnected(trace1: PCBTrace, trace2: PCBTrace): boolean;
|
|
37
39
|
areTracesConnected(traceId1: string, traceId2: string): boolean;
|
|
38
40
|
getAllTracesConnectedToTrace(traceId: string): PCBTrace[];
|
package/dist/index.js
CHANGED
|
@@ -54,6 +54,41 @@ var ConnectivityMap = class {
|
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
+
addConnections(connections) {
|
|
58
|
+
for (const connection of connections) {
|
|
59
|
+
const existingNets = /* @__PURE__ */ new Set();
|
|
60
|
+
for (const id of connection) {
|
|
61
|
+
const existingNetId = this.idToNetMap[id];
|
|
62
|
+
if (existingNetId) {
|
|
63
|
+
existingNets.add(existingNetId);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
let targetNetId;
|
|
67
|
+
if (existingNets.size === 0) {
|
|
68
|
+
targetNetId = `connectivity_net${Object.keys(this.netMap).length}`;
|
|
69
|
+
this.netMap[targetNetId] = [];
|
|
70
|
+
} else if (existingNets.size === 1) {
|
|
71
|
+
targetNetId = existingNets.values().next().value ?? `connectivity_net${Object.keys(this.netMap).length}`;
|
|
72
|
+
} else {
|
|
73
|
+
targetNetId = existingNets.values().next().value ?? `connectivity_net${Object.keys(this.netMap).length}`;
|
|
74
|
+
for (const netId of existingNets) {
|
|
75
|
+
if (netId !== targetNetId) {
|
|
76
|
+
this.netMap[targetNetId].push(...this.netMap[netId]);
|
|
77
|
+
this.netMap[netId] = this.netMap[targetNetId];
|
|
78
|
+
for (const id of this.netMap[targetNetId]) {
|
|
79
|
+
this.idToNetMap[id] = targetNetId;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
for (const id of connection) {
|
|
85
|
+
if (!this.netMap[targetNetId].includes(id)) {
|
|
86
|
+
this.netMap[targetNetId].push(id);
|
|
87
|
+
}
|
|
88
|
+
this.idToNetMap[id] = targetNetId;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
57
92
|
getIdsConnectedToNet(netId) {
|
|
58
93
|
return this.netMap[netId] || [];
|
|
59
94
|
}
|
|
@@ -66,7 +101,7 @@ var ConnectivityMap = class {
|
|
|
66
101
|
return netId1 === netId2 || netId2 === id1 || netId2 === id1;
|
|
67
102
|
}
|
|
68
103
|
areAllIdsConnected(ids) {
|
|
69
|
-
|
|
104
|
+
const netId = this.getNetConnectedToId(ids[0]);
|
|
70
105
|
for (const id of ids) {
|
|
71
106
|
const nextNetId = this.getNetConnectedToId(id);
|
|
72
107
|
if (nextNetId === void 0) {
|
|
@@ -141,12 +176,16 @@ var PcbConnectivityMap = class {
|
|
|
141
176
|
portIdToElm;
|
|
142
177
|
connMap;
|
|
143
178
|
constructor(circuitJson) {
|
|
144
|
-
this.circuitJson = circuitJson;
|
|
179
|
+
this.circuitJson = circuitJson || [];
|
|
145
180
|
this.traceIdToElm = /* @__PURE__ */ new Map();
|
|
146
181
|
this.portIdToElm = /* @__PURE__ */ new Map();
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
182
|
+
if (circuitJson) {
|
|
183
|
+
this._buildTraceMap();
|
|
184
|
+
this._buildPortMap();
|
|
185
|
+
this.connMap = this._buildTraceConnectivityMap();
|
|
186
|
+
} else {
|
|
187
|
+
this.connMap = new ConnectivityMap({});
|
|
188
|
+
}
|
|
150
189
|
}
|
|
151
190
|
_buildPortMap() {
|
|
152
191
|
for (const element of this.circuitJson) {
|
|
@@ -189,6 +228,21 @@ var PcbConnectivityMap = class {
|
|
|
189
228
|
}
|
|
190
229
|
return new ConnectivityMap(findConnectedNetworks(connections));
|
|
191
230
|
}
|
|
231
|
+
addTrace(trace) {
|
|
232
|
+
this.traceIdToElm.set(trace.pcb_trace_id, trace);
|
|
233
|
+
const connections = [];
|
|
234
|
+
for (const rp of trace.route) {
|
|
235
|
+
if (rp.route_type === "wire") {
|
|
236
|
+
if (rp.start_pcb_port_id) {
|
|
237
|
+
connections.push([rp.start_pcb_port_id, trace.pcb_trace_id]);
|
|
238
|
+
}
|
|
239
|
+
if (rp.end_pcb_port_id) {
|
|
240
|
+
connections.push([rp.end_pcb_port_id, trace.pcb_trace_id]);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
this.connMap.addConnections(connections);
|
|
245
|
+
}
|
|
192
246
|
_arePcbTracesConnected(trace1, trace2) {
|
|
193
247
|
for (let i = 0; i < trace1.route.length - 1; i++) {
|
|
194
248
|
const segment1A = trace1.route[i];
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/findConnectedNetworks.ts","../src/ConnectivityMap.ts","../src/getSourcePortConnectivityMapFromCircuitJson.ts","../src/getFullConnectivityMapFromCircuitJson.ts","../src/PcbConnectivityMap.ts"],"sourcesContent":["type NodeId = string\n\nexport function findConnectedNetworks(\n connections: Array<NodeId[]>,\n): Record<string, string[]> {\n const networks: Map<string, Set<string>> = new Map()\n let netCounter = 0\n\n function getOrCreateNetwork(nodeId: string): Set<string> {\n for (const [, network] of networks) {\n if (network.has(nodeId)) {\n return network\n }\n }\n const newNetwork = new Set<string>()\n networks.set(`connectivity_net${netCounter++}`, newNetwork)\n return newNetwork\n }\n\n for (const connection of connections) {\n let network: Set<string> | null = null\n\n for (const nodeId of connection) {\n if (!network) {\n network = getOrCreateNetwork(nodeId)\n } else if (!network.has(nodeId)) {\n const existingNetwork = getOrCreateNetwork(nodeId)\n if (existingNetwork !== network) {\n // Merge networks\n for (const node of existingNetwork) {\n network.add(node)\n }\n networks.delete(\n Array.from(networks.entries()).find(\n ([, net]) => net === existingNetwork,\n )![0],\n )\n }\n }\n network.add(nodeId)\n }\n }\n\n return Object.fromEntries(\n Array.from(networks.entries()).map(([netId, connectedNodes]) => [\n netId,\n Array.from(connectedNodes),\n ]),\n )\n}\n","export class ConnectivityMap {\n netMap: Record<string, string[]>\n\n idToNetMap: Record<string, string>\n\n constructor(netMap: Record<string, string[]>) {\n this.netMap = netMap\n this.idToNetMap = {}\n for (const [netId, ids] of Object.entries(netMap)) {\n for (const id of ids) {\n this.idToNetMap[id] = netId\n }\n }\n }\n\n getIdsConnectedToNet(netId: string): string[] {\n return this.netMap[netId] || []\n }\n\n getNetConnectedToId(id: string): string | undefined {\n return this.idToNetMap[id]\n }\n\n areIdsConnected(id1: string, id2: string): boolean {\n const netId1 = this.getNetConnectedToId(id1)\n const netId2 = this.getNetConnectedToId(id2)\n return netId1 === netId2 || netId2 === id1 || netId2 === id1\n }\n\n areAllIdsConnected(ids: string[]): boolean {\n let netId = this.getNetConnectedToId(ids[0])\n for (const id of ids) {\n const nextNetId = this.getNetConnectedToId(id)\n if (nextNetId === undefined) {\n return false\n }\n if (nextNetId !== netId) {\n return false\n }\n }\n return true\n }\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport { findConnectedNetworks } from \"./findConnectedNetworks\"\nimport { ConnectivityMap } from \"./ConnectivityMap\"\n\nexport const getSourcePortConnectivityMapFromCircuitJson = (\n circuitJson: AnySoupElement[],\n) => {\n const connections: string[][] = []\n\n for (const element of circuitJson) {\n if (element.type === \"source_trace\") {\n connections.push([\n ...(element.connected_source_port_ids ?? []),\n ...(element.connected_source_net_ids ?? []),\n ])\n }\n }\n\n const netMap = findConnectedNetworks(connections)\n\n return new ConnectivityMap(netMap)\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport { findConnectedNetworks } from \"./findConnectedNetworks\"\nimport { ConnectivityMap } from \"./ConnectivityMap\"\n\nexport const getFullConnectivityMapFromCircuitJson = (\n circuitJson: AnySoupElement[],\n) => {\n const connections: string[][] = []\n\n for (const element of circuitJson) {\n if (element.type === \"source_trace\") {\n connections.push(\n [\n element.source_trace_id,\n ...(element.connected_source_port_ids ?? []),\n ...(element.connected_source_net_ids ?? []),\n ].filter(Boolean),\n )\n } else if (element.type === \"pcb_port\") {\n const { pcb_port_id, source_port_id } = element\n if (source_port_id && pcb_port_id) {\n connections.push([source_port_id, pcb_port_id])\n }\n } else if (element.type === \"pcb_smtpad\") {\n const { pcb_smtpad_id, pcb_port_id } = element\n if (pcb_port_id && pcb_smtpad_id) {\n connections.push([pcb_smtpad_id, pcb_port_id])\n }\n } else if (element.type === \"pcb_plated_hole\") {\n const { pcb_plated_hole_id, pcb_port_id } = element\n if (pcb_port_id && pcb_plated_hole_id) {\n connections.push([pcb_plated_hole_id, pcb_port_id])\n }\n } else if (element.type === \"pcb_trace\") {\n const { pcb_trace_id, source_trace_id } = element\n if (source_trace_id && pcb_trace_id) {\n connections.push([pcb_trace_id, source_trace_id])\n }\n }\n }\n\n const netMap = findConnectedNetworks(connections)\n\n return new ConnectivityMap(netMap)\n}\n","import type { AnyCircuitElement, PCBPort, PCBTrace } from \"@tscircuit/soup\"\nimport { ConnectivityMap } from \"./ConnectivityMap\"\nimport { doesLineIntersectLine } from \"@tscircuit/math-utils\"\nimport { findConnectedNetworks } from \"./findConnectedNetworks\"\n\n/**\n * A PCB Connectivity Map is a connectivity map that has analyzed what traces and ports are actually connected on the\n * PCB.\n *\n * This is useful for determining how to route a trace on the PCB. For example, you may want to determine where the\n * nearest connected net point is to connect an unrouted pin.\n */\nexport class PcbConnectivityMap {\n circuitJson: AnyCircuitElement[]\n traceIdToElm: Map<string, PCBTrace>\n portIdToElm: Map<string, PCBPort>\n connMap: ConnectivityMap\n\n constructor(circuitJson: AnyCircuitElement[]) {\n this.circuitJson = circuitJson\n this.traceIdToElm = new Map()\n this.portIdToElm = new Map()\n this._buildTraceMap()\n this._buildPortMap()\n this.connMap = this._buildTraceConnectivityMap()\n }\n\n private _buildPortMap() {\n for (const element of this.circuitJson) {\n if (element.type === \"pcb_port\") {\n this.portIdToElm.set(element.pcb_port_id, element as PCBPort)\n }\n }\n }\n\n private _buildTraceMap() {\n for (const element of this.circuitJson) {\n if (element.type === \"pcb_trace\") {\n this.traceIdToElm.set(element.pcb_trace_id, element as PCBTrace)\n }\n }\n }\n\n private _buildTraceConnectivityMap(): ConnectivityMap {\n const connections: string[][] = []\n const traceIds = Array.from(this.traceIdToElm.keys())\n\n for (let i = 0; i < traceIds.length; i++) {\n for (let j = i + 1; j < traceIds.length; j++) {\n const trace1 = this.traceIdToElm.get(traceIds[i])!\n const trace2 = this.traceIdToElm.get(traceIds[j])!\n if (this._arePcbTracesConnected(trace1, trace2)) {\n connections.push([traceIds[i], traceIds[j]])\n }\n }\n }\n\n for (const port of this.portIdToElm.values()) {\n for (const trace of this.traceIdToElm.values()) {\n for (const rp of trace.route) {\n if (rp.route_type === \"wire\") {\n if (rp.start_pcb_port_id === port.pcb_port_id) {\n connections.push([port.pcb_port_id, trace.pcb_trace_id])\n } else if (rp.end_pcb_port_id === port.pcb_port_id) {\n connections.push([trace.pcb_trace_id, port.pcb_port_id])\n }\n }\n }\n }\n }\n\n return new ConnectivityMap(findConnectedNetworks(connections))\n }\n\n _arePcbTracesConnected(trace1: PCBTrace, trace2: PCBTrace): boolean {\n for (let i = 0; i < trace1.route.length - 1; i++) {\n const segment1A = trace1.route[i]\n const segment1B = trace1.route[i + 1]\n if (segment1A.route_type !== \"wire\") continue\n if (segment1B.route_type !== \"wire\") continue\n for (let j = 0; j < trace2.route.length - 1; j++) {\n const segment2A = trace2.route[j]\n const segment2B = trace2.route[j + 1]\n\n if (segment2A.route_type !== \"wire\") continue\n if (segment2B.route_type !== \"wire\") continue\n\n // Check if lines are overlapping\n const isOverlapping = doesLineIntersectLine(\n [segment1A, segment1B],\n [segment2A, segment2B],\n {\n lineThickness: (segment1A.width + segment2A.width) / 2,\n },\n )\n if (isOverlapping) {\n return true\n }\n }\n }\n return false\n }\n\n areTracesConnected(traceId1: string, traceId2: string): boolean {\n return this.connMap.areIdsConnected(traceId1, traceId2)\n }\n\n getAllTracesConnectedToTrace(traceId: string): PCBTrace[] {\n const netId = this.connMap.getNetConnectedToId(traceId)\n return netId\n ? this.connMap\n .getIdsConnectedToNet(netId)\n .filter((id) => this.traceIdToElm.has(id))\n .map((id) => this.traceIdToElm.get(id) as PCBTrace)\n : []\n }\n\n getAllTracesConnectedToPort(portId: string): PCBTrace[] {\n const netId = this.connMap.getNetConnectedToId(portId)\n return netId\n ? this.connMap\n .getIdsConnectedToNet(netId)\n .filter((id) => this.traceIdToElm.has(id))\n .map((id) => this.traceIdToElm.get(id) as PCBTrace)\n : []\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/findConnectedNetworks.ts","../src/ConnectivityMap.ts","../src/getSourcePortConnectivityMapFromCircuitJson.ts","../src/getFullConnectivityMapFromCircuitJson.ts","../src/PcbConnectivityMap.ts"],"sourcesContent":["type NodeId = string\n\nexport function findConnectedNetworks(\n connections: Array<NodeId[]>,\n): Record<string, string[]> {\n const networks: Map<string, Set<string>> = new Map()\n let netCounter = 0\n\n function getOrCreateNetwork(nodeId: string): Set<string> {\n for (const [, network] of networks) {\n if (network.has(nodeId)) {\n return network\n }\n }\n const newNetwork = new Set<string>()\n networks.set(`connectivity_net${netCounter++}`, newNetwork)\n return newNetwork\n }\n\n for (const connection of connections) {\n let network: Set<string> | null = null\n\n for (const nodeId of connection) {\n if (!network) {\n network = getOrCreateNetwork(nodeId)\n } else if (!network.has(nodeId)) {\n const existingNetwork = getOrCreateNetwork(nodeId)\n if (existingNetwork !== network) {\n // Merge networks\n for (const node of existingNetwork) {\n network.add(node)\n }\n networks.delete(\n Array.from(networks.entries()).find(\n ([, net]) => net === existingNetwork,\n )![0],\n )\n }\n }\n network.add(nodeId)\n }\n }\n\n return Object.fromEntries(\n Array.from(networks.entries()).map(([netId, connectedNodes]) => [\n netId,\n Array.from(connectedNodes),\n ]),\n )\n}\n","export class ConnectivityMap {\n netMap: Record<string, string[]>\n\n idToNetMap: Record<string, string>\n\n constructor(netMap: Record<string, string[]>) {\n this.netMap = netMap\n this.idToNetMap = {}\n for (const [netId, ids] of Object.entries(netMap)) {\n for (const id of ids) {\n this.idToNetMap[id] = netId\n }\n }\n }\n\n addConnections(connections: string[][]) {\n for (const connection of connections) {\n const existingNets = new Set<string>()\n\n // Find all existing nets for the connection\n for (const id of connection) {\n const existingNetId = this.idToNetMap[id]\n if (existingNetId) {\n existingNets.add(existingNetId)\n }\n }\n\n let targetNetId: string\n\n if (existingNets.size === 0) {\n // If no existing nets found, create a new one\n targetNetId = `connectivity_net${Object.keys(this.netMap).length}`\n this.netMap[targetNetId] = []\n } else if (existingNets.size === 1) {\n // If only one existing net found, use it\n targetNetId =\n existingNets.values().next().value ??\n `connectivity_net${Object.keys(this.netMap).length}`\n } else {\n // If multiple nets found, merge them\n targetNetId =\n existingNets.values().next().value ??\n `connectivity_net${Object.keys(this.netMap).length}`\n for (const netId of existingNets) {\n if (netId !== targetNetId) {\n this.netMap[targetNetId].push(...this.netMap[netId])\n\n // we could delete the net, but setting it to reference the other net\n // will make sure any usage of the old netId will still work\n this.netMap[netId] = this.netMap[targetNetId]\n for (const id of this.netMap[targetNetId]) {\n this.idToNetMap[id] = targetNetId\n }\n }\n }\n }\n\n // Add all ids to the target net\n for (const id of connection) {\n if (!this.netMap[targetNetId].includes(id)) {\n this.netMap[targetNetId].push(id)\n }\n this.idToNetMap[id] = targetNetId\n }\n }\n }\n\n getIdsConnectedToNet(netId: string): string[] {\n return this.netMap[netId] || []\n }\n\n getNetConnectedToId(id: string): string | undefined {\n return this.idToNetMap[id]\n }\n\n areIdsConnected(id1: string, id2: string): boolean {\n const netId1 = this.getNetConnectedToId(id1)\n const netId2 = this.getNetConnectedToId(id2)\n return netId1 === netId2 || netId2 === id1 || netId2 === id1\n }\n\n areAllIdsConnected(ids: string[]): boolean {\n const netId = this.getNetConnectedToId(ids[0])\n for (const id of ids) {\n const nextNetId = this.getNetConnectedToId(id)\n if (nextNetId === undefined) {\n return false\n }\n if (nextNetId !== netId) {\n return false\n }\n }\n return true\n }\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport { findConnectedNetworks } from \"./findConnectedNetworks\"\nimport { ConnectivityMap } from \"./ConnectivityMap\"\n\nexport const getSourcePortConnectivityMapFromCircuitJson = (\n circuitJson: AnySoupElement[],\n) => {\n const connections: string[][] = []\n\n for (const element of circuitJson) {\n if (element.type === \"source_trace\") {\n connections.push([\n ...(element.connected_source_port_ids ?? []),\n ...(element.connected_source_net_ids ?? []),\n ])\n }\n }\n\n const netMap = findConnectedNetworks(connections)\n\n return new ConnectivityMap(netMap)\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport { findConnectedNetworks } from \"./findConnectedNetworks\"\nimport { ConnectivityMap } from \"./ConnectivityMap\"\n\nexport const getFullConnectivityMapFromCircuitJson = (\n circuitJson: AnySoupElement[],\n) => {\n const connections: string[][] = []\n\n for (const element of circuitJson) {\n if (element.type === \"source_trace\") {\n connections.push(\n [\n element.source_trace_id,\n ...(element.connected_source_port_ids ?? []),\n ...(element.connected_source_net_ids ?? []),\n ].filter(Boolean),\n )\n } else if (element.type === \"pcb_port\") {\n const { pcb_port_id, source_port_id } = element\n if (source_port_id && pcb_port_id) {\n connections.push([source_port_id, pcb_port_id])\n }\n } else if (element.type === \"pcb_smtpad\") {\n const { pcb_smtpad_id, pcb_port_id } = element\n if (pcb_port_id && pcb_smtpad_id) {\n connections.push([pcb_smtpad_id, pcb_port_id])\n }\n } else if (element.type === \"pcb_plated_hole\") {\n const { pcb_plated_hole_id, pcb_port_id } = element\n if (pcb_port_id && pcb_plated_hole_id) {\n connections.push([pcb_plated_hole_id, pcb_port_id])\n }\n } else if (element.type === \"pcb_trace\") {\n const { pcb_trace_id, source_trace_id } = element\n if (source_trace_id && pcb_trace_id) {\n connections.push([pcb_trace_id, source_trace_id])\n }\n }\n }\n\n const netMap = findConnectedNetworks(connections)\n\n return new ConnectivityMap(netMap)\n}\n","import type { AnyCircuitElement, PCBPort, PCBTrace } from \"@tscircuit/soup\"\nimport { ConnectivityMap } from \"./ConnectivityMap\"\nimport { doesLineIntersectLine } from \"@tscircuit/math-utils\"\nimport { findConnectedNetworks } from \"./findConnectedNetworks\"\n\n/**\n * A PCB Connectivity Map is a connectivity map that has analyzed what traces and ports are actually connected on the\n * PCB.\n *\n * This is useful for determining how to route a trace on the PCB. For example, you may want to determine where the\n * nearest connected net point is to connect an unrouted pin.\n */\nexport class PcbConnectivityMap {\n circuitJson: AnyCircuitElement[]\n traceIdToElm: Map<string, PCBTrace>\n portIdToElm: Map<string, PCBPort>\n connMap: ConnectivityMap\n\n constructor(circuitJson?: AnyCircuitElement[]) {\n this.circuitJson = circuitJson || []\n this.traceIdToElm = new Map()\n this.portIdToElm = new Map()\n if (circuitJson) {\n this._buildTraceMap()\n this._buildPortMap()\n this.connMap = this._buildTraceConnectivityMap()\n } else {\n this.connMap = new ConnectivityMap({})\n }\n }\n\n private _buildPortMap() {\n for (const element of this.circuitJson) {\n if (element.type === \"pcb_port\") {\n this.portIdToElm.set(element.pcb_port_id, element as PCBPort)\n }\n }\n }\n\n private _buildTraceMap() {\n for (const element of this.circuitJson) {\n if (element.type === \"pcb_trace\") {\n this.traceIdToElm.set(element.pcb_trace_id, element as PCBTrace)\n }\n }\n }\n\n private _buildTraceConnectivityMap(): ConnectivityMap {\n const connections: string[][] = []\n const traceIds = Array.from(this.traceIdToElm.keys())\n\n for (let i = 0; i < traceIds.length; i++) {\n for (let j = i + 1; j < traceIds.length; j++) {\n const trace1 = this.traceIdToElm.get(traceIds[i])!\n const trace2 = this.traceIdToElm.get(traceIds[j])!\n if (this._arePcbTracesConnected(trace1, trace2)) {\n connections.push([traceIds[i], traceIds[j]])\n }\n }\n }\n\n for (const port of this.portIdToElm.values()) {\n for (const trace of this.traceIdToElm.values()) {\n for (const rp of trace.route) {\n if (rp.route_type === \"wire\") {\n if (rp.start_pcb_port_id === port.pcb_port_id) {\n connections.push([port.pcb_port_id, trace.pcb_trace_id])\n } else if (rp.end_pcb_port_id === port.pcb_port_id) {\n connections.push([trace.pcb_trace_id, port.pcb_port_id])\n }\n }\n }\n }\n }\n\n return new ConnectivityMap(findConnectedNetworks(connections))\n }\n\n addTrace(trace: PCBTrace) {\n this.traceIdToElm.set(trace.pcb_trace_id, trace)\n const connections: string[][] = []\n for (const rp of trace.route) {\n if (rp.route_type === \"wire\") {\n if (rp.start_pcb_port_id) {\n connections.push([rp.start_pcb_port_id, trace.pcb_trace_id])\n }\n if (rp.end_pcb_port_id) {\n connections.push([rp.end_pcb_port_id, trace.pcb_trace_id])\n }\n }\n }\n\n this.connMap.addConnections(connections)\n }\n\n _arePcbTracesConnected(trace1: PCBTrace, trace2: PCBTrace): boolean {\n for (let i = 0; i < trace1.route.length - 1; i++) {\n const segment1A = trace1.route[i]\n const segment1B = trace1.route[i + 1]\n if (segment1A.route_type !== \"wire\") continue\n if (segment1B.route_type !== \"wire\") continue\n for (let j = 0; j < trace2.route.length - 1; j++) {\n const segment2A = trace2.route[j]\n const segment2B = trace2.route[j + 1]\n\n if (segment2A.route_type !== \"wire\") continue\n if (segment2B.route_type !== \"wire\") continue\n\n // Check if lines are overlapping\n const isOverlapping = doesLineIntersectLine(\n [segment1A, segment1B],\n [segment2A, segment2B],\n {\n lineThickness: (segment1A.width + segment2A.width) / 2,\n },\n )\n if (isOverlapping) {\n return true\n }\n }\n }\n return false\n }\n\n areTracesConnected(traceId1: string, traceId2: string): boolean {\n return this.connMap.areIdsConnected(traceId1, traceId2)\n }\n\n getAllTracesConnectedToTrace(traceId: string): PCBTrace[] {\n const netId = this.connMap.getNetConnectedToId(traceId)\n return netId\n ? this.connMap\n .getIdsConnectedToNet(netId)\n .filter((id) => this.traceIdToElm.has(id))\n .map((id) => this.traceIdToElm.get(id) as PCBTrace)\n : []\n }\n\n getAllTracesConnectedToPort(portId: string): PCBTrace[] {\n const netId = this.connMap.getNetConnectedToId(portId)\n return netId\n ? this.connMap\n .getIdsConnectedToNet(netId)\n .filter((id) => this.traceIdToElm.has(id))\n .map((id) => this.traceIdToElm.get(id) as PCBTrace)\n : []\n }\n}\n"],"mappings":"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","names":[]}
|