@tscircuit/checks 0.0.160 → 0.0.162
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/README.md +4 -2
- package/dist/index.d.ts +14 -5
- package/dist/index.js +161 -10
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ and output an array of arrays for any issues found.
|
|
|
14
14
|
| [`checkAllPinsInComponentAreUnderspecified`](./lib/check-all-pins-in-component-are-underspecified.ts) | Returns `source_component_pins_underspecified_warning` when every pin on a chip lacks pin attributes. |
|
|
15
15
|
| [`checkNoPowerPinDefined`](./lib/check-no-power-pin-defined.ts) | Returns `source_no_power_pin_defined_warning` when a chip has no pin with `requires_power=true`. |
|
|
16
16
|
| [`checkNoGroundPinDefined`](./lib/check-no-ground-pin-defined.ts) | Returns `source_no_ground_pin_defined_warning` when a chip has no pin with `requires_ground=true`. |
|
|
17
|
+
| [`checkSchematicComponentExcessiveVerticalPadding`](./lib/check-schematic-component-excessive-vertical-padding.ts) | Returns a `schematic_component_styling_warning` with `styling_issue_type: "excessive_top_padding"` or `"excessive_bottom_padding"` when a box-style component has more than three pin spacings of empty space above or below its left/right pins. |
|
|
17
18
|
| [`checkDifferentNetViaSpacing`](./lib/check-different-net-via-spacing.ts) | Returns `pcb_via_clearance_error` if vias on different nets are too close together. |
|
|
18
19
|
| [`checkEachPcbPortConnectedToPcbTraces`](./lib/check-each-pcb-port-connected-to-pcb-trace.ts) | Returns `pcb_trace_error` if any `source_port` is not connected to its corresponding PCB traces. |
|
|
19
20
|
| [`checkEachPcbTraceNonOverlapping`](./lib/check-each-pcb-trace-non-overlapping/check-each-pcb-trace-non-overlapping.ts) | Returns `pcb_trace_error` when `pcb_trace` segments physically overlap incompatible geometry on the same layer. Pad/via near-misses are reported by the typed clearance checks instead. |
|
|
@@ -27,7 +28,7 @@ and output an array of arrays for any issues found.
|
|
|
27
28
|
| [`checkSourceTracesHavePcbTraces`](./lib/check-source-traces-have-pcb-traces.ts) | Returns `pcb_trace_error` when source traces are missing corresponding `pcb_trace` routes. |
|
|
28
29
|
| [`checkTracesAreContiguous`](./lib/check-traces-are-contiguous/check-traces-are-contiguous.ts) | Returns `pcb_trace_error` when trace endpoints are floating or do not connect as expected. |
|
|
29
30
|
| [`checkViasOffBoard`](./lib/check-pcb-components-out-of-board/checkViasOffBoard.ts) | Returns `pcb_placement_error` if any PCB via lies outside or crosses the board boundary. |
|
|
30
|
-
| [`checkCopperToBoardEdgeClearance`](./lib/check-copper-to-board-edge-clearance.ts) | Checks via, SMT-pad,
|
|
31
|
+
| [`checkCopperToBoardEdgeClearance`](./lib/check-copper-to-board-edge-clearance.ts) | Checks via, SMT-pad, plated-hole, and copper-pour geometry against the polygon board outline and required edge clearance. |
|
|
31
32
|
|
|
32
33
|
## Aggregate check runner functions
|
|
33
34
|
|
|
@@ -36,8 +37,9 @@ and output an array of arrays for any issues found.
|
|
|
36
37
|
| [`runAllPlacementChecks`](./lib/run-all-checks.ts) | Runs placement checks (`checkCopperToBoardEdgeClearance`, `checkPcbComponentsOutOfBoard`, `checkPcbComponentOverlap`, `checkPadPadClearance`, `checkCourtyardOverlap`, `checkConnectorAccessibleOrientation`, and `checkTestPointAccessibility`). |
|
|
37
38
|
| [`runAllNetlistChecks`](./lib/run-all-checks.ts) | Runs netlist connectivity checks (currently `checkPinMustBeConnected`). |
|
|
38
39
|
| [`runAllPinSpecificationChecks`](./lib/run-all-checks.ts) | Runs pin specification checks (e.g. `checkAllPinsInComponentAreUnderspecified`, `checkNoPowerPinDefined`, and `checkNoGroundPinDefined`). |
|
|
40
|
+
| [`runAllSchematicChecks`](./lib/run-all-checks.ts) | Runs schematic-layout checks (currently `checkSchematicComponentExcessiveVerticalPadding`). |
|
|
39
41
|
| [`runAllRoutingChecks`](./lib/run-all-checks.ts) | Runs all routing checks currently enabled (`checkEachPcbPortConnectedToPcbTraces`, `checkSourceTracesHavePcbTraces`, `checkEachPcbTraceNonOverlapping`, `checkPadTraceClearance`, `checkViaTraceClearance`, same/different net via spacing, and `checkPcbTracesOutOfBoard`). Trace-obstacle pairs are classified before aggregation, so each pair produces one overlap or clearance diagnostic, never both. |
|
|
40
|
-
| [`runAllChecks`](./lib/run-all-checks.ts) | Runs placement, netlist, pin specification, and routing checks and returns a combined list of issues. |
|
|
42
|
+
| [`runAllChecks`](./lib/run-all-checks.ts) | Runs placement, schematic, netlist, pin specification, and routing checks and returns a combined list of issues. |
|
|
41
43
|
|
|
42
44
|
## Implementation Details
|
|
43
45
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as circuit_json from 'circuit-json';
|
|
2
|
-
import { AnyCircuitElement, PcbPortNotConnectedError, PcbTraceError, PcbPlacementError, PcbComponentOutsideBoardError, PcbViaClearanceError, PcbTraceWarning, PcbTraceMissingError, PcbFootprintOverlapError, PcbTraceTooLongWarning, PcbPadPadClearanceError, PcbPadTraceClearanceError, PcbViaTraceClearanceError, SourceComponentPinsUnderspecifiedWarning, SourceNoPowerPinDefinedWarning, SourceNoGroundPinDefinedWarning, PcbConnectorNotInAccessibleOrientationWarning } from 'circuit-json';
|
|
2
|
+
import { AnyCircuitElement, PcbPortNotConnectedError, PcbTraceError, PcbPlacementError, PcbComponentOutsideBoardError, PcbViaClearanceError, PcbTraceWarning, PcbTraceMissingError, PcbFootprintOverlapError, PcbTraceTooLongWarning, PcbPadPadClearanceError, PcbPadTraceClearanceError, PcbViaTraceClearanceError, SourceComponentPinsUnderspecifiedWarning, SourceNoPowerPinDefinedWarning, SourceNoGroundPinDefinedWarning, SchematicComponentStylingWarning, PcbConnectorNotInAccessibleOrientationWarning } from 'circuit-json';
|
|
3
3
|
import { ConnectivityMap } from 'circuit-json-to-connectivity-map';
|
|
4
4
|
|
|
5
5
|
declare function checkEachPcbPortConnectedToPcbTraces(circuitJson: AnyCircuitElement[]): PcbPortNotConnectedError[];
|
|
@@ -18,8 +18,9 @@ declare class NetManager {
|
|
|
18
18
|
declare function checkViasOffBoard(circuitJson: AnyCircuitElement[]): PcbPlacementError[];
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
|
-
* Checks the finished copper geometry of every via, SMT pad,
|
|
22
|
-
* against the real board outline and its configured edge-clearance
|
|
21
|
+
* Checks the finished copper geometry of every via, SMT pad, plated hole, and
|
|
22
|
+
* copper pour against the real board outline and its configured edge-clearance
|
|
23
|
+
* rule.
|
|
23
24
|
*
|
|
24
25
|
* Component and footprint rotations are normally composed into Circuit JSON's
|
|
25
26
|
* absolute coordinates and `ccw_rotation` fields. Polygon-pad plated holes are
|
|
@@ -152,6 +153,13 @@ declare function checkNoPowerPinDefined(circuitJson: AnyCircuitElement[]): Sourc
|
|
|
152
153
|
*/
|
|
153
154
|
declare function checkNoGroundPinDefined(circuitJson: AnyCircuitElement[]): SourceNoGroundPinDefinedWarning[];
|
|
154
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Warns when the left/right pins of a box-style schematic component leave
|
|
158
|
+
* excessive empty space above or below their vertical span. This commonly
|
|
159
|
+
* happens when an unnecessarily large schematic height is set on a component.
|
|
160
|
+
*/
|
|
161
|
+
declare function checkSchematicComponentExcessiveVerticalPadding(circuitJson: AnyCircuitElement[]): SchematicComponentStylingWarning[];
|
|
162
|
+
|
|
155
163
|
declare function runAllPlacementChecks(circuitJson: AnyCircuitElement[]): Promise<(circuit_json.PcbPlacementError | circuit_json.PcbComponentOutsideBoardError | circuit_json.PcbFootprintOverlapError | circuit_json.PcbPadPadClearanceError | circuit_json.PcbConnectorNotInAccessibleOrientationWarning | circuit_json.PcbCourtyardOverlapError)[]>;
|
|
156
164
|
declare function runAllNetlistChecks(circuitJson: AnyCircuitElement[]): Promise<{
|
|
157
165
|
type: "source_pin_must_be_connected_error";
|
|
@@ -162,6 +170,7 @@ declare function runAllNetlistChecks(circuitJson: AnyCircuitElement[]): Promise<
|
|
|
162
170
|
source_port_id: string;
|
|
163
171
|
subcircuit_id?: string;
|
|
164
172
|
}[]>;
|
|
173
|
+
declare function runAllSchematicChecks(circuitJson: AnyCircuitElement[]): Promise<circuit_json.SchematicComponentStylingWarning[]>;
|
|
165
174
|
declare function runAllPinSpecificationChecks(circuitJson: AnyCircuitElement[]): Promise<(circuit_json.SourceComponentPinsUnderspecifiedWarning | circuit_json.SourceNoPowerPinDefinedWarning | circuit_json.SourceNoGroundPinDefinedWarning)[]>;
|
|
166
175
|
declare function runAllRoutingChecks(circuitJson: AnyCircuitElement[]): Promise<(circuit_json.PcbPortNotConnectedError | circuit_json.PcbTraceError | circuit_json.PcbViaClearanceError | circuit_json.PcbTraceMissingError | circuit_json.PcbTraceTooLongWarning | circuit_json.PcbPadPadClearanceError | circuit_json.PcbPadTraceClearanceError | circuit_json.PcbViaTraceClearanceError)[]>;
|
|
167
176
|
declare function runAllChecks(circuitJson: AnyCircuitElement[]): Promise<(circuit_json.PcbPortNotConnectedError | circuit_json.PcbTraceError | circuit_json.PcbPlacementError | circuit_json.PcbComponentOutsideBoardError | circuit_json.PcbViaClearanceError | circuit_json.PcbTraceMissingError | circuit_json.PcbFootprintOverlapError | circuit_json.PcbTraceTooLongWarning | circuit_json.PcbPadPadClearanceError | circuit_json.PcbPadTraceClearanceError | circuit_json.PcbViaTraceClearanceError | {
|
|
@@ -172,7 +181,7 @@ declare function runAllChecks(circuitJson: AnyCircuitElement[]): Promise<(circui
|
|
|
172
181
|
source_component_id: string;
|
|
173
182
|
source_port_id: string;
|
|
174
183
|
subcircuit_id?: string;
|
|
175
|
-
} | circuit_json.SourceComponentPinsUnderspecifiedWarning | circuit_json.SourceNoPowerPinDefinedWarning | circuit_json.SourceNoGroundPinDefinedWarning | circuit_json.PcbConnectorNotInAccessibleOrientationWarning | circuit_json.PcbCourtyardOverlapError)[]>;
|
|
184
|
+
} | circuit_json.SourceComponentPinsUnderspecifiedWarning | circuit_json.SourceNoPowerPinDefinedWarning | circuit_json.SourceNoGroundPinDefinedWarning | circuit_json.SchematicComponentStylingWarning | circuit_json.PcbConnectorNotInAccessibleOrientationWarning | circuit_json.PcbCourtyardOverlapError)[]>;
|
|
176
185
|
|
|
177
186
|
declare function checkConnectorAccessibleOrientation(circuitJson: AnyCircuitElement[]): PcbConnectorNotInAccessibleOrientationWarning[];
|
|
178
187
|
|
|
@@ -183,4 +192,4 @@ declare function checkConnectorAccessibleOrientation(circuitJson: AnyCircuitElem
|
|
|
183
192
|
*/
|
|
184
193
|
declare function checkTestPointAccessibility(circuitJson: AnyCircuitElement[]): PcbPlacementError[];
|
|
185
194
|
|
|
186
|
-
export { NetManager, checkAllPinsInComponentAreUnderspecified, checkConnectorAccessibleOrientation, checkCopperToBoardEdgeClearance, checkDifferentNetViaSpacing, checkEachPcbPortConnectedToPcbTraces, checkEachPcbTraceNonOverlapping, checkNoGroundPinDefined, checkNoPowerPinDefined, checkPadPadClearance, checkPadTraceClearance, checkPcbComponentOverCutout, checkPcbComponentOverlap, checkPcbComponentsOutOfBoard, checkPcbTraceLengths, checkPcbTracesOutOfBoard, checkPinMustBeConnected, checkSameNetViaSpacing, checkSourceTracesHavePcbTraces, checkSourceTracesMatchPcbTraceThickness, checkTestPointAccessibility, checkTracesAreContiguous, checkViaPadClearance, checkViaTraceClearance, checkViasInPads, checkViasOffBoard, dedupePcbDrcErrors, runAllChecks, runAllNetlistChecks, runAllPinSpecificationChecks, runAllPlacementChecks, runAllRoutingChecks };
|
|
195
|
+
export { NetManager, checkAllPinsInComponentAreUnderspecified, checkConnectorAccessibleOrientation, checkCopperToBoardEdgeClearance, checkDifferentNetViaSpacing, checkEachPcbPortConnectedToPcbTraces, checkEachPcbTraceNonOverlapping, checkNoGroundPinDefined, checkNoPowerPinDefined, checkPadPadClearance, checkPadTraceClearance, checkPcbComponentOverCutout, checkPcbComponentOverlap, checkPcbComponentsOutOfBoard, checkPcbTraceLengths, checkPcbTracesOutOfBoard, checkPinMustBeConnected, checkSameNetViaSpacing, checkSchematicComponentExcessiveVerticalPadding, checkSourceTracesHavePcbTraces, checkSourceTracesMatchPcbTraceThickness, checkTestPointAccessibility, checkTracesAreContiguous, checkViaPadClearance, checkViaTraceClearance, checkViasInPads, checkViasOffBoard, dedupePcbDrcErrors, runAllChecks, runAllNetlistChecks, runAllPinSpecificationChecks, runAllPlacementChecks, runAllRoutingChecks, runAllSchematicChecks };
|
package/dist/index.js
CHANGED
|
@@ -1536,6 +1536,57 @@ var pointsToPolygon = (points) => {
|
|
|
1536
1536
|
if (points.length < 3) return null;
|
|
1537
1537
|
return new Flatten.Polygon(points.map(({ x, y }) => new Flatten.Point(x, y)));
|
|
1538
1538
|
};
|
|
1539
|
+
var brepRingToPolygon = (vertices) => {
|
|
1540
|
+
const ring = vertices.filter((vertex, index) => {
|
|
1541
|
+
const previous = vertices[index - 1];
|
|
1542
|
+
return !previous || Math.abs(previous.x - vertex.x) > GEOMETRY_EPSILON || Math.abs(previous.y - vertex.y) > GEOMETRY_EPSILON;
|
|
1543
|
+
});
|
|
1544
|
+
if (ring.length > 1 && Math.abs(ring[0].x - ring.at(-1).x) <= GEOMETRY_EPSILON && Math.abs(ring[0].y - ring.at(-1).y) <= GEOMETRY_EPSILON) {
|
|
1545
|
+
ring.pop();
|
|
1546
|
+
}
|
|
1547
|
+
if (ring.length < 3) return null;
|
|
1548
|
+
const edges = [];
|
|
1549
|
+
for (let index = 0; index < ring.length; index++) {
|
|
1550
|
+
const start = ring[index];
|
|
1551
|
+
const end = ring[(index + 1) % ring.length];
|
|
1552
|
+
const startPoint = new Flatten.Point(start.x, start.y);
|
|
1553
|
+
const endPoint = new Flatten.Point(end.x, end.y);
|
|
1554
|
+
const bulge = start.bulge ?? 0;
|
|
1555
|
+
if (Math.abs(bulge) <= GEOMETRY_EPSILON) {
|
|
1556
|
+
edges.push(new Flatten.Segment(startPoint, endPoint));
|
|
1557
|
+
continue;
|
|
1558
|
+
}
|
|
1559
|
+
const chordLength = startPoint.distanceTo(endPoint)[0];
|
|
1560
|
+
if (chordLength <= GEOMETRY_EPSILON) continue;
|
|
1561
|
+
const midpoint2 = {
|
|
1562
|
+
x: (start.x + end.x) / 2,
|
|
1563
|
+
y: (start.y + end.y) / 2
|
|
1564
|
+
};
|
|
1565
|
+
const leftNormal = {
|
|
1566
|
+
x: -(end.y - start.y) / chordLength,
|
|
1567
|
+
y: (end.x - start.x) / chordLength
|
|
1568
|
+
};
|
|
1569
|
+
const centerOffset = chordLength * (1 - bulge * bulge) / (4 * bulge);
|
|
1570
|
+
const center = new Flatten.Point(
|
|
1571
|
+
midpoint2.x + leftNormal.x * centerOffset,
|
|
1572
|
+
midpoint2.y + leftNormal.y * centerOffset
|
|
1573
|
+
);
|
|
1574
|
+
const radius = chordLength * (1 + bulge * bulge) / (4 * Math.abs(bulge));
|
|
1575
|
+
edges.push(
|
|
1576
|
+
new Flatten.Arc(
|
|
1577
|
+
center,
|
|
1578
|
+
radius,
|
|
1579
|
+
Math.atan2(start.y - center.y, start.x - center.x),
|
|
1580
|
+
Math.atan2(end.y - center.y, end.x - center.x),
|
|
1581
|
+
bulge > 0
|
|
1582
|
+
)
|
|
1583
|
+
);
|
|
1584
|
+
}
|
|
1585
|
+
if (edges.length < 3) return null;
|
|
1586
|
+
const polygon = new Flatten.Polygon();
|
|
1587
|
+
polygon.addFace(edges);
|
|
1588
|
+
return polygon;
|
|
1589
|
+
};
|
|
1539
1590
|
var boardToPolygon = (board) => {
|
|
1540
1591
|
if (board.outline && board.outline.length >= 3) {
|
|
1541
1592
|
return pointsToPolygon(board.outline);
|
|
@@ -1773,22 +1824,45 @@ var getCopperGeometry = (element, componentCcwRotationsById) => {
|
|
|
1773
1824
|
};
|
|
1774
1825
|
}
|
|
1775
1826
|
if (element.type === "pcb_smtpad") return getSmtPadGeometry(element);
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1827
|
+
if (element.type === "pcb_plated_hole") {
|
|
1828
|
+
return getPlatedHoleGeometry(
|
|
1829
|
+
element,
|
|
1830
|
+
element.pcb_component_id ? componentCcwRotationsById.get(
|
|
1831
|
+
toPcbComponentId(element.pcb_component_id)
|
|
1832
|
+
) ?? 0 : 0
|
|
1833
|
+
);
|
|
1834
|
+
}
|
|
1835
|
+
let polygon;
|
|
1836
|
+
switch (element.shape) {
|
|
1837
|
+
case "rect":
|
|
1838
|
+
polygon = getRectanglePolygon({
|
|
1839
|
+
x: element.center.x,
|
|
1840
|
+
y: element.center.y,
|
|
1841
|
+
width: element.width,
|
|
1842
|
+
height: element.height,
|
|
1843
|
+
ccwRotationDegrees: element.rotation ?? 0
|
|
1844
|
+
});
|
|
1845
|
+
break;
|
|
1846
|
+
case "polygon":
|
|
1847
|
+
polygon = pointsToPolygon(element.points);
|
|
1848
|
+
break;
|
|
1849
|
+
case "brep":
|
|
1850
|
+
polygon = brepRingToPolygon(element.brep_shape.outer_ring.vertices);
|
|
1851
|
+
break;
|
|
1852
|
+
}
|
|
1853
|
+
return polygon ? { kind: "shapes", shapes: [polygon] } : null;
|
|
1782
1854
|
};
|
|
1783
1855
|
var getCopperElementId = (element) => {
|
|
1784
1856
|
if (element.type === "pcb_via") return element.pcb_via_id;
|
|
1785
1857
|
if (element.type === "pcb_smtpad") return element.pcb_smtpad_id;
|
|
1786
|
-
return element.pcb_plated_hole_id;
|
|
1858
|
+
if (element.type === "pcb_plated_hole") return element.pcb_plated_hole_id;
|
|
1859
|
+
return element.pcb_copper_pour_id;
|
|
1787
1860
|
};
|
|
1788
1861
|
var getCopperElementLabel = (element) => {
|
|
1789
1862
|
if (element.type === "pcb_via") return "Via";
|
|
1790
1863
|
if (element.type === "pcb_smtpad") return "SMT pad";
|
|
1791
|
-
return "Plated hole";
|
|
1864
|
+
if (element.type === "pcb_plated_hole") return "Plated hole";
|
|
1865
|
+
return "Copper pour";
|
|
1792
1866
|
};
|
|
1793
1867
|
var measureClearance = (board, geometry) => {
|
|
1794
1868
|
if (geometry.kind === "shapes") {
|
|
@@ -1816,7 +1890,7 @@ function checkCopperToBoardEdgeClearance(circuitJson) {
|
|
|
1816
1890
|
const requiredClearance = getBoardDrcValue(board, "min_board_edge_clearance") ?? jlcMinTolerances.min_board_edge_clearance;
|
|
1817
1891
|
if (requiredClearance === void 0) return [];
|
|
1818
1892
|
const copperElements = circuitJson.filter(
|
|
1819
|
-
(element) => element.type === "pcb_via" || element.type === "pcb_smtpad" || element.type === "pcb_plated_hole"
|
|
1893
|
+
(element) => element.type === "pcb_via" || element.type === "pcb_smtpad" || element.type === "pcb_plated_hole" || element.type === "pcb_copper_pour"
|
|
1820
1894
|
);
|
|
1821
1895
|
const componentCcwRotationsById = new Map(
|
|
1822
1896
|
circuitJson.filter(
|
|
@@ -3557,6 +3631,77 @@ function checkNoGroundPinDefined(circuitJson) {
|
|
|
3557
3631
|
return warnings;
|
|
3558
3632
|
}
|
|
3559
3633
|
|
|
3634
|
+
// lib/check-schematic-component-excessive-vertical-padding.ts
|
|
3635
|
+
var DEFAULT_PIN_SPACING = 0.2;
|
|
3636
|
+
var MAX_VERTICAL_PADDING_IN_PIN_SPACINGS = 3;
|
|
3637
|
+
var FLOATING_POINT_TOLERANCE = 1e-9;
|
|
3638
|
+
function checkSchematicComponentExcessiveVerticalPadding(circuitJson) {
|
|
3639
|
+
const schematicComponents = circuitJson.filter(
|
|
3640
|
+
(element) => element.type === "schematic_component"
|
|
3641
|
+
);
|
|
3642
|
+
const schematicPorts = circuitJson.filter(
|
|
3643
|
+
(element) => element.type === "schematic_port"
|
|
3644
|
+
);
|
|
3645
|
+
const sourceComponents = circuitJson.filter(
|
|
3646
|
+
(element) => element.type === "source_component"
|
|
3647
|
+
);
|
|
3648
|
+
const sourceComponentById = new Map(
|
|
3649
|
+
sourceComponents.map((component) => [
|
|
3650
|
+
component.source_component_id,
|
|
3651
|
+
component
|
|
3652
|
+
])
|
|
3653
|
+
);
|
|
3654
|
+
const portsByComponentId = /* @__PURE__ */ new Map();
|
|
3655
|
+
for (const port of schematicPorts) {
|
|
3656
|
+
if (!port.schematic_component_id) continue;
|
|
3657
|
+
const componentPorts = portsByComponentId.get(port.schematic_component_id) ?? [];
|
|
3658
|
+
componentPorts.push(port);
|
|
3659
|
+
portsByComponentId.set(port.schematic_component_id, componentPorts);
|
|
3660
|
+
}
|
|
3661
|
+
const warnings = [];
|
|
3662
|
+
for (const component of schematicComponents) {
|
|
3663
|
+
if (!component.is_box_with_pins || component.size.height <= 0) continue;
|
|
3664
|
+
const sidePorts = (portsByComponentId.get(component.schematic_component_id) ?? []).filter(
|
|
3665
|
+
(port) => port.side_of_component === "left" || port.side_of_component === "right"
|
|
3666
|
+
);
|
|
3667
|
+
if (sidePorts.length < 2) continue;
|
|
3668
|
+
const pinYs = sidePorts.map((port) => port.center.y);
|
|
3669
|
+
const highestPinY = Math.max(...pinYs);
|
|
3670
|
+
const lowestPinY = Math.min(...pinYs);
|
|
3671
|
+
const componentTopY = component.center.y + component.size.height / 2;
|
|
3672
|
+
const componentBottomY = component.center.y - component.size.height / 2;
|
|
3673
|
+
const pinSpacing = component.pin_spacing ?? DEFAULT_PIN_SPACING;
|
|
3674
|
+
const maximumPadding = pinSpacing * MAX_VERTICAL_PADDING_IN_PIN_SPACINGS;
|
|
3675
|
+
const paddingBySide = {
|
|
3676
|
+
top: componentTopY - highestPinY,
|
|
3677
|
+
bottom: lowestPinY - componentBottomY
|
|
3678
|
+
};
|
|
3679
|
+
const sourceComponent = component.source_component_id ? sourceComponentById.get(component.source_component_id) : void 0;
|
|
3680
|
+
const componentName = sourceComponent?.name ?? component.schematic_component_id;
|
|
3681
|
+
for (const side of ["top", "bottom"]) {
|
|
3682
|
+
const padding = paddingBySide[side];
|
|
3683
|
+
if (padding <= maximumPadding + FLOATING_POINT_TOLERANCE || padding <= 0) {
|
|
3684
|
+
continue;
|
|
3685
|
+
}
|
|
3686
|
+
const relativePosition = side === "top" ? "above" : "below";
|
|
3687
|
+
const stylingIssueType = `excessive_${side}_padding`;
|
|
3688
|
+
warnings.push({
|
|
3689
|
+
type: "schematic_component_styling_warning",
|
|
3690
|
+
schematic_component_styling_warning_id: `schematic_component_styling_warning_${component.schematic_component_id}_${stylingIssueType}`,
|
|
3691
|
+
warning_type: "schematic_component_styling_warning",
|
|
3692
|
+
message: `${componentName} has excessive empty space ${relativePosition} its pins (${padding.toFixed(2)}mm, more than ${MAX_VERTICAL_PADDING_IN_PIN_SPACINGS} pin spacings)`,
|
|
3693
|
+
schematic_component_id: component.schematic_component_id,
|
|
3694
|
+
styling_issue_type: stylingIssueType,
|
|
3695
|
+
schematic_port_ids: sidePorts.map((port) => port.schematic_port_id),
|
|
3696
|
+
source_component_id: component.source_component_id,
|
|
3697
|
+
schematic_sheet_id: component.schematic_sheet_id,
|
|
3698
|
+
subcircuit_id: component.subcircuit_id
|
|
3699
|
+
});
|
|
3700
|
+
}
|
|
3701
|
+
}
|
|
3702
|
+
return warnings;
|
|
3703
|
+
}
|
|
3704
|
+
|
|
3560
3705
|
// lib/check-connector-accessible-orientation.ts
|
|
3561
3706
|
import { getBoardBounds } from "@tscircuit/circuit-json-util";
|
|
3562
3707
|
function getFacingDirectionFromInsertionDirection(component) {
|
|
@@ -3841,6 +3986,9 @@ async function runAllPlacementChecks(circuitJson) {
|
|
|
3841
3986
|
async function runAllNetlistChecks(circuitJson) {
|
|
3842
3987
|
return [...checkPinMustBeConnected(circuitJson)];
|
|
3843
3988
|
}
|
|
3989
|
+
async function runAllSchematicChecks(circuitJson) {
|
|
3990
|
+
return checkSchematicComponentExcessiveVerticalPadding(circuitJson);
|
|
3991
|
+
}
|
|
3844
3992
|
async function runAllPinSpecificationChecks(circuitJson) {
|
|
3845
3993
|
return [
|
|
3846
3994
|
...checkAllPinsInComponentAreUnderspecified(circuitJson),
|
|
@@ -3866,6 +4014,7 @@ async function runAllRoutingChecks(circuitJson) {
|
|
|
3866
4014
|
async function runAllChecks(circuitJson) {
|
|
3867
4015
|
return [
|
|
3868
4016
|
...await runAllPlacementChecks(circuitJson),
|
|
4017
|
+
...await runAllSchematicChecks(circuitJson),
|
|
3869
4018
|
...await runAllNetlistChecks(circuitJson),
|
|
3870
4019
|
...await runAllPinSpecificationChecks(circuitJson),
|
|
3871
4020
|
...await runAllRoutingChecks(circuitJson)
|
|
@@ -3890,6 +4039,7 @@ export {
|
|
|
3890
4039
|
checkPcbTracesOutOfBoard,
|
|
3891
4040
|
checkPinMustBeConnected,
|
|
3892
4041
|
checkSameNetViaSpacing,
|
|
4042
|
+
checkSchematicComponentExcessiveVerticalPadding,
|
|
3893
4043
|
checkSourceTracesHavePcbTraces,
|
|
3894
4044
|
checkSourceTracesMatchPcbTraceThickness,
|
|
3895
4045
|
checkTestPointAccessibility,
|
|
@@ -3903,6 +4053,7 @@ export {
|
|
|
3903
4053
|
runAllNetlistChecks,
|
|
3904
4054
|
runAllPinSpecificationChecks,
|
|
3905
4055
|
runAllPlacementChecks,
|
|
3906
|
-
runAllRoutingChecks
|
|
4056
|
+
runAllRoutingChecks,
|
|
4057
|
+
runAllSchematicChecks
|
|
3907
4058
|
};
|
|
3908
4059
|
//# sourceMappingURL=index.js.map
|