@tscircuit/core 0.0.645 → 0.0.646
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 +2 -0
- package/dist/index.js +780 -29
- package/package.json +4 -2
package/dist/index.d.ts
CHANGED
|
@@ -202,6 +202,7 @@ declare class RootCircuit {
|
|
|
202
202
|
schematicDisabled: boolean;
|
|
203
203
|
pcbDisabled: boolean;
|
|
204
204
|
pcbRoutingDisabled: boolean;
|
|
205
|
+
_featureMspSchematicTraceRouting: boolean;
|
|
205
206
|
/**
|
|
206
207
|
* The RootCircuit name is usually set by the platform, it's not required but
|
|
207
208
|
* if supplied can identify the circuit in certain effects, e.g. it is passed
|
|
@@ -1125,6 +1126,7 @@ declare class Group<Props extends z.ZodType<any, any, any> = typeof groupProps>
|
|
|
1125
1126
|
_runLocalAutorouting(): Promise<void>;
|
|
1126
1127
|
_startAsyncAutorouting(): void;
|
|
1127
1128
|
doInitialPcbTraceRender(): void;
|
|
1129
|
+
doInitialSchematicTraceRender(): void;
|
|
1128
1130
|
updatePcbTraceRender(): void;
|
|
1129
1131
|
_updatePcbTraceRenderFromSimpleRouteJson(): void;
|
|
1130
1132
|
_updatePcbTraceRenderFromPcbTraces(): void;
|
package/dist/index.js
CHANGED
|
@@ -23,7 +23,7 @@ __export(components_exports, {
|
|
|
23
23
|
FabricationNoteText: () => FabricationNoteText,
|
|
24
24
|
Footprint: () => Footprint,
|
|
25
25
|
Fuse: () => Fuse,
|
|
26
|
-
Group: () =>
|
|
26
|
+
Group: () => Group6,
|
|
27
27
|
Hole: () => Hole,
|
|
28
28
|
Inductor: () => Inductor,
|
|
29
29
|
Jumper: () => Jumper,
|
|
@@ -4197,7 +4197,7 @@ var getMaxLengthFromConnectedCapacitors = (ports, { db }) => {
|
|
|
4197
4197
|
return sourceComponent.max_decoupling_trace_length;
|
|
4198
4198
|
}
|
|
4199
4199
|
return null;
|
|
4200
|
-
}).filter((
|
|
4200
|
+
}).filter((length7) => length7 !== null);
|
|
4201
4201
|
if (capacitorMaxLengths.length === 0) return void 0;
|
|
4202
4202
|
return Math.min(...capacitorMaxLengths);
|
|
4203
4203
|
};
|
|
@@ -5091,6 +5091,7 @@ var TraceConnectionError = class extends Error {
|
|
|
5091
5091
|
|
|
5092
5092
|
// lib/components/primitive-components/Trace/Trace_doInitialSchematicTraceRender.ts
|
|
5093
5093
|
var Trace_doInitialSchematicTraceRender = (trace) => {
|
|
5094
|
+
if (trace.root?._featureMspSchematicTraceRouting) return;
|
|
5094
5095
|
if (trace._couldNotFindPort) return;
|
|
5095
5096
|
if (trace.root?.schematicDisabled) return;
|
|
5096
5097
|
const { db } = trace.root;
|
|
@@ -7219,7 +7220,7 @@ var CapacityMeshAutorouter = class {
|
|
|
7219
7220
|
|
|
7220
7221
|
// lib/components/primitive-components/Group/Group.ts
|
|
7221
7222
|
import "circuit-json";
|
|
7222
|
-
import
|
|
7223
|
+
import Debug9 from "debug";
|
|
7223
7224
|
import "zod";
|
|
7224
7225
|
|
|
7225
7226
|
// lib/components/primitive-components/TraceHint.ts
|
|
@@ -8024,7 +8025,7 @@ function convertTreeToInputProblem(tree, db, group) {
|
|
|
8024
8025
|
netMap: {},
|
|
8025
8026
|
pinStrongConnMap: {},
|
|
8026
8027
|
netConnMap: {},
|
|
8027
|
-
chipGap: 0.
|
|
8028
|
+
chipGap: 0.6,
|
|
8028
8029
|
partitionGap: 1.2
|
|
8029
8030
|
};
|
|
8030
8031
|
debug5(
|
|
@@ -9501,7 +9502,751 @@ var Group_doInitialPcbLayoutFlex = (group) => {
|
|
|
9501
9502
|
|
|
9502
9503
|
// lib/components/primitive-components/Group/Group.ts
|
|
9503
9504
|
import { convertSrjToGraphicsObject } from "@tscircuit/capacity-autorouter";
|
|
9504
|
-
|
|
9505
|
+
|
|
9506
|
+
// lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/Group_doInitialSchematicTraceRender.ts
|
|
9507
|
+
import { SchematicTracePipelineSolver as SchematicTracePipelineSolver4 } from "@tscircuit/schematic-trace-solver";
|
|
9508
|
+
import Debug8 from "debug";
|
|
9509
|
+
|
|
9510
|
+
// lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/createSchematicTraceSolverInputProblem.ts
|
|
9511
|
+
import "@tscircuit/schematic-trace-solver";
|
|
9512
|
+
function createSchematicTraceSolverInputProblem(group) {
|
|
9513
|
+
const { db } = group.root;
|
|
9514
|
+
const sckToSourceNet = /* @__PURE__ */ new Map();
|
|
9515
|
+
const sckToUserNetId = /* @__PURE__ */ new Map();
|
|
9516
|
+
const allScks = /* @__PURE__ */ new Set();
|
|
9517
|
+
const traces = group.selectAll("trace");
|
|
9518
|
+
const displayLabelTraces = traces.filter(
|
|
9519
|
+
(t) => t._parsedProps?.schDisplayLabel
|
|
9520
|
+
);
|
|
9521
|
+
const displayLabelSourceTraceIds = new Set(
|
|
9522
|
+
displayLabelTraces.map((t) => t.source_trace_id).filter((id) => Boolean(id))
|
|
9523
|
+
);
|
|
9524
|
+
const childGroups = group.selectAll("group");
|
|
9525
|
+
const allSchematicGroupIds = [
|
|
9526
|
+
group.schematic_group_id,
|
|
9527
|
+
...childGroups.map((a) => a.schematic_group_id)
|
|
9528
|
+
];
|
|
9529
|
+
const schematicComponents = db.schematic_component.list().filter((a) => allSchematicGroupIds.includes(a.schematic_group_id));
|
|
9530
|
+
const chips = [];
|
|
9531
|
+
const pinIdToSchematicPortId = /* @__PURE__ */ new Map();
|
|
9532
|
+
const schematicPortIdToPinId = /* @__PURE__ */ new Map();
|
|
9533
|
+
for (const schematicComponent of schematicComponents) {
|
|
9534
|
+
const chipId = schematicComponent.schematic_component_id;
|
|
9535
|
+
const pins = [];
|
|
9536
|
+
const sourceComponent = db.source_component.getWhere({
|
|
9537
|
+
source_component_id: schematicComponent.source_component_id
|
|
9538
|
+
});
|
|
9539
|
+
const schematicPorts = db.schematic_port.list({
|
|
9540
|
+
schematic_component_id: schematicComponent.schematic_component_id
|
|
9541
|
+
});
|
|
9542
|
+
for (const schematicPort of schematicPorts) {
|
|
9543
|
+
const pinId = `${sourceComponent?.name ?? schematicComponent.schematic_component_id}.${schematicPort.pin_number}`;
|
|
9544
|
+
pinIdToSchematicPortId.set(pinId, schematicPort.schematic_port_id);
|
|
9545
|
+
schematicPortIdToPinId.set(schematicPort.schematic_port_id, pinId);
|
|
9546
|
+
}
|
|
9547
|
+
for (const schematicPort of schematicPorts) {
|
|
9548
|
+
const pinId = schematicPortIdToPinId.get(schematicPort.schematic_port_id);
|
|
9549
|
+
pins.push({
|
|
9550
|
+
pinId,
|
|
9551
|
+
x: schematicPort.center.x,
|
|
9552
|
+
y: schematicPort.center.y
|
|
9553
|
+
});
|
|
9554
|
+
}
|
|
9555
|
+
chips.push({
|
|
9556
|
+
chipId,
|
|
9557
|
+
center: schematicComponent.center,
|
|
9558
|
+
width: schematicComponent.size.width,
|
|
9559
|
+
height: schematicComponent.size.height,
|
|
9560
|
+
pins
|
|
9561
|
+
});
|
|
9562
|
+
}
|
|
9563
|
+
const allSourceAndSchematicPortIdsInScope = /* @__PURE__ */ new Set();
|
|
9564
|
+
const schPortIdToSourcePortId = /* @__PURE__ */ new Map();
|
|
9565
|
+
const sourcePortIdToSchPortId = /* @__PURE__ */ new Map();
|
|
9566
|
+
const userNetIdToSck = /* @__PURE__ */ new Map();
|
|
9567
|
+
for (const sc of schematicComponents) {
|
|
9568
|
+
const ports = db.schematic_port.list({
|
|
9569
|
+
schematic_component_id: sc.schematic_component_id
|
|
9570
|
+
});
|
|
9571
|
+
for (const sp of ports) {
|
|
9572
|
+
allSourceAndSchematicPortIdsInScope.add(sp.schematic_port_id);
|
|
9573
|
+
if (sp.source_port_id) {
|
|
9574
|
+
schPortIdToSourcePortId.set(sp.schematic_port_id, sp.source_port_id);
|
|
9575
|
+
sourcePortIdToSchPortId.set(sp.source_port_id, sp.schematic_port_id);
|
|
9576
|
+
}
|
|
9577
|
+
}
|
|
9578
|
+
}
|
|
9579
|
+
const allowedSubcircuitIds = /* @__PURE__ */ new Set();
|
|
9580
|
+
if (group.subcircuit_id) allowedSubcircuitIds.add(group.subcircuit_id);
|
|
9581
|
+
for (const cg of childGroups) {
|
|
9582
|
+
if (cg.subcircuit_id) allowedSubcircuitIds.add(cg.subcircuit_id);
|
|
9583
|
+
}
|
|
9584
|
+
const directConnections = [];
|
|
9585
|
+
const pairKeyToSourceTraceId = /* @__PURE__ */ new Map();
|
|
9586
|
+
for (const st of db.source_trace.list()) {
|
|
9587
|
+
if (displayLabelSourceTraceIds.has(st.source_trace_id)) continue;
|
|
9588
|
+
if (st.subcircuit_id && !allowedSubcircuitIds.has(st.subcircuit_id)) {
|
|
9589
|
+
continue;
|
|
9590
|
+
}
|
|
9591
|
+
const connected = (st.connected_source_port_ids ?? []).map((srcId) => sourcePortIdToSchPortId.get(srcId)).filter(
|
|
9592
|
+
(sourcePortId) => Boolean(sourcePortId) && allSourceAndSchematicPortIdsInScope.has(sourcePortId)
|
|
9593
|
+
);
|
|
9594
|
+
if (connected.length >= 2) {
|
|
9595
|
+
const [a, b] = connected.slice(0, 2);
|
|
9596
|
+
const pairKey = [a, b].sort().join("::");
|
|
9597
|
+
if (!pairKeyToSourceTraceId.has(pairKey)) {
|
|
9598
|
+
pairKeyToSourceTraceId.set(pairKey, st.source_trace_id);
|
|
9599
|
+
const userNetId = st.display_name ?? st.source_trace_id;
|
|
9600
|
+
if (st.subcircuit_connectivity_map_key) {
|
|
9601
|
+
allScks.add(st.subcircuit_connectivity_map_key);
|
|
9602
|
+
userNetIdToSck.set(userNetId, st.subcircuit_connectivity_map_key);
|
|
9603
|
+
sckToUserNetId.set(st.subcircuit_connectivity_map_key, userNetId);
|
|
9604
|
+
}
|
|
9605
|
+
directConnections.push({
|
|
9606
|
+
pinIds: [a, b].map((id) => schematicPortIdToPinId.get(id)),
|
|
9607
|
+
netId: userNetId
|
|
9608
|
+
});
|
|
9609
|
+
}
|
|
9610
|
+
}
|
|
9611
|
+
}
|
|
9612
|
+
const netConnections = [];
|
|
9613
|
+
for (const net of db.source_net.list().filter((n) => allowedSubcircuitIds.has(n.subcircuit_id))) {
|
|
9614
|
+
if (net.subcircuit_connectivity_map_key) {
|
|
9615
|
+
allScks.add(net.subcircuit_connectivity_map_key);
|
|
9616
|
+
sckToSourceNet.set(net.subcircuit_connectivity_map_key, net);
|
|
9617
|
+
}
|
|
9618
|
+
}
|
|
9619
|
+
const sckToPinIds = /* @__PURE__ */ new Map();
|
|
9620
|
+
for (const [schId, srcPortId] of schPortIdToSourcePortId) {
|
|
9621
|
+
const sp = db.source_port.get(srcPortId);
|
|
9622
|
+
if (!sp?.subcircuit_connectivity_map_key) continue;
|
|
9623
|
+
const sck = sp.subcircuit_connectivity_map_key;
|
|
9624
|
+
allScks.add(sck);
|
|
9625
|
+
if (!sckToPinIds.has(sck)) sckToPinIds.set(sck, []);
|
|
9626
|
+
sckToPinIds.get(sck).push(schId);
|
|
9627
|
+
}
|
|
9628
|
+
for (const [subcircuitConnectivityKey, schematicPortIds] of sckToPinIds) {
|
|
9629
|
+
const sourceNet = sckToSourceNet.get(subcircuitConnectivityKey);
|
|
9630
|
+
if (sourceNet && schematicPortIds.length >= 2) {
|
|
9631
|
+
const userNetId = String(
|
|
9632
|
+
sourceNet.name || sourceNet.source_net_id || subcircuitConnectivityKey
|
|
9633
|
+
);
|
|
9634
|
+
userNetIdToSck.set(userNetId, subcircuitConnectivityKey);
|
|
9635
|
+
sckToUserNetId.set(subcircuitConnectivityKey, userNetId);
|
|
9636
|
+
netConnections.push({
|
|
9637
|
+
netId: userNetId,
|
|
9638
|
+
pinIds: schematicPortIds.map(
|
|
9639
|
+
(portId) => schematicPortIdToPinId.get(portId)
|
|
9640
|
+
)
|
|
9641
|
+
});
|
|
9642
|
+
}
|
|
9643
|
+
}
|
|
9644
|
+
const availableNetLabelOrientations = (() => {
|
|
9645
|
+
const netToAllowedOrientations = {};
|
|
9646
|
+
const presentNetIds = new Set(netConnections.map((nc) => nc.netId));
|
|
9647
|
+
for (const net of db.source_net.list().filter(
|
|
9648
|
+
(n) => !n.subcircuit_id || allowedSubcircuitIds.has(n.subcircuit_id)
|
|
9649
|
+
)) {
|
|
9650
|
+
if (!net.name) continue;
|
|
9651
|
+
if (!presentNetIds.has(net.name)) continue;
|
|
9652
|
+
if (net.name === "GND") {
|
|
9653
|
+
netToAllowedOrientations[net.name] = ["y-"];
|
|
9654
|
+
} else if (/^V/.test(net.name)) {
|
|
9655
|
+
netToAllowedOrientations[net.name] = ["y+"];
|
|
9656
|
+
}
|
|
9657
|
+
}
|
|
9658
|
+
return netToAllowedOrientations;
|
|
9659
|
+
})();
|
|
9660
|
+
const inputProblem = {
|
|
9661
|
+
chips,
|
|
9662
|
+
directConnections,
|
|
9663
|
+
netConnections,
|
|
9664
|
+
availableNetLabelOrientations,
|
|
9665
|
+
maxMspPairDistance: 2
|
|
9666
|
+
};
|
|
9667
|
+
return {
|
|
9668
|
+
inputProblem,
|
|
9669
|
+
pinIdToSchematicPortId,
|
|
9670
|
+
pairKeyToSourceTraceId,
|
|
9671
|
+
sckToSourceNet,
|
|
9672
|
+
sckToUserNetId,
|
|
9673
|
+
userNetIdToSck,
|
|
9674
|
+
allSourceAndSchematicPortIdsInScope,
|
|
9675
|
+
schPortIdToSourcePortId,
|
|
9676
|
+
displayLabelTraces,
|
|
9677
|
+
allScks
|
|
9678
|
+
};
|
|
9679
|
+
}
|
|
9680
|
+
|
|
9681
|
+
// lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/applyTracesFromSolverOutput.ts
|
|
9682
|
+
import "@tscircuit/schematic-trace-solver";
|
|
9683
|
+
|
|
9684
|
+
// lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/compute-crossings.ts
|
|
9685
|
+
var TOL = 1e-6;
|
|
9686
|
+
function isHorizontalEdge(edge) {
|
|
9687
|
+
const dx = Math.abs(edge.to.x - edge.from.x);
|
|
9688
|
+
const dy = Math.abs(edge.to.y - edge.from.y);
|
|
9689
|
+
return dx >= dy;
|
|
9690
|
+
}
|
|
9691
|
+
function length6(a, b) {
|
|
9692
|
+
return Math.hypot(b.x - a.x, b.y - a.y);
|
|
9693
|
+
}
|
|
9694
|
+
function pointAt(a, b, t) {
|
|
9695
|
+
return { x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t };
|
|
9696
|
+
}
|
|
9697
|
+
function paramAlong(a, b, p) {
|
|
9698
|
+
const L = length6(a, b);
|
|
9699
|
+
if (L < TOL) return 0;
|
|
9700
|
+
const t = ((p.x - a.x) * (b.x - a.x) + (p.y - a.y) * (b.y - a.y)) / ((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y));
|
|
9701
|
+
return Math.max(0, Math.min(1, t)) * L;
|
|
9702
|
+
}
|
|
9703
|
+
function cross(ax, ay, bx, by) {
|
|
9704
|
+
return ax * by - ay * bx;
|
|
9705
|
+
}
|
|
9706
|
+
function segmentIntersection(p1, p2, q1, q2) {
|
|
9707
|
+
const r = { x: p2.x - p1.x, y: p2.y - p1.y };
|
|
9708
|
+
const s = { x: q2.x - q1.x, y: q2.y - q1.y };
|
|
9709
|
+
const rxs = cross(r.x, r.y, s.x, s.y);
|
|
9710
|
+
const q_p = { x: q1.x - p1.x, y: q1.y - p1.y };
|
|
9711
|
+
const q_pxr = cross(q_p.x, q_p.y, r.x, r.y);
|
|
9712
|
+
if (Math.abs(rxs) < TOL && Math.abs(q_pxr) < TOL) {
|
|
9713
|
+
return null;
|
|
9714
|
+
}
|
|
9715
|
+
if (Math.abs(rxs) < TOL && Math.abs(q_pxr) >= TOL) {
|
|
9716
|
+
return null;
|
|
9717
|
+
}
|
|
9718
|
+
const t = cross(q_p.x, q_p.y, s.x, s.y) / rxs;
|
|
9719
|
+
const u = cross(q_p.x, q_p.y, r.x, r.y) / rxs;
|
|
9720
|
+
if (t < -TOL || t > 1 + TOL || u < -TOL || u > 1 + TOL) return null;
|
|
9721
|
+
const pt = { x: p1.x + t * r.x, y: p1.y + t * r.y };
|
|
9722
|
+
return pt;
|
|
9723
|
+
}
|
|
9724
|
+
function mergeIntervals(intervals, tol = TOL) {
|
|
9725
|
+
if (intervals.length === 0) return intervals;
|
|
9726
|
+
intervals.sort((a, b) => a.start - b.start);
|
|
9727
|
+
const merged = [];
|
|
9728
|
+
let cur = { ...intervals[0] };
|
|
9729
|
+
for (let i = 1; i < intervals.length; i++) {
|
|
9730
|
+
const nxt = intervals[i];
|
|
9731
|
+
if (nxt.start <= cur.end + tol) {
|
|
9732
|
+
cur.end = Math.max(cur.end, nxt.end);
|
|
9733
|
+
} else {
|
|
9734
|
+
merged.push(cur);
|
|
9735
|
+
cur = { ...nxt };
|
|
9736
|
+
}
|
|
9737
|
+
}
|
|
9738
|
+
merged.push(cur);
|
|
9739
|
+
return merged;
|
|
9740
|
+
}
|
|
9741
|
+
function splitEdgeByCrossings(edge, crossingDistances, crossLen) {
|
|
9742
|
+
const L = length6(edge.from, edge.to);
|
|
9743
|
+
if (L < TOL || crossingDistances.length === 0) return [edge];
|
|
9744
|
+
const half = crossLen / 2;
|
|
9745
|
+
const rawIntervals = crossingDistances.map((d) => ({
|
|
9746
|
+
start: Math.max(0, d - half),
|
|
9747
|
+
end: Math.min(L, d + half)
|
|
9748
|
+
})).filter((iv) => iv.end - iv.start > TOL);
|
|
9749
|
+
const intervals = mergeIntervals(rawIntervals);
|
|
9750
|
+
const result = [];
|
|
9751
|
+
let cursor = 0;
|
|
9752
|
+
const dir = { x: edge.to.x - edge.from.x, y: edge.to.y - edge.from.y };
|
|
9753
|
+
const addSeg = (d0, d1, isCrossing) => {
|
|
9754
|
+
if (d1 - d0 <= TOL) return;
|
|
9755
|
+
const t0 = d0 / L;
|
|
9756
|
+
const t1 = d1 / L;
|
|
9757
|
+
result.push({
|
|
9758
|
+
from: pointAt(edge.from, edge.to, t0),
|
|
9759
|
+
to: pointAt(edge.from, edge.to, t1),
|
|
9760
|
+
...isCrossing ? { is_crossing: true } : {}
|
|
9761
|
+
});
|
|
9762
|
+
};
|
|
9763
|
+
for (const iv of intervals) {
|
|
9764
|
+
if (iv.start - cursor > TOL) {
|
|
9765
|
+
addSeg(cursor, iv.start, false);
|
|
9766
|
+
}
|
|
9767
|
+
addSeg(iv.start, iv.end, true);
|
|
9768
|
+
cursor = iv.end;
|
|
9769
|
+
}
|
|
9770
|
+
if (L - cursor > TOL) {
|
|
9771
|
+
addSeg(cursor, L, false);
|
|
9772
|
+
}
|
|
9773
|
+
return result.length > 0 ? result : [edge];
|
|
9774
|
+
}
|
|
9775
|
+
function computeCrossings(traces, opts = {}) {
|
|
9776
|
+
const crossLen = opts.crossSegmentLength ?? 0.075;
|
|
9777
|
+
const tol = opts.tolerance ?? TOL;
|
|
9778
|
+
const crossingsByEdge = /* @__PURE__ */ new Map();
|
|
9779
|
+
const keyOf = (ref) => `${ref.traceIdx}:${ref.edgeIdx}`;
|
|
9780
|
+
const getEdge = (ref) => traces[ref.traceIdx].edges[ref.edgeIdx];
|
|
9781
|
+
for (let ti = 0; ti < traces.length; ti++) {
|
|
9782
|
+
const A = traces[ti];
|
|
9783
|
+
for (let ei = 0; ei < A.edges.length; ei++) {
|
|
9784
|
+
const eA = A.edges[ei];
|
|
9785
|
+
for (let tj = ti; tj < traces.length; tj++) {
|
|
9786
|
+
const B = traces[tj];
|
|
9787
|
+
for (let ej = tj === ti ? ei + 1 : 0; ej < B.edges.length; ej++) {
|
|
9788
|
+
const eB = B.edges[ej];
|
|
9789
|
+
const P = segmentIntersection(eA.from, eA.to, eB.from, eB.to);
|
|
9790
|
+
if (!P) continue;
|
|
9791
|
+
const LA = length6(eA.from, eA.to);
|
|
9792
|
+
const LB = length6(eB.from, eB.to);
|
|
9793
|
+
if (LA < tol || LB < tol) continue;
|
|
9794
|
+
const dA = paramAlong(eA.from, eA.to, P);
|
|
9795
|
+
const dB = paramAlong(eB.from, eB.to, P);
|
|
9796
|
+
const nearEndpointA = dA <= tol || Math.abs(LA - dA) <= tol || Number.isNaN(dA);
|
|
9797
|
+
const nearEndpointB = dB <= tol || Math.abs(LB - dB) <= tol || Number.isNaN(dB);
|
|
9798
|
+
if (!nearEndpointA && !nearEndpointB) {
|
|
9799
|
+
const aIsHorizontal = isHorizontalEdge(eA);
|
|
9800
|
+
const bIsHorizontal = isHorizontalEdge(eB);
|
|
9801
|
+
let assignToA;
|
|
9802
|
+
if (aIsHorizontal !== bIsHorizontal) {
|
|
9803
|
+
assignToA = aIsHorizontal;
|
|
9804
|
+
} else {
|
|
9805
|
+
const ax = Math.abs(eA.to.x - eA.from.x);
|
|
9806
|
+
const ay = Math.abs(eA.to.y - eA.from.y);
|
|
9807
|
+
const bx = Math.abs(eB.to.x - eB.from.x);
|
|
9808
|
+
const by = Math.abs(eB.to.y - eB.from.y);
|
|
9809
|
+
const aScore = ax - ay;
|
|
9810
|
+
const bScore = bx - by;
|
|
9811
|
+
assignToA = aScore === bScore ? true : aScore > bScore;
|
|
9812
|
+
}
|
|
9813
|
+
const chosenKey = keyOf({
|
|
9814
|
+
traceIdx: assignToA ? ti : tj,
|
|
9815
|
+
edgeIdx: assignToA ? ei : ej
|
|
9816
|
+
});
|
|
9817
|
+
const chosenList = crossingsByEdge.get(chosenKey) ?? [];
|
|
9818
|
+
chosenList.push(assignToA ? dA : dB);
|
|
9819
|
+
crossingsByEdge.set(chosenKey, chosenList);
|
|
9820
|
+
}
|
|
9821
|
+
}
|
|
9822
|
+
}
|
|
9823
|
+
}
|
|
9824
|
+
}
|
|
9825
|
+
const out = traces.map((t) => ({ id: t.id, edges: [] }));
|
|
9826
|
+
for (let ti = 0; ti < traces.length; ti++) {
|
|
9827
|
+
const trace = traces[ti];
|
|
9828
|
+
for (let ei = 0; ei < trace.edges.length; ei++) {
|
|
9829
|
+
const eRefKey = keyOf({ traceIdx: ti, edgeIdx: ei });
|
|
9830
|
+
const splittingDistances = crossingsByEdge.get(eRefKey) ?? [];
|
|
9831
|
+
if (splittingDistances.length === 0) {
|
|
9832
|
+
out[ti].edges.push(trace.edges[ei]);
|
|
9833
|
+
continue;
|
|
9834
|
+
}
|
|
9835
|
+
const uniqueSorted = Array.from(
|
|
9836
|
+
new Set(splittingDistances.map((d) => Number(d.toFixed(6))))
|
|
9837
|
+
).sort((a, b) => a - b);
|
|
9838
|
+
const split = splitEdgeByCrossings(
|
|
9839
|
+
trace.edges[ei],
|
|
9840
|
+
uniqueSorted,
|
|
9841
|
+
crossLen
|
|
9842
|
+
);
|
|
9843
|
+
out[ti].edges.push(...split);
|
|
9844
|
+
}
|
|
9845
|
+
}
|
|
9846
|
+
return out;
|
|
9847
|
+
}
|
|
9848
|
+
|
|
9849
|
+
// lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/compute-junctions.ts
|
|
9850
|
+
var TOL2 = 1e-6;
|
|
9851
|
+
function nearlyEqual(a, b, tol = TOL2) {
|
|
9852
|
+
return Math.abs(a - b) <= tol;
|
|
9853
|
+
}
|
|
9854
|
+
function pointEq(a, b, tol = TOL2) {
|
|
9855
|
+
return nearlyEqual(a.x, b.x, tol) && nearlyEqual(a.y, b.y, tol);
|
|
9856
|
+
}
|
|
9857
|
+
function onSegment(p, a, b, tol = TOL2) {
|
|
9858
|
+
const minX = Math.min(a.x, b.x) - tol;
|
|
9859
|
+
const maxX = Math.max(a.x, b.x) + tol;
|
|
9860
|
+
const minY = Math.min(a.y, b.y) - tol;
|
|
9861
|
+
const maxY = Math.max(a.y, b.y) + tol;
|
|
9862
|
+
if (p.x < minX || p.x > maxX || p.y < minY || p.y > maxY) return false;
|
|
9863
|
+
const area = Math.abs((b.x - a.x) * (p.y - a.y) - (b.y - a.y) * (p.x - a.x));
|
|
9864
|
+
return area <= tol;
|
|
9865
|
+
}
|
|
9866
|
+
function dedupePoints(points, tol = TOL2) {
|
|
9867
|
+
const map = /* @__PURE__ */ new Map();
|
|
9868
|
+
for (const p of points) {
|
|
9869
|
+
const key = `${p.x.toFixed(6)},${p.y.toFixed(6)}`;
|
|
9870
|
+
if (!map.has(key)) map.set(key, p);
|
|
9871
|
+
}
|
|
9872
|
+
return Array.from(map.values());
|
|
9873
|
+
}
|
|
9874
|
+
function edgeVec(e) {
|
|
9875
|
+
return { x: e.to.x - e.from.x, y: e.to.y - e.from.y };
|
|
9876
|
+
}
|
|
9877
|
+
function isParallel(e1, e2, tol = TOL2) {
|
|
9878
|
+
const v1 = edgeVec(e1);
|
|
9879
|
+
const v2 = edgeVec(e2);
|
|
9880
|
+
const L1 = Math.hypot(v1.x, v1.y);
|
|
9881
|
+
const L2 = Math.hypot(v2.x, v2.y);
|
|
9882
|
+
if (L1 < tol || L2 < tol) return true;
|
|
9883
|
+
const cross2 = v1.x * v2.y - v1.y * v2.x;
|
|
9884
|
+
return Math.abs(cross2) <= tol * L1 * L2;
|
|
9885
|
+
}
|
|
9886
|
+
function incidentEdgesAtPoint(trace, p, tol = TOL2) {
|
|
9887
|
+
return trace.edges.filter(
|
|
9888
|
+
(e) => pointEq(e.from, p, tol) || pointEq(e.to, p, tol)
|
|
9889
|
+
);
|
|
9890
|
+
}
|
|
9891
|
+
function nearestEndpointOnTrace(trace, p, tol = TOL2) {
|
|
9892
|
+
for (const e of trace.edges) {
|
|
9893
|
+
if (pointEq(e.from, p, tol)) return e.from;
|
|
9894
|
+
if (pointEq(e.to, p, tol)) return e.to;
|
|
9895
|
+
}
|
|
9896
|
+
return null;
|
|
9897
|
+
}
|
|
9898
|
+
function edgeDirectionFromPoint(e, p, tol = TOL2) {
|
|
9899
|
+
const other = pointEq(e.from, p, tol) || nearlyEqual(e.from.x, p.x, tol) && nearlyEqual(e.from.y, p.y, tol) ? e.to : e.from;
|
|
9900
|
+
const dx = other.x - p.x;
|
|
9901
|
+
const dy = other.y - p.y;
|
|
9902
|
+
if (Math.abs(dx) < tol && Math.abs(dy) < tol) return null;
|
|
9903
|
+
if (Math.abs(dx) >= Math.abs(dy)) {
|
|
9904
|
+
return dx >= 0 ? "right" : "left";
|
|
9905
|
+
}
|
|
9906
|
+
return dy >= 0 ? "up" : "down";
|
|
9907
|
+
}
|
|
9908
|
+
function getCornerOrientationAtPoint(trace, p, tol = TOL2) {
|
|
9909
|
+
const incident = incidentEdgesAtPoint(trace, p, tol);
|
|
9910
|
+
if (incident.length < 2) return null;
|
|
9911
|
+
const dirs = incident.map((e) => edgeDirectionFromPoint(e, p, tol));
|
|
9912
|
+
const hasUp = dirs.includes("up");
|
|
9913
|
+
const hasDown = dirs.includes("down");
|
|
9914
|
+
const hasLeft = dirs.includes("left");
|
|
9915
|
+
const hasRight = dirs.includes("right");
|
|
9916
|
+
const vertical = hasUp ? "up" : hasDown ? "down" : null;
|
|
9917
|
+
const horizontal = hasRight ? "right" : hasLeft ? "left" : null;
|
|
9918
|
+
if (vertical && horizontal) {
|
|
9919
|
+
return `${vertical}-${horizontal}`;
|
|
9920
|
+
}
|
|
9921
|
+
return null;
|
|
9922
|
+
}
|
|
9923
|
+
function computeJunctions(traces, opts = {}) {
|
|
9924
|
+
const tol = opts.tolerance ?? TOL2;
|
|
9925
|
+
const result = {};
|
|
9926
|
+
for (const t of traces) result[t.id] = [];
|
|
9927
|
+
const endpointsByTrace = traces.map((t) => {
|
|
9928
|
+
const pts = [];
|
|
9929
|
+
for (const e of t.edges) {
|
|
9930
|
+
pts.push(e.from, e.to);
|
|
9931
|
+
}
|
|
9932
|
+
return dedupePoints(pts, tol);
|
|
9933
|
+
});
|
|
9934
|
+
for (let i = 0; i < traces.length; i++) {
|
|
9935
|
+
const A = traces[i];
|
|
9936
|
+
const AEnds = endpointsByTrace[i];
|
|
9937
|
+
for (let j = i + 1; j < traces.length; j++) {
|
|
9938
|
+
const B = traces[j];
|
|
9939
|
+
const BEnds = endpointsByTrace[j];
|
|
9940
|
+
for (const pa of AEnds) {
|
|
9941
|
+
for (const pb of BEnds) {
|
|
9942
|
+
if (pointEq(pa, pb, tol)) {
|
|
9943
|
+
const aEdgesAtP = incidentEdgesAtPoint(A, pa, tol);
|
|
9944
|
+
const bEdgesAtP = incidentEdgesAtPoint(B, pb, tol);
|
|
9945
|
+
const hasCorner = aEdgesAtP.some(
|
|
9946
|
+
(eA) => bEdgesAtP.some((eB) => !isParallel(eA, eB, tol))
|
|
9947
|
+
);
|
|
9948
|
+
const aCorner = getCornerOrientationAtPoint(A, pa, tol);
|
|
9949
|
+
const bCorner = getCornerOrientationAtPoint(B, pb, tol);
|
|
9950
|
+
const sameCornerOrientation = aCorner !== null && bCorner !== null && aCorner === bCorner;
|
|
9951
|
+
if (hasCorner && !sameCornerOrientation) {
|
|
9952
|
+
result[A.id].push(pa);
|
|
9953
|
+
if (A.id !== B.id) result[B.id].push(pb);
|
|
9954
|
+
}
|
|
9955
|
+
}
|
|
9956
|
+
}
|
|
9957
|
+
}
|
|
9958
|
+
for (const pa of AEnds) {
|
|
9959
|
+
for (const eB of B.edges) {
|
|
9960
|
+
if (onSegment(pa, eB.from, eB.to, tol)) {
|
|
9961
|
+
const aEdgesAtP = incidentEdgesAtPoint(A, pa, tol);
|
|
9962
|
+
const hasCorner = aEdgesAtP.some((eA) => !isParallel(eA, eB, tol));
|
|
9963
|
+
const aCorner = getCornerOrientationAtPoint(A, pa, tol);
|
|
9964
|
+
const bEndpointNearPa = nearestEndpointOnTrace(B, pa, tol * 1e3);
|
|
9965
|
+
const bCorner = bEndpointNearPa ? getCornerOrientationAtPoint(B, bEndpointNearPa, tol) : null;
|
|
9966
|
+
const sameCornerOrientation = aCorner !== null && bCorner !== null && aCorner === bCorner;
|
|
9967
|
+
if (hasCorner && !sameCornerOrientation) {
|
|
9968
|
+
result[A.id].push(pa);
|
|
9969
|
+
if (A.id !== B.id) result[B.id].push(pa);
|
|
9970
|
+
}
|
|
9971
|
+
}
|
|
9972
|
+
}
|
|
9973
|
+
}
|
|
9974
|
+
for (const pb of BEnds) {
|
|
9975
|
+
for (const eA of A.edges) {
|
|
9976
|
+
if (onSegment(pb, eA.from, eA.to, tol)) {
|
|
9977
|
+
const bEdgesAtP = incidentEdgesAtPoint(B, pb, tol);
|
|
9978
|
+
const hasCorner = bEdgesAtP.some((eB) => !isParallel(eA, eB, tol));
|
|
9979
|
+
const bCorner = getCornerOrientationAtPoint(B, pb, tol);
|
|
9980
|
+
const aEndpointNearPb = nearestEndpointOnTrace(A, pb, tol * 1e3);
|
|
9981
|
+
const aCorner = aEndpointNearPb ? getCornerOrientationAtPoint(A, aEndpointNearPb, tol) : null;
|
|
9982
|
+
const sameCornerOrientation = aCorner !== null && bCorner !== null && aCorner === bCorner;
|
|
9983
|
+
if (hasCorner && !sameCornerOrientation) {
|
|
9984
|
+
result[B.id].push(pb);
|
|
9985
|
+
if (A.id !== B.id) result[A.id].push(pb);
|
|
9986
|
+
}
|
|
9987
|
+
}
|
|
9988
|
+
}
|
|
9989
|
+
}
|
|
9990
|
+
}
|
|
9991
|
+
}
|
|
9992
|
+
for (const id of Object.keys(result)) {
|
|
9993
|
+
result[id] = dedupePoints(result[id], tol);
|
|
9994
|
+
}
|
|
9995
|
+
return result;
|
|
9996
|
+
}
|
|
9997
|
+
|
|
9998
|
+
// lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/applyTracesFromSolverOutput.ts
|
|
9999
|
+
function applyTracesFromSolverOutput(args) {
|
|
10000
|
+
const { group, solver, pinIdToSchematicPortId, pairKeyToSourceTraceId } = args;
|
|
10001
|
+
const { db } = group.root;
|
|
10002
|
+
const correctedMap = solver.traceOverlapShiftSolver?.correctedTraceMap;
|
|
10003
|
+
const pendingTraces = [];
|
|
10004
|
+
for (const solved of Object.values(correctedMap ?? {})) {
|
|
10005
|
+
const points = solved?.tracePath;
|
|
10006
|
+
if (!Array.isArray(points) || points.length < 2) continue;
|
|
10007
|
+
const edges = [];
|
|
10008
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
10009
|
+
edges.push({
|
|
10010
|
+
from: { x: points[i].x, y: points[i].y },
|
|
10011
|
+
to: { x: points[i + 1].x, y: points[i + 1].y }
|
|
10012
|
+
});
|
|
10013
|
+
}
|
|
10014
|
+
let source_trace_id = null;
|
|
10015
|
+
if (Array.isArray(solved?.pins) && solved.pins.length === 2) {
|
|
10016
|
+
const pA = pinIdToSchematicPortId.get(solved.pins[0]?.pinId);
|
|
10017
|
+
const pB = pinIdToSchematicPortId.get(solved.pins[1]?.pinId);
|
|
10018
|
+
if (pA && pB) {
|
|
10019
|
+
const pairKey = [pA, pB].sort().join("::");
|
|
10020
|
+
source_trace_id = pairKeyToSourceTraceId.get(pairKey) || `solver_${solved.mspPairId || pairKey}`;
|
|
10021
|
+
for (const schPid of [pA, pB]) {
|
|
10022
|
+
const existing = db.schematic_port.get(schPid);
|
|
10023
|
+
if (existing) db.schematic_port.update(schPid, { is_connected: true });
|
|
10024
|
+
}
|
|
10025
|
+
}
|
|
10026
|
+
}
|
|
10027
|
+
if (!source_trace_id) {
|
|
10028
|
+
source_trace_id = `solver_${solved?.mspPairId}`;
|
|
10029
|
+
}
|
|
10030
|
+
pendingTraces.push({
|
|
10031
|
+
id: source_trace_id,
|
|
10032
|
+
edges
|
|
10033
|
+
});
|
|
10034
|
+
}
|
|
10035
|
+
const withCrossings = computeCrossings(
|
|
10036
|
+
pendingTraces.map((t) => ({ id: t.id, edges: t.edges }))
|
|
10037
|
+
);
|
|
10038
|
+
const junctionsById = computeJunctions(withCrossings);
|
|
10039
|
+
for (const t of withCrossings) {
|
|
10040
|
+
db.schematic_trace.insert({
|
|
10041
|
+
source_trace_id: t.id,
|
|
10042
|
+
edges: t.edges,
|
|
10043
|
+
junctions: junctionsById[t.id] ?? []
|
|
10044
|
+
});
|
|
10045
|
+
}
|
|
10046
|
+
}
|
|
10047
|
+
|
|
10048
|
+
// lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/applyNetLabelPlacements.ts
|
|
10049
|
+
import "@tscircuit/schematic-trace-solver";
|
|
10050
|
+
|
|
10051
|
+
// lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/oppositeSide.ts
|
|
10052
|
+
var oppositeSide = (input) => {
|
|
10053
|
+
switch (input) {
|
|
10054
|
+
case "x+":
|
|
10055
|
+
return "left";
|
|
10056
|
+
case "x-":
|
|
10057
|
+
return "right";
|
|
10058
|
+
case "y+":
|
|
10059
|
+
return "bottom";
|
|
10060
|
+
case "y-":
|
|
10061
|
+
return "top";
|
|
10062
|
+
case "left":
|
|
10063
|
+
return "right";
|
|
10064
|
+
case "top":
|
|
10065
|
+
return "bottom";
|
|
10066
|
+
case "right":
|
|
10067
|
+
return "left";
|
|
10068
|
+
case "bottom":
|
|
10069
|
+
return "top";
|
|
10070
|
+
}
|
|
10071
|
+
};
|
|
10072
|
+
|
|
10073
|
+
// lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/applyNetLabelPlacements.ts
|
|
10074
|
+
function applyNetLabelPlacements(args) {
|
|
10075
|
+
const {
|
|
10076
|
+
group,
|
|
10077
|
+
solver,
|
|
10078
|
+
sckToSourceNet,
|
|
10079
|
+
allScks,
|
|
10080
|
+
allSourceAndSchematicPortIdsInScope,
|
|
10081
|
+
schPortIdToSourcePortId,
|
|
10082
|
+
userNetIdToSck
|
|
10083
|
+
} = args;
|
|
10084
|
+
const { db } = group.root;
|
|
10085
|
+
const netLabelPlacements = solver.netLabelPlacementSolver?.netLabelPlacements ?? [];
|
|
10086
|
+
const globalConnMap = solver.mspConnectionPairSolver.globalConnMap;
|
|
10087
|
+
for (const placement of netLabelPlacements) {
|
|
10088
|
+
const placementUserNetId = globalConnMap.getIdsConnectedToNet(placement.globalConnNetId).find((id) => userNetIdToSck.get(id));
|
|
10089
|
+
const placementSck = userNetIdToSck.get(placementUserNetId);
|
|
10090
|
+
const anchor_position = placement.anchorPoint;
|
|
10091
|
+
const orientation = placement.orientation;
|
|
10092
|
+
const anchor_side = oppositeSide(orientation);
|
|
10093
|
+
const sourceNet = placementSck ? sckToSourceNet.get(placementSck) : void 0;
|
|
10094
|
+
if (!sourceNet) {
|
|
10095
|
+
continue;
|
|
10096
|
+
}
|
|
10097
|
+
const text = sourceNet.name;
|
|
10098
|
+
const center = placement.center ?? computeSchematicNetLabelCenter({
|
|
10099
|
+
anchor_position,
|
|
10100
|
+
anchor_side,
|
|
10101
|
+
text
|
|
10102
|
+
});
|
|
10103
|
+
db.schematic_net_label.insert({
|
|
10104
|
+
text,
|
|
10105
|
+
anchor_position,
|
|
10106
|
+
center,
|
|
10107
|
+
anchor_side,
|
|
10108
|
+
...sourceNet?.source_net_id ? { source_net_id: sourceNet.source_net_id } : {}
|
|
10109
|
+
});
|
|
10110
|
+
}
|
|
10111
|
+
}
|
|
10112
|
+
|
|
10113
|
+
// lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/insertNetLabelsForTracesExcludedFromRouting.ts
|
|
10114
|
+
import "@tscircuit/schematic-trace-solver";
|
|
10115
|
+
function insertNetLabelsForTracesExcludedFromRouting(args) {
|
|
10116
|
+
const { group, displayLabelTraces } = args;
|
|
10117
|
+
const { db } = group.root;
|
|
10118
|
+
for (const trace of displayLabelTraces) {
|
|
10119
|
+
const label = trace._parsedProps?.schDisplayLabel;
|
|
10120
|
+
if (!label) continue;
|
|
10121
|
+
try {
|
|
10122
|
+
const res = trace._findConnectedPorts?.();
|
|
10123
|
+
if (!res?.allPortsFound || !res.ports || res.ports.length < 1) continue;
|
|
10124
|
+
const ports = res.ports.slice(0, 2);
|
|
10125
|
+
for (const port of ports) {
|
|
10126
|
+
const anchor_position = port._getGlobalSchematicPositionAfterLayout();
|
|
10127
|
+
const side = getEnteringEdgeFromDirection(port.facingDirection || "right") || "right";
|
|
10128
|
+
const center = computeSchematicNetLabelCenter({
|
|
10129
|
+
anchor_position,
|
|
10130
|
+
anchor_side: side,
|
|
10131
|
+
text: label
|
|
10132
|
+
});
|
|
10133
|
+
db.schematic_net_label.insert({
|
|
10134
|
+
text: label,
|
|
10135
|
+
anchor_position,
|
|
10136
|
+
center,
|
|
10137
|
+
anchor_side: side,
|
|
10138
|
+
...trace.source_trace_id ? { source_trace_id: trace.source_trace_id } : {}
|
|
10139
|
+
});
|
|
10140
|
+
}
|
|
10141
|
+
} catch {
|
|
10142
|
+
}
|
|
10143
|
+
}
|
|
10144
|
+
}
|
|
10145
|
+
|
|
10146
|
+
// lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/insertNetLabelsForPortsMissingTrace.ts
|
|
10147
|
+
var insertNetLabelsForPortsMissingTrace = ({
|
|
10148
|
+
allSourceAndSchematicPortIdsInScope,
|
|
10149
|
+
group,
|
|
10150
|
+
schPortIdToSourcePortId,
|
|
10151
|
+
sckToSourceNet: connKeyToNet
|
|
10152
|
+
}) => {
|
|
10153
|
+
const { db } = group.root;
|
|
10154
|
+
for (const schOrSrcPortId of Array.from(
|
|
10155
|
+
allSourceAndSchematicPortIdsInScope
|
|
10156
|
+
)) {
|
|
10157
|
+
const sp = db.schematic_port.get(schOrSrcPortId);
|
|
10158
|
+
if (!sp) continue;
|
|
10159
|
+
if (sp.is_connected) continue;
|
|
10160
|
+
const srcPortId = schPortIdToSourcePortId.get(schOrSrcPortId);
|
|
10161
|
+
if (!srcPortId) continue;
|
|
10162
|
+
const sourcePort = db.source_port.get(srcPortId);
|
|
10163
|
+
const key = sourcePort?.subcircuit_connectivity_map_key;
|
|
10164
|
+
if (!key) continue;
|
|
10165
|
+
const sourceNet = connKeyToNet.get(key);
|
|
10166
|
+
if (!sourceNet) {
|
|
10167
|
+
continue;
|
|
10168
|
+
}
|
|
10169
|
+
const existingAtPort = db.schematic_net_label.list().some((nl) => {
|
|
10170
|
+
const samePos = Math.abs(nl.anchor_position.x - sp.center.x) < 1e-6 && Math.abs(nl.anchor_position.y - sp.center.y) < 1e-6;
|
|
10171
|
+
if (!samePos) return false;
|
|
10172
|
+
if (sourceNet.source_net_id && nl.source_net_id) {
|
|
10173
|
+
return nl.source_net_id === sourceNet.source_net_id;
|
|
10174
|
+
}
|
|
10175
|
+
return nl.text === (sourceNet.name || key);
|
|
10176
|
+
});
|
|
10177
|
+
if (existingAtPort) continue;
|
|
10178
|
+
const text = sourceNet.name || sourceNet.source_net_id || key;
|
|
10179
|
+
const side = getEnteringEdgeFromDirection(sp.facing_direction || "right") || "right";
|
|
10180
|
+
const center = computeSchematicNetLabelCenter({
|
|
10181
|
+
anchor_position: sp.center,
|
|
10182
|
+
anchor_side: side,
|
|
10183
|
+
text
|
|
10184
|
+
});
|
|
10185
|
+
db.schematic_net_label.insert({
|
|
10186
|
+
text,
|
|
10187
|
+
anchor_position: sp.center,
|
|
10188
|
+
center,
|
|
10189
|
+
anchor_side: side,
|
|
10190
|
+
...sourceNet.source_net_id ? { source_net_id: sourceNet.source_net_id } : {}
|
|
10191
|
+
});
|
|
10192
|
+
}
|
|
10193
|
+
};
|
|
10194
|
+
|
|
10195
|
+
// lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/Group_doInitialSchematicTraceRender.ts
|
|
10196
|
+
var debug7 = Debug8("Group_doInitialSchematicTraceRender");
|
|
10197
|
+
var Group_doInitialSchematicTraceRender = (group) => {
|
|
10198
|
+
if (!group.root?._featureMspSchematicTraceRouting) return;
|
|
10199
|
+
if (!group.isSubcircuit) return;
|
|
10200
|
+
if (group.root?.schematicDisabled) return;
|
|
10201
|
+
const {
|
|
10202
|
+
inputProblem,
|
|
10203
|
+
pinIdToSchematicPortId,
|
|
10204
|
+
pairKeyToSourceTraceId,
|
|
10205
|
+
sckToSourceNet,
|
|
10206
|
+
allSourceAndSchematicPortIdsInScope,
|
|
10207
|
+
schPortIdToSourcePortId,
|
|
10208
|
+
displayLabelTraces,
|
|
10209
|
+
allScks,
|
|
10210
|
+
userNetIdToSck
|
|
10211
|
+
} = createSchematicTraceSolverInputProblem(group);
|
|
10212
|
+
if (debug7.enabled) {
|
|
10213
|
+
globalThis.debugOutputs?.add(
|
|
10214
|
+
"group-trace-render-input-problem",
|
|
10215
|
+
JSON.stringify(inputProblem, null, 2)
|
|
10216
|
+
);
|
|
10217
|
+
}
|
|
10218
|
+
const solver = new SchematicTracePipelineSolver4(inputProblem);
|
|
10219
|
+
solver.solve();
|
|
10220
|
+
applyTracesFromSolverOutput({
|
|
10221
|
+
group,
|
|
10222
|
+
solver,
|
|
10223
|
+
pinIdToSchematicPortId,
|
|
10224
|
+
pairKeyToSourceTraceId
|
|
10225
|
+
});
|
|
10226
|
+
applyNetLabelPlacements({
|
|
10227
|
+
group,
|
|
10228
|
+
solver,
|
|
10229
|
+
sckToSourceNet,
|
|
10230
|
+
allSourceAndSchematicPortIdsInScope,
|
|
10231
|
+
schPortIdToSourcePortId,
|
|
10232
|
+
allScks,
|
|
10233
|
+
userNetIdToSck
|
|
10234
|
+
});
|
|
10235
|
+
insertNetLabelsForPortsMissingTrace({
|
|
10236
|
+
group,
|
|
10237
|
+
allSourceAndSchematicPortIdsInScope,
|
|
10238
|
+
schPortIdToSourcePortId,
|
|
10239
|
+
sckToSourceNet
|
|
10240
|
+
});
|
|
10241
|
+
insertNetLabelsForTracesExcludedFromRouting({
|
|
10242
|
+
group,
|
|
10243
|
+
solver,
|
|
10244
|
+
displayLabelTraces
|
|
10245
|
+
});
|
|
10246
|
+
};
|
|
10247
|
+
|
|
10248
|
+
// lib/components/primitive-components/Group/Group.ts
|
|
10249
|
+
var Group6 = class extends NormalComponent {
|
|
9505
10250
|
constructor() {
|
|
9506
10251
|
super(...arguments);
|
|
9507
10252
|
__publicField(this, "pcb_group_id", null);
|
|
@@ -9669,20 +10414,20 @@ var Group = class extends NormalComponent {
|
|
|
9669
10414
|
return false;
|
|
9670
10415
|
}
|
|
9671
10416
|
_hasTracesToRoute() {
|
|
9672
|
-
const
|
|
10417
|
+
const debug8 = Debug9("tscircuit:core:_hasTracesToRoute");
|
|
9673
10418
|
const traces = this.selectAll("trace");
|
|
9674
|
-
|
|
10419
|
+
debug8(`[${this.getString()}] has ${traces.length} traces to route`);
|
|
9675
10420
|
return traces.length > 0;
|
|
9676
10421
|
}
|
|
9677
10422
|
async _runEffectMakeHttpAutoroutingRequest() {
|
|
9678
10423
|
const { db } = this.root;
|
|
9679
|
-
const
|
|
10424
|
+
const debug8 = Debug9("tscircuit:core:_runEffectMakeHttpAutoroutingRequest");
|
|
9680
10425
|
const props = this._parsedProps;
|
|
9681
10426
|
const autorouterConfig = this._getAutorouterConfig();
|
|
9682
10427
|
const serverUrl = autorouterConfig.serverUrl;
|
|
9683
10428
|
const serverMode = autorouterConfig.serverMode;
|
|
9684
10429
|
const fetchWithDebug = (url, options) => {
|
|
9685
|
-
|
|
10430
|
+
debug8("fetching", url);
|
|
9686
10431
|
if (options.headers) {
|
|
9687
10432
|
options.headers["Tscircuit-Core-Version"] = this.root?.getCoreVersion();
|
|
9688
10433
|
}
|
|
@@ -9798,15 +10543,15 @@ var Group = class extends NormalComponent {
|
|
|
9798
10543
|
async _runLocalAutorouting() {
|
|
9799
10544
|
const { db } = this.root;
|
|
9800
10545
|
const props = this._parsedProps;
|
|
9801
|
-
const
|
|
9802
|
-
|
|
10546
|
+
const debug8 = Debug9("tscircuit:core:_runLocalAutorouting");
|
|
10547
|
+
debug8(`[${this.getString()}] starting local autorouting`);
|
|
9803
10548
|
const autorouterConfig = this._getAutorouterConfig();
|
|
9804
10549
|
const { simpleRouteJson } = getSimpleRouteJsonFromCircuitJson({
|
|
9805
10550
|
db,
|
|
9806
10551
|
minTraceWidth: this.props.autorouter?.minTraceWidth ?? 0.15,
|
|
9807
10552
|
subcircuit_id: this.subcircuit_id
|
|
9808
10553
|
});
|
|
9809
|
-
if (
|
|
10554
|
+
if (debug8.enabled) {
|
|
9810
10555
|
const graphicsObject = convertSrjToGraphicsObject(
|
|
9811
10556
|
simpleRouteJson
|
|
9812
10557
|
);
|
|
@@ -9831,11 +10576,11 @@ var Group = class extends NormalComponent {
|
|
|
9831
10576
|
const routingPromise = new Promise(
|
|
9832
10577
|
(resolve, reject) => {
|
|
9833
10578
|
autorouter.on("complete", (event) => {
|
|
9834
|
-
|
|
10579
|
+
debug8(`[${this.getString()}] local autorouting complete`);
|
|
9835
10580
|
resolve(event.traces);
|
|
9836
10581
|
});
|
|
9837
10582
|
autorouter.on("error", (event) => {
|
|
9838
|
-
|
|
10583
|
+
debug8(
|
|
9839
10584
|
`[${this.getString()}] local autorouting error: ${event.error.message}`
|
|
9840
10585
|
);
|
|
9841
10586
|
reject(event.error);
|
|
@@ -9892,30 +10637,33 @@ var Group = class extends NormalComponent {
|
|
|
9892
10637
|
}
|
|
9893
10638
|
}
|
|
9894
10639
|
doInitialPcbTraceRender() {
|
|
9895
|
-
const
|
|
10640
|
+
const debug8 = Debug9("tscircuit:core:doInitialPcbTraceRender");
|
|
9896
10641
|
if (!this.isSubcircuit) return;
|
|
9897
10642
|
if (this.root?.pcbDisabled) return;
|
|
9898
10643
|
if (this.getInheritedProperty("routingDisabled")) return;
|
|
9899
10644
|
if (this._shouldUseTraceByTraceRouting()) return;
|
|
9900
10645
|
if (!this._areChildSubcircuitsRouted()) {
|
|
9901
|
-
|
|
10646
|
+
debug8(
|
|
9902
10647
|
`[${this.getString()}] child subcircuits are not routed, skipping async autorouting until subcircuits routed`
|
|
9903
10648
|
);
|
|
9904
10649
|
return;
|
|
9905
10650
|
}
|
|
9906
|
-
|
|
10651
|
+
debug8(
|
|
9907
10652
|
`[${this.getString()}] no child subcircuits to wait for, initiating async routing`
|
|
9908
10653
|
);
|
|
9909
10654
|
if (!this._hasTracesToRoute()) return;
|
|
9910
10655
|
this._startAsyncAutorouting();
|
|
9911
10656
|
}
|
|
10657
|
+
doInitialSchematicTraceRender() {
|
|
10658
|
+
Group_doInitialSchematicTraceRender(this);
|
|
10659
|
+
}
|
|
9912
10660
|
updatePcbTraceRender() {
|
|
9913
|
-
const
|
|
9914
|
-
|
|
10661
|
+
const debug8 = Debug9("tscircuit:core:updatePcbTraceRender");
|
|
10662
|
+
debug8(`[${this.getString()}] updating...`);
|
|
9915
10663
|
if (!this.isSubcircuit) return;
|
|
9916
10664
|
if (this._shouldRouteAsync() && this._hasTracesToRoute() && !this._hasStartedAsyncAutorouting) {
|
|
9917
10665
|
if (this._areChildSubcircuitsRouted()) {
|
|
9918
|
-
|
|
10666
|
+
debug8(
|
|
9919
10667
|
`[${this.getString()}] child subcircuits are now routed, starting async autorouting`
|
|
9920
10668
|
);
|
|
9921
10669
|
this._startAsyncAutorouting();
|
|
@@ -9926,14 +10674,14 @@ var Group = class extends NormalComponent {
|
|
|
9926
10674
|
if (this._shouldUseTraceByTraceRouting()) return;
|
|
9927
10675
|
const { db } = this.root;
|
|
9928
10676
|
if (this._asyncAutoroutingResult.output_simple_route_json) {
|
|
9929
|
-
|
|
10677
|
+
debug8(
|
|
9930
10678
|
`[${this.getString()}] updating PCB traces from simple route json (${this._asyncAutoroutingResult.output_simple_route_json.traces?.length} traces)`
|
|
9931
10679
|
);
|
|
9932
10680
|
this._updatePcbTraceRenderFromSimpleRouteJson();
|
|
9933
10681
|
return;
|
|
9934
10682
|
}
|
|
9935
10683
|
if (this._asyncAutoroutingResult.output_pcb_traces) {
|
|
9936
|
-
|
|
10684
|
+
debug8(
|
|
9937
10685
|
`[${this.getString()}] updating PCB traces from ${this._asyncAutoroutingResult.output_pcb_traces.length} traces`
|
|
9938
10686
|
);
|
|
9939
10687
|
this._updatePcbTraceRenderFromPcbTraces();
|
|
@@ -10237,7 +10985,7 @@ import {
|
|
|
10237
10985
|
checkEachPcbPortConnectedToPcbTraces,
|
|
10238
10986
|
checkEachPcbTraceNonOverlapping
|
|
10239
10987
|
} from "@tscircuit/checks";
|
|
10240
|
-
var Board = class extends
|
|
10988
|
+
var Board = class extends Group6 {
|
|
10241
10989
|
constructor() {
|
|
10242
10990
|
super(...arguments);
|
|
10243
10991
|
__publicField(this, "pcb_board_id", null);
|
|
@@ -11413,7 +12161,7 @@ var FabricationNoteText = class extends PrimitiveComponent2 {
|
|
|
11413
12161
|
|
|
11414
12162
|
// lib/components/primitive-components/Group/Subcircuit.ts
|
|
11415
12163
|
import "@tscircuit/props";
|
|
11416
|
-
var Subcircuit = class extends
|
|
12164
|
+
var Subcircuit = class extends Group6 {
|
|
11417
12165
|
constructor(props) {
|
|
11418
12166
|
super({
|
|
11419
12167
|
...props,
|
|
@@ -11424,7 +12172,7 @@ var Subcircuit = class extends Group {
|
|
|
11424
12172
|
|
|
11425
12173
|
// lib/components/primitive-components/Breakout/Breakout.ts
|
|
11426
12174
|
import "@tscircuit/props";
|
|
11427
|
-
var Breakout = class extends
|
|
12175
|
+
var Breakout = class extends Group6 {
|
|
11428
12176
|
constructor(props) {
|
|
11429
12177
|
super({
|
|
11430
12178
|
...props,
|
|
@@ -12855,7 +13603,7 @@ import { identity as identity5 } from "transformation-matrix";
|
|
|
12855
13603
|
var package_default = {
|
|
12856
13604
|
name: "@tscircuit/core",
|
|
12857
13605
|
type: "module",
|
|
12858
|
-
version: "0.0.
|
|
13606
|
+
version: "0.0.645",
|
|
12859
13607
|
types: "dist/index.d.ts",
|
|
12860
13608
|
main: "dist/index.js",
|
|
12861
13609
|
module: "dist/index.js",
|
|
@@ -12885,8 +13633,8 @@ var package_default = {
|
|
|
12885
13633
|
devDependencies: {
|
|
12886
13634
|
"@biomejs/biome": "^1.8.3",
|
|
12887
13635
|
"@tscircuit/capacity-autorouter": "^0.0.100",
|
|
12888
|
-
"@tscircuit/circuit-json-util": "^0.0.65",
|
|
12889
13636
|
"@tscircuit/checks": "^0.0.71",
|
|
13637
|
+
"@tscircuit/circuit-json-util": "^0.0.65",
|
|
12890
13638
|
"@tscircuit/footprinter": "^0.0.208",
|
|
12891
13639
|
"@tscircuit/import-snippet": "^0.0.4",
|
|
12892
13640
|
"@tscircuit/infgrid-ijump-astar": "^0.0.33",
|
|
@@ -12898,6 +13646,7 @@ var package_default = {
|
|
|
12898
13646
|
"@tscircuit/schematic-autolayout": "^0.0.6",
|
|
12899
13647
|
"@tscircuit/schematic-corpus": "^0.0.110",
|
|
12900
13648
|
"@tscircuit/schematic-match-adapt": "^0.0.16",
|
|
13649
|
+
"@tscircuit/schematic-trace-solver": "^0.0.12",
|
|
12901
13650
|
"@tscircuit/simple-3d-svg": "^0.0.38",
|
|
12902
13651
|
"@types/bun": "^1.2.16",
|
|
12903
13652
|
"@types/debug": "^4.1.12",
|
|
@@ -12914,6 +13663,7 @@ var package_default = {
|
|
|
12914
13663
|
"circuit-json-to-simple-3d": "^0.0.6",
|
|
12915
13664
|
"circuit-to-svg": "^0.0.174",
|
|
12916
13665
|
concurrently: "^9.1.2",
|
|
13666
|
+
"connectivity-map": "^1.0.0",
|
|
12917
13667
|
debug: "^4.3.6",
|
|
12918
13668
|
"graphics-debug": "^0.0.60",
|
|
12919
13669
|
howfat: "^0.3.8",
|
|
@@ -12974,6 +13724,7 @@ var RootCircuit = class {
|
|
|
12974
13724
|
__publicField(this, "schematicDisabled", false);
|
|
12975
13725
|
__publicField(this, "pcbDisabled", false);
|
|
12976
13726
|
__publicField(this, "pcbRoutingDisabled", false);
|
|
13727
|
+
__publicField(this, "_featureMspSchematicTraceRouting", false);
|
|
12977
13728
|
/**
|
|
12978
13729
|
* The RootCircuit name is usually set by the platform, it's not required but
|
|
12979
13730
|
* if supplied can identify the circuit in certain effects, e.g. it is passed
|
|
@@ -13024,7 +13775,7 @@ var RootCircuit = class {
|
|
|
13024
13775
|
this.firstChild = this.children[0];
|
|
13025
13776
|
return;
|
|
13026
13777
|
}
|
|
13027
|
-
const group = new
|
|
13778
|
+
const group = new Group6({ subcircuit: true });
|
|
13028
13779
|
group.parent = this;
|
|
13029
13780
|
group.addAll(this.children);
|
|
13030
13781
|
this.children = [group];
|
|
@@ -13363,7 +14114,7 @@ export {
|
|
|
13363
14114
|
FabricationNoteText,
|
|
13364
14115
|
Footprint,
|
|
13365
14116
|
Fuse,
|
|
13366
|
-
Group,
|
|
14117
|
+
Group6 as Group,
|
|
13367
14118
|
Hole,
|
|
13368
14119
|
Inductor,
|
|
13369
14120
|
Jumper,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.646",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@biomejs/biome": "^1.8.3",
|
|
33
33
|
"@tscircuit/capacity-autorouter": "^0.0.100",
|
|
34
|
-
"@tscircuit/circuit-json-util": "^0.0.65",
|
|
35
34
|
"@tscircuit/checks": "^0.0.71",
|
|
35
|
+
"@tscircuit/circuit-json-util": "^0.0.65",
|
|
36
36
|
"@tscircuit/footprinter": "^0.0.208",
|
|
37
37
|
"@tscircuit/import-snippet": "^0.0.4",
|
|
38
38
|
"@tscircuit/infgrid-ijump-astar": "^0.0.33",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"@tscircuit/schematic-autolayout": "^0.0.6",
|
|
45
45
|
"@tscircuit/schematic-corpus": "^0.0.110",
|
|
46
46
|
"@tscircuit/schematic-match-adapt": "^0.0.16",
|
|
47
|
+
"@tscircuit/schematic-trace-solver": "^0.0.12",
|
|
47
48
|
"@tscircuit/simple-3d-svg": "^0.0.38",
|
|
48
49
|
"@types/bun": "^1.2.16",
|
|
49
50
|
"@types/debug": "^4.1.12",
|
|
@@ -60,6 +61,7 @@
|
|
|
60
61
|
"circuit-json-to-simple-3d": "^0.0.6",
|
|
61
62
|
"circuit-to-svg": "^0.0.174",
|
|
62
63
|
"concurrently": "^9.1.2",
|
|
64
|
+
"connectivity-map": "^1.0.0",
|
|
63
65
|
"debug": "^4.3.6",
|
|
64
66
|
"graphics-debug": "^0.0.60",
|
|
65
67
|
"howfat": "^0.3.8",
|