@tscircuit/core 0.0.1429 → 0.0.1430
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +123 -79
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2546,51 +2546,29 @@ var isRouteOutsideBoard = ({
|
|
|
2546
2546
|
);
|
|
2547
2547
|
};
|
|
2548
2548
|
|
|
2549
|
-
// lib/utils/obstacles/
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
const
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
const
|
|
2557
|
-
const
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
);
|
|
2562
|
-
}
|
|
2563
|
-
const obstacle = {
|
|
2564
|
-
type: "rect",
|
|
2565
|
-
layers: [start.layer],
|
|
2566
|
-
center: {
|
|
2567
|
-
x: (start.x + end.x) / 2,
|
|
2568
|
-
y: (start.y + end.y) / 2
|
|
2569
|
-
},
|
|
2570
|
-
width: isHorz ? Math.abs(start.x - end.x) : 0.1,
|
|
2571
|
-
// TODO use route width
|
|
2572
|
-
height: isVert ? Math.abs(start.y - end.y) : 0.1,
|
|
2573
|
-
// TODO use route width
|
|
2574
|
-
connectedTo: [source_trace_id]
|
|
2575
|
-
};
|
|
2576
|
-
obstacles.push(obstacle);
|
|
2577
|
-
if (prev && prev.layer === start.layer && start.layer !== end.layer) {
|
|
2578
|
-
const via = {
|
|
2579
|
-
type: "rect",
|
|
2580
|
-
layers: [start.layer, end.layer],
|
|
2549
|
+
// lib/utils/obstacles/fillCircleWithRects.ts
|
|
2550
|
+
function fillCircleWithRects(circle, options = {}) {
|
|
2551
|
+
const { center, radius } = circle;
|
|
2552
|
+
const { rectHeight = 0.1 } = options;
|
|
2553
|
+
const rects = [];
|
|
2554
|
+
const numSlices = Math.ceil(radius * 2 / rectHeight);
|
|
2555
|
+
for (let i = 0; i < numSlices; i++) {
|
|
2556
|
+
const y = center.y - radius + (i + 0.5) * rectHeight;
|
|
2557
|
+
const dy = y - center.y;
|
|
2558
|
+
const halfWidth = Math.sqrt(radius * radius - dy * dy);
|
|
2559
|
+
if (halfWidth > 0) {
|
|
2560
|
+
rects.push({
|
|
2581
2561
|
center: {
|
|
2582
|
-
x:
|
|
2583
|
-
y
|
|
2562
|
+
x: center.x,
|
|
2563
|
+
y
|
|
2584
2564
|
},
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
};
|
|
2589
|
-
obstacles.push(via);
|
|
2565
|
+
width: halfWidth * 2,
|
|
2566
|
+
height: rectHeight
|
|
2567
|
+
});
|
|
2590
2568
|
}
|
|
2591
2569
|
}
|
|
2592
|
-
return
|
|
2593
|
-
}
|
|
2570
|
+
return rects;
|
|
2571
|
+
}
|
|
2594
2572
|
|
|
2595
2573
|
// lib/utils/obstacles/fillPolygonWithRects.ts
|
|
2596
2574
|
function fillPolygonWithRects(polygon, options = {}) {
|
|
@@ -2633,29 +2611,88 @@ function fillPolygonWithRects(polygon, options = {}) {
|
|
|
2633
2611
|
return rects;
|
|
2634
2612
|
}
|
|
2635
2613
|
|
|
2636
|
-
// lib/utils/obstacles/
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
const
|
|
2640
|
-
const
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2614
|
+
// lib/utils/obstacles/getAxisAlignedRectFromPolygon.ts
|
|
2615
|
+
var AXIS_ALIGNED_RECT_TOLERANCE_MM = 1e-3;
|
|
2616
|
+
var getAxisAlignedRectFromPolygon = (points) => {
|
|
2617
|
+
const isCloseTo2 = (a, b) => Math.abs(a - b) <= AXIS_ALIGNED_RECT_TOLERANCE_MM;
|
|
2618
|
+
const normalizedPoints = points.filter(
|
|
2619
|
+
(point6, index) => index === 0 || !isCloseTo2(point6.x, points[index - 1].x) || !isCloseTo2(point6.y, points[index - 1].y)
|
|
2620
|
+
);
|
|
2621
|
+
if (normalizedPoints.length > 1 && isCloseTo2(normalizedPoints[0].x, normalizedPoints.at(-1).x) && isCloseTo2(normalizedPoints[0].y, normalizedPoints.at(-1).y)) {
|
|
2622
|
+
normalizedPoints.pop();
|
|
2623
|
+
}
|
|
2624
|
+
if (normalizedPoints.length < 4) return null;
|
|
2625
|
+
const minX = Math.min(...normalizedPoints.map((point6) => point6.x));
|
|
2626
|
+
const maxX = Math.max(...normalizedPoints.map((point6) => point6.x));
|
|
2627
|
+
const minY = Math.min(...normalizedPoints.map((point6) => point6.y));
|
|
2628
|
+
const maxY = Math.max(...normalizedPoints.map((point6) => point6.y));
|
|
2629
|
+
const expectedCorners = [
|
|
2630
|
+
{ x: minX, y: minY },
|
|
2631
|
+
{ x: minX, y: maxY },
|
|
2632
|
+
{ x: maxX, y: minY },
|
|
2633
|
+
{ x: maxX, y: maxY }
|
|
2634
|
+
];
|
|
2635
|
+
if (!normalizedPoints.every(
|
|
2636
|
+
(point6) => isCloseTo2(point6.x, minX) || isCloseTo2(point6.x, maxX) || isCloseTo2(point6.y, minY) || isCloseTo2(point6.y, maxY)
|
|
2637
|
+
) || !expectedCorners.every(
|
|
2638
|
+
(corner) => normalizedPoints.some(
|
|
2639
|
+
(point6) => isCloseTo2(point6.x, corner.x) && isCloseTo2(point6.y, corner.y)
|
|
2640
|
+
)
|
|
2641
|
+
)) {
|
|
2642
|
+
return null;
|
|
2643
|
+
}
|
|
2644
|
+
return {
|
|
2645
|
+
center: { x: (minX + maxX) / 2, y: (minY + maxY) / 2 },
|
|
2646
|
+
width: maxX - minX,
|
|
2647
|
+
height: maxY - minY
|
|
2648
|
+
};
|
|
2649
|
+
};
|
|
2650
|
+
|
|
2651
|
+
// lib/utils/obstacles/getObstaclesFromRoute.ts
|
|
2652
|
+
var isCloseTo = (a, b) => Math.abs(a - b) < 1e-4;
|
|
2653
|
+
var getObstaclesFromRoute = (route, source_trace_id, { viaDiameter = 0.5 } = {}) => {
|
|
2654
|
+
const obstacles = [];
|
|
2655
|
+
for (let i = 0; i < route.length - 1; i++) {
|
|
2656
|
+
const [start, end] = [route[i], route[i + 1]];
|
|
2657
|
+
const prev = i - 1 >= 0 ? route[i - 1] : null;
|
|
2658
|
+
const isHorz = isCloseTo(start.y, end.y);
|
|
2659
|
+
const isVert = isCloseTo(start.x, end.x);
|
|
2660
|
+
if (!isHorz && !isVert) {
|
|
2661
|
+
throw new Error(
|
|
2662
|
+
`getObstaclesFromTrace currently only supports horizontal and vertical traces (not diagonals) Conflicting trace: ${source_trace_id}, start: (${start.x}, ${start.y}), end: (${end.x}, ${end.y})`
|
|
2663
|
+
);
|
|
2664
|
+
}
|
|
2665
|
+
const obstacle = {
|
|
2666
|
+
type: "rect",
|
|
2667
|
+
layers: [start.layer],
|
|
2668
|
+
center: {
|
|
2669
|
+
x: (start.x + end.x) / 2,
|
|
2670
|
+
y: (start.y + end.y) / 2
|
|
2671
|
+
},
|
|
2672
|
+
width: isHorz ? Math.abs(start.x - end.x) : 0.1,
|
|
2673
|
+
// TODO use route width
|
|
2674
|
+
height: isVert ? Math.abs(start.y - end.y) : 0.1,
|
|
2675
|
+
// TODO use route width
|
|
2676
|
+
connectedTo: [source_trace_id]
|
|
2677
|
+
};
|
|
2678
|
+
obstacles.push(obstacle);
|
|
2679
|
+
if (prev && prev.layer === start.layer && start.layer !== end.layer) {
|
|
2680
|
+
const via = {
|
|
2681
|
+
type: "rect",
|
|
2682
|
+
layers: [start.layer, end.layer],
|
|
2648
2683
|
center: {
|
|
2649
|
-
x:
|
|
2650
|
-
y
|
|
2684
|
+
x: start.x,
|
|
2685
|
+
y: start.y
|
|
2651
2686
|
},
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2687
|
+
connectedTo: [source_trace_id],
|
|
2688
|
+
width: viaDiameter,
|
|
2689
|
+
height: viaDiameter
|
|
2690
|
+
};
|
|
2691
|
+
obstacles.push(via);
|
|
2655
2692
|
}
|
|
2656
2693
|
}
|
|
2657
|
-
return
|
|
2658
|
-
}
|
|
2694
|
+
return obstacles;
|
|
2695
|
+
};
|
|
2659
2696
|
|
|
2660
2697
|
// lib/utils/obstacles/getObstaclesFromCircuitJson.ts
|
|
2661
2698
|
var EVERY_LAYER = ["top", "inner1", "inner2", "bottom"];
|
|
@@ -2729,7 +2766,7 @@ var getObstaclesFromCircuitJson = (circuitJson, connMap) => {
|
|
|
2729
2766
|
center: rect.center,
|
|
2730
2767
|
width: rect.width,
|
|
2731
2768
|
height: rect.height,
|
|
2732
|
-
ccwRotationDegrees: element.ccw_rotation,
|
|
2769
|
+
ccwRotationDegrees: axisAlignedRect ? void 0 : element.ccw_rotation,
|
|
2733
2770
|
connectedTo: withNetId([element.pcb_smtpad_id])
|
|
2734
2771
|
});
|
|
2735
2772
|
} else if (element.shape === "pill" || element.shape === "rotated_pill") {
|
|
@@ -2747,24 +2784,31 @@ var getObstaclesFromCircuitJson = (circuitJson, connMap) => {
|
|
|
2747
2784
|
connectedTo: withNetId([element.pcb_smtpad_id])
|
|
2748
2785
|
});
|
|
2749
2786
|
} else if (element.shape === "polygon") {
|
|
2750
|
-
const
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
},
|
|
2764
|
-
width: maxX - minX,
|
|
2765
|
-
height: maxY - minY,
|
|
2766
|
-
connectedTo: withNetId([element.pcb_smtpad_id])
|
|
2787
|
+
const axisAlignedRect = getAxisAlignedRectFromPolygon(element.points);
|
|
2788
|
+
if (axisAlignedRect) {
|
|
2789
|
+
obstacles.push({
|
|
2790
|
+
componentId: pcbComponentId,
|
|
2791
|
+
type: "rect",
|
|
2792
|
+
layers: [element.layer],
|
|
2793
|
+
...axisAlignedRect,
|
|
2794
|
+
connectedTo: withNetId([element.pcb_smtpad_id])
|
|
2795
|
+
});
|
|
2796
|
+
continue;
|
|
2797
|
+
}
|
|
2798
|
+
const approximatingRects = fillPolygonWithRects(element.points, {
|
|
2799
|
+
rectHeight: 0.1
|
|
2767
2800
|
});
|
|
2801
|
+
for (const rect of approximatingRects) {
|
|
2802
|
+
obstacles.push({
|
|
2803
|
+
componentId: pcbComponentId,
|
|
2804
|
+
type: "rect",
|
|
2805
|
+
layers: [element.layer],
|
|
2806
|
+
center: rect.center,
|
|
2807
|
+
width: rect.width,
|
|
2808
|
+
height: rect.height,
|
|
2809
|
+
connectedTo: withNetId([element.pcb_smtpad_id])
|
|
2810
|
+
});
|
|
2811
|
+
}
|
|
2768
2812
|
}
|
|
2769
2813
|
} else if (element.type === "pcb_keepout") {
|
|
2770
2814
|
if (element.shape === "circle") {
|
|
@@ -22352,7 +22396,7 @@ function Group_getRoutingPhasePlans(group) {
|
|
|
22352
22396
|
var package_default = {
|
|
22353
22397
|
name: "@tscircuit/core",
|
|
22354
22398
|
type: "module",
|
|
22355
|
-
version: "0.0.
|
|
22399
|
+
version: "0.0.1429",
|
|
22356
22400
|
types: "dist/index.d.ts",
|
|
22357
22401
|
main: "dist/index.js",
|
|
22358
22402
|
module: "dist/index.js",
|