@tscircuit/core 0.0.1967 → 0.0.1969
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 -3
- package/dist/index.js +329 -393
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -369,9 +369,9 @@ interface IIsolatedCircuit {
|
|
|
369
369
|
interface IRootCircuit extends IIsolatedCircuit {
|
|
370
370
|
}
|
|
371
371
|
|
|
372
|
-
declare const orderedRenderPhases: readonly ["ReactSubtreesRender", "RenderIsolatedSubcircuits", "InflateSubcircuitCircuitJson", "SourceNameDuplicateComponentRemoval", "PcbFootprintStringRender", "FetchPartFootprint", "ResolveFootprintPinLabels", "InitializePortsFromChildren", "CreateNetsFromProps", "AssignFallbackProps", "CreateTracesFromProps", "CreateTracesFromNetLabels", "CreateTraceHintsFromProps", "CreateAutoplacedBreakoutPoints", "SourceGroupRender", "AssignNameToUnnamedComponents", "SourceRender", "CheckRefDesConvention", "SourceComponentPropertyValidation", "SourceParentAttachment", "PortMatching", "OptimizeSelectorCache", "SourceTraceRender", "SourceAddConnectivityMapKey", "SourceDesignRuleChecks", "SimulationRender", "SchematicComponentRender", "SchematicPortRender", "SymbolContainerRender", "SchematicPrimitiveRender", "SchematicSymbolResize", "SchematicComponentSizeCalculation", "SchematicLayout", "SchematicSectionRender", "SchematicTraceRender", "SchematicSheetRender", "SchematicReplaceNetLabelsWithSymbols", "SchematicLabelNetsWithConflictingNames", "PanelBoardLayout", "ValidatePcbCoordinates", "PcbComponentRender", "PcbPrimitiveRender", "PcbFootprintLayout", "PcbPortRender", "PcbPortAttachment", "PcbComponentSizeCalculation", "PcbComponentAnchorAlignment", "PcbCalcPlacementResolution", "PcbLayout", "PcbBoardAutoSize", "PanelLayout", "PcbFlexRender", "PcbAutoplaceBreakoutPoints", "PcbTraceHintRender", "PcbManualTraceRender", "PcbPlacementDesignRuleChecks", "PcbTraceRender", "PcbRouteNetIslands", "
|
|
372
|
+
declare const orderedRenderPhases: readonly ["ReactSubtreesRender", "RenderIsolatedSubcircuits", "InflateSubcircuitCircuitJson", "SourceNameDuplicateComponentRemoval", "PcbFootprintStringRender", "FetchPartFootprint", "ResolveFootprintPinLabels", "InitializePortsFromChildren", "CreateNetsFromProps", "AssignFallbackProps", "CreateTracesFromProps", "CreateTracesFromNetLabels", "CreateTraceHintsFromProps", "CreateAutoplacedBreakoutPoints", "SourceGroupRender", "AssignNameToUnnamedComponents", "SourceRender", "CheckRefDesConvention", "SourceComponentPropertyValidation", "SourceParentAttachment", "PortMatching", "OptimizeSelectorCache", "SourceTraceRender", "SourceAddConnectivityMapKey", "SourceDesignRuleChecks", "SimulationRender", "SchematicComponentRender", "SchematicPortRender", "SymbolContainerRender", "SchematicPrimitiveRender", "SchematicSymbolResize", "SchematicComponentSizeCalculation", "SchematicLayout", "SchematicSectionRender", "SchematicTraceRender", "SchematicSheetRender", "SchematicReplaceNetLabelsWithSymbols", "SchematicLabelNetsWithConflictingNames", "PanelBoardLayout", "ValidatePcbCoordinates", "PcbComponentRender", "PcbPrimitiveRender", "PcbFootprintLayout", "PcbPortRender", "PcbPortAttachment", "PcbComponentSizeCalculation", "PcbComponentAnchorAlignment", "PcbCalcPlacementResolution", "PcbLayout", "PcbBoardAutoSize", "PanelLayout", "PcbFlexRender", "PcbAutoplaceBreakoutPoints", "PcbTraceHintRender", "PcbManualTraceRender", "PcbPlacementDesignRuleChecks", "PcbTraceRender", "PcbRouteNetIslands", "PcbCopperPourRender", "PcbViaStitchRender", "PcbCopperPourCleanup", "PcbDesignRuleChecks", "SilkscreenOverlapAdjustment", "CadModelRender", "PartsEngineRender", "PartOrientationAnalysis", "SupplierFootprintMismatchWarning", "SimulationSpiceEngineRender"];
|
|
373
373
|
type RenderPhase = (typeof orderedRenderPhases)[number];
|
|
374
|
-
declare const renderPhaseIndexMap: Map<"ReactSubtreesRender" | "RenderIsolatedSubcircuits" | "InflateSubcircuitCircuitJson" | "SourceNameDuplicateComponentRemoval" | "PcbFootprintStringRender" | "FetchPartFootprint" | "ResolveFootprintPinLabels" | "InitializePortsFromChildren" | "CreateNetsFromProps" | "AssignFallbackProps" | "CreateTracesFromProps" | "CreateTracesFromNetLabels" | "CreateTraceHintsFromProps" | "CreateAutoplacedBreakoutPoints" | "SourceGroupRender" | "AssignNameToUnnamedComponents" | "SourceRender" | "CheckRefDesConvention" | "SourceComponentPropertyValidation" | "SourceParentAttachment" | "PortMatching" | "OptimizeSelectorCache" | "SourceTraceRender" | "SourceAddConnectivityMapKey" | "SourceDesignRuleChecks" | "SimulationRender" | "SchematicComponentRender" | "SchematicPortRender" | "SymbolContainerRender" | "SchematicPrimitiveRender" | "SchematicSymbolResize" | "SchematicComponentSizeCalculation" | "SchematicLayout" | "SchematicSectionRender" | "SchematicTraceRender" | "SchematicSheetRender" | "SchematicReplaceNetLabelsWithSymbols" | "SchematicLabelNetsWithConflictingNames" | "PanelBoardLayout" | "ValidatePcbCoordinates" | "PcbComponentRender" | "PcbPrimitiveRender" | "PcbFootprintLayout" | "PcbPortRender" | "PcbPortAttachment" | "PcbComponentSizeCalculation" | "PcbComponentAnchorAlignment" | "PcbCalcPlacementResolution" | "PcbLayout" | "PcbBoardAutoSize" | "PanelLayout" | "PcbFlexRender" | "PcbAutoplaceBreakoutPoints" | "PcbTraceHintRender" | "PcbManualTraceRender" | "PcbPlacementDesignRuleChecks" | "PcbTraceRender" | "PcbRouteNetIslands" | "
|
|
374
|
+
declare const renderPhaseIndexMap: Map<"ReactSubtreesRender" | "RenderIsolatedSubcircuits" | "InflateSubcircuitCircuitJson" | "SourceNameDuplicateComponentRemoval" | "PcbFootprintStringRender" | "FetchPartFootprint" | "ResolveFootprintPinLabels" | "InitializePortsFromChildren" | "CreateNetsFromProps" | "AssignFallbackProps" | "CreateTracesFromProps" | "CreateTracesFromNetLabels" | "CreateTraceHintsFromProps" | "CreateAutoplacedBreakoutPoints" | "SourceGroupRender" | "AssignNameToUnnamedComponents" | "SourceRender" | "CheckRefDesConvention" | "SourceComponentPropertyValidation" | "SourceParentAttachment" | "PortMatching" | "OptimizeSelectorCache" | "SourceTraceRender" | "SourceAddConnectivityMapKey" | "SourceDesignRuleChecks" | "SimulationRender" | "SchematicComponentRender" | "SchematicPortRender" | "SymbolContainerRender" | "SchematicPrimitiveRender" | "SchematicSymbolResize" | "SchematicComponentSizeCalculation" | "SchematicLayout" | "SchematicSectionRender" | "SchematicTraceRender" | "SchematicSheetRender" | "SchematicReplaceNetLabelsWithSymbols" | "SchematicLabelNetsWithConflictingNames" | "PanelBoardLayout" | "ValidatePcbCoordinates" | "PcbComponentRender" | "PcbPrimitiveRender" | "PcbFootprintLayout" | "PcbPortRender" | "PcbPortAttachment" | "PcbComponentSizeCalculation" | "PcbComponentAnchorAlignment" | "PcbCalcPlacementResolution" | "PcbLayout" | "PcbBoardAutoSize" | "PanelLayout" | "PcbFlexRender" | "PcbAutoplaceBreakoutPoints" | "PcbTraceHintRender" | "PcbManualTraceRender" | "PcbPlacementDesignRuleChecks" | "PcbTraceRender" | "PcbRouteNetIslands" | "PcbCopperPourRender" | "PcbViaStitchRender" | "PcbCopperPourCleanup" | "PcbDesignRuleChecks" | "SilkscreenOverlapAdjustment" | "CadModelRender" | "PartsEngineRender" | "PartOrientationAnalysis" | "SupplierFootprintMismatchWarning" | "SimulationSpiceEngineRender", number>;
|
|
375
375
|
type RenderPhaseFn<K extends RenderPhase = RenderPhase> = `doInitial${K}` | `update${K}` | `remove${K}`;
|
|
376
376
|
type RenderPhaseStates = Record<RenderPhase, {
|
|
377
377
|
initialized: boolean;
|
|
@@ -6251,7 +6251,6 @@ declare class Board extends Group<typeof boardProps> implements BoardI, Subcircu
|
|
|
6251
6251
|
removePcbComponentRender(): void;
|
|
6252
6252
|
doInitialPcbDesignRuleChecks(): void;
|
|
6253
6253
|
doInitialPcbPlacementDesignRuleChecks(): void;
|
|
6254
|
-
doInitialPcbImplicitCopperPourRender(): void;
|
|
6255
6254
|
_generatedStitchingViaIds: Set<string>;
|
|
6256
6255
|
doInitialPcbCopperPourCleanup(): void;
|
|
6257
6256
|
updatePcbDesignRuleChecks(): void;
|
package/dist/index.js
CHANGED
|
@@ -484,7 +484,6 @@ var orderedRenderPhases = [
|
|
|
484
484
|
"PcbPlacementDesignRuleChecks",
|
|
485
485
|
"PcbTraceRender",
|
|
486
486
|
"PcbRouteNetIslands",
|
|
487
|
-
"PcbImplicitCopperPourRender",
|
|
488
487
|
"PcbCopperPourRender",
|
|
489
488
|
"PcbViaStitchRender",
|
|
490
489
|
"PcbCopperPourCleanup",
|
|
@@ -535,14 +534,6 @@ var asyncPhaseDependencies = {
|
|
|
535
534
|
PcbTraceHintRender: ["PcbFootprintStringRender", "FetchPartFootprint"],
|
|
536
535
|
PcbManualTraceRender: ["PcbFootprintStringRender", "FetchPartFootprint"],
|
|
537
536
|
PcbCopperPourRender: [
|
|
538
|
-
"PcbFootprintStringRender",
|
|
539
|
-
"FetchPartFootprint",
|
|
540
|
-
"PcbPlacementDesignRuleChecks",
|
|
541
|
-
"PcbTraceRender",
|
|
542
|
-
"PcbRouteNetIslands",
|
|
543
|
-
"PcbImplicitCopperPourRender"
|
|
544
|
-
],
|
|
545
|
-
PcbImplicitCopperPourRender: [
|
|
546
537
|
"PcbFootprintStringRender",
|
|
547
538
|
"FetchPartFootprint",
|
|
548
539
|
"PcbPlacementDesignRuleChecks",
|
|
@@ -555,7 +546,6 @@ var asyncPhaseDependencies = {
|
|
|
555
546
|
"PcbPlacementDesignRuleChecks",
|
|
556
547
|
"PcbTraceRender",
|
|
557
548
|
"PcbRouteNetIslands",
|
|
558
|
-
"PcbImplicitCopperPourRender",
|
|
559
549
|
"PcbCopperPourRender"
|
|
560
550
|
],
|
|
561
551
|
PcbPlacementDesignRuleChecks: [
|
|
@@ -568,7 +558,6 @@ var asyncPhaseDependencies = {
|
|
|
568
558
|
"PcbPlacementDesignRuleChecks",
|
|
569
559
|
"PcbTraceRender",
|
|
570
560
|
"PcbRouteNetIslands",
|
|
571
|
-
"PcbImplicitCopperPourRender",
|
|
572
561
|
"PcbCopperPourRender",
|
|
573
562
|
"PcbViaStitchRender"
|
|
574
563
|
],
|
|
@@ -583,7 +572,6 @@ var asyncPhaseDependencies = {
|
|
|
583
572
|
"FetchPartFootprint",
|
|
584
573
|
"PcbPlacementDesignRuleChecks",
|
|
585
574
|
"PcbTraceRender",
|
|
586
|
-
"PcbImplicitCopperPourRender",
|
|
587
575
|
"PcbCopperPourRender",
|
|
588
576
|
"PcbViaStitchRender",
|
|
589
577
|
"PcbCopperPourCleanup"
|
|
@@ -63800,7 +63788,7 @@ function Group_getRoutingPhasePlans(group) {
|
|
|
63800
63788
|
var package_default = {
|
|
63801
63789
|
name: "@tscircuit/core",
|
|
63802
63790
|
type: "module",
|
|
63803
|
-
version: "0.0.
|
|
63791
|
+
version: "0.0.1968",
|
|
63804
63792
|
types: "dist/index.d.ts",
|
|
63805
63793
|
main: "dist/index.js",
|
|
63806
63794
|
module: "dist/index.js",
|
|
@@ -63839,7 +63827,7 @@ var package_default = {
|
|
|
63839
63827
|
"@tscircuit/checks": "^0.0.208",
|
|
63840
63828
|
"@tscircuit/circuit-json-util": "^0.0.116",
|
|
63841
63829
|
"@tscircuit/common": "^0.0.20",
|
|
63842
|
-
"@tscircuit/copper-pour-solver": "^0.0.
|
|
63830
|
+
"@tscircuit/copper-pour-solver": "^0.0.57",
|
|
63843
63831
|
"@tscircuit/create-fdm-enclosure": "0.0.4",
|
|
63844
63832
|
"@tscircuit/fanout-solver": "0.0.78",
|
|
63845
63833
|
"@tscircuit/footprinter": "^0.0.426",
|
|
@@ -68903,382 +68891,6 @@ function Subcircuit_getSubcircuitPropHash(subcircuit) {
|
|
|
68903
68891
|
return computeHash(hashableData);
|
|
68904
68892
|
}
|
|
68905
68893
|
|
|
68906
|
-
// lib/components/primitive-components/CopperPour/CopperPour.ts
|
|
68907
|
-
import { copperPourProps } from "@tscircuit/props";
|
|
68908
|
-
|
|
68909
|
-
// lib/components/primitive-components/CopperPour/CopperPour_doInitialPcbCopperPourRender.ts
|
|
68910
|
-
import {
|
|
68911
|
-
CopperPourPipelineSolver as CopperPourPipelineSolver2,
|
|
68912
|
-
convertCircuitJsonToInputProblem,
|
|
68913
|
-
initializeManifoldGeometry
|
|
68914
|
-
} from "@tscircuit/copper-pour-solver";
|
|
68915
|
-
|
|
68916
|
-
// lib/components/primitive-components/CopperPour/utils/mark-trace-segments-inside-copper-pour.ts
|
|
68917
|
-
var EPSILON24 = 1e-9;
|
|
68918
|
-
var isWireRoutePoint = (routePoint) => routePoint.route_type === "wire";
|
|
68919
|
-
var isPointOnSegment2 = (p, a, b) => {
|
|
68920
|
-
const cross4 = (p.y - a.y) * (b.x - a.x) - (p.x - a.x) * (b.y - a.y);
|
|
68921
|
-
if (Math.abs(cross4) > EPSILON24) return false;
|
|
68922
|
-
const dot = (p.x - a.x) * (b.x - a.x) + (p.y - a.y) * (b.y - a.y);
|
|
68923
|
-
if (dot < -EPSILON24) return false;
|
|
68924
|
-
const squaredLength = (b.x - a.x) ** 2 + (b.y - a.y) ** 2;
|
|
68925
|
-
if (dot - squaredLength > EPSILON24) return false;
|
|
68926
|
-
return true;
|
|
68927
|
-
};
|
|
68928
|
-
var isPointInRing2 = (point6, ring) => {
|
|
68929
|
-
if (ring.length < 3) return false;
|
|
68930
|
-
let inside2 = false;
|
|
68931
|
-
let previous = ring[ring.length - 1];
|
|
68932
|
-
for (const current of ring) {
|
|
68933
|
-
if (isPointOnSegment2(point6, previous, current)) return true;
|
|
68934
|
-
const intersects = current.y > point6.y !== previous.y > point6.y && point6.x < (previous.x - current.x) * (point6.y - current.y) / (previous.y - current.y) + current.x;
|
|
68935
|
-
if (intersects) inside2 = !inside2;
|
|
68936
|
-
previous = current;
|
|
68937
|
-
}
|
|
68938
|
-
return inside2;
|
|
68939
|
-
};
|
|
68940
|
-
var isPointInRectPour = (p, pour) => {
|
|
68941
|
-
const { center, width, height } = pour;
|
|
68942
|
-
const rotationRad = (pour.rotation ?? 0) * Math.PI / 180;
|
|
68943
|
-
const cosR = Math.cos(-rotationRad);
|
|
68944
|
-
const sinR = Math.sin(-rotationRad);
|
|
68945
|
-
const dx = p.x - center.x;
|
|
68946
|
-
const dy = p.y - center.y;
|
|
68947
|
-
const localX = dx * cosR - dy * sinR;
|
|
68948
|
-
const localY = dx * sinR + dy * cosR;
|
|
68949
|
-
return Math.abs(localX) <= width / 2 + EPSILON24 && Math.abs(localY) <= height / 2 + EPSILON24;
|
|
68950
|
-
};
|
|
68951
|
-
var isPointInBrepPour = (p, pour) => {
|
|
68952
|
-
const outerRing = pour.brep_shape.outer_ring.vertices.map((v) => ({
|
|
68953
|
-
x: v.x,
|
|
68954
|
-
y: v.y
|
|
68955
|
-
}));
|
|
68956
|
-
if (!isPointInRing2(p, outerRing)) return false;
|
|
68957
|
-
for (const innerRing of pour.brep_shape.inner_rings) {
|
|
68958
|
-
const points = innerRing.vertices.map((v) => ({ x: v.x, y: v.y }));
|
|
68959
|
-
if (isPointInRing2(p, points)) return false;
|
|
68960
|
-
}
|
|
68961
|
-
return true;
|
|
68962
|
-
};
|
|
68963
|
-
var isPointInCopperPour = (point6, pour) => {
|
|
68964
|
-
if (pour.shape === "rect") {
|
|
68965
|
-
return isPointInRectPour(point6, pour);
|
|
68966
|
-
}
|
|
68967
|
-
if (pour.shape === "brep") {
|
|
68968
|
-
return isPointInBrepPour(point6, pour);
|
|
68969
|
-
}
|
|
68970
|
-
return false;
|
|
68971
|
-
};
|
|
68972
|
-
var isTraceConnectedToSourceNet = (trace, sourceNetId, sourceTraceById) => {
|
|
68973
|
-
if (trace.source_trace_id === sourceNetId) return true;
|
|
68974
|
-
if (!trace.source_trace_id) return false;
|
|
68975
|
-
const sourceTrace = sourceTraceById.get(trace.source_trace_id);
|
|
68976
|
-
if (!sourceTrace) return false;
|
|
68977
|
-
return sourceTrace.connected_source_net_ids.includes(sourceNetId);
|
|
68978
|
-
};
|
|
68979
|
-
var isSegmentFullyInsideCopperPour = (start, end, pour) => {
|
|
68980
|
-
const dx = end.x - start.x;
|
|
68981
|
-
const dy = end.y - start.y;
|
|
68982
|
-
const length8 = Math.hypot(dx, dy);
|
|
68983
|
-
if (length8 <= EPSILON24) return false;
|
|
68984
|
-
const samples = [0, 0.25, 0.5, 0.75, 1];
|
|
68985
|
-
return samples.every(
|
|
68986
|
-
(t) => isPointInCopperPour(
|
|
68987
|
-
{
|
|
68988
|
-
x: start.x + dx * t,
|
|
68989
|
-
y: start.y + dy * t
|
|
68990
|
-
},
|
|
68991
|
-
pour
|
|
68992
|
-
)
|
|
68993
|
-
);
|
|
68994
|
-
};
|
|
68995
|
-
var markTraceSegmentsInsideCopperPour = ({
|
|
68996
|
-
db,
|
|
68997
|
-
copperPour
|
|
68998
|
-
}) => {
|
|
68999
|
-
if (!copperPour.source_net_id) return;
|
|
69000
|
-
const sourceTraceById = new Map(
|
|
69001
|
-
db.source_trace.list().map((sourceTrace) => [sourceTrace.source_trace_id, sourceTrace])
|
|
69002
|
-
);
|
|
69003
|
-
for (const trace of db.pcb_trace.list()) {
|
|
69004
|
-
if (!isTraceConnectedToSourceNet(
|
|
69005
|
-
trace,
|
|
69006
|
-
copperPour.source_net_id,
|
|
69007
|
-
sourceTraceById
|
|
69008
|
-
)) {
|
|
69009
|
-
continue;
|
|
69010
|
-
}
|
|
69011
|
-
let routeChanged = false;
|
|
69012
|
-
const nextRoute = trace.route.map((routePoint) => ({ ...routePoint }));
|
|
69013
|
-
for (let i = 0; i < nextRoute.length - 1; i++) {
|
|
69014
|
-
const fromRoutePoint = nextRoute[i];
|
|
69015
|
-
const toRoutePoint = nextRoute[i + 1];
|
|
69016
|
-
if (!fromRoutePoint || !toRoutePoint) continue;
|
|
69017
|
-
if (!isWireRoutePoint(fromRoutePoint) || !isWireRoutePoint(toRoutePoint))
|
|
69018
|
-
continue;
|
|
69019
|
-
if (fromRoutePoint.layer !== copperPour.layer || toRoutePoint.layer !== copperPour.layer)
|
|
69020
|
-
continue;
|
|
69021
|
-
if (isSegmentFullyInsideCopperPour(
|
|
69022
|
-
{ x: fromRoutePoint.x, y: fromRoutePoint.y },
|
|
69023
|
-
{ x: toRoutePoint.x, y: toRoutePoint.y },
|
|
69024
|
-
copperPour
|
|
69025
|
-
)) {
|
|
69026
|
-
fromRoutePoint.is_inside_copper_pour = true;
|
|
69027
|
-
fromRoutePoint.copper_pour_id = copperPour.pcb_copper_pour_id;
|
|
69028
|
-
toRoutePoint.is_inside_copper_pour = true;
|
|
69029
|
-
toRoutePoint.copper_pour_id = copperPour.pcb_copper_pour_id;
|
|
69030
|
-
routeChanged = true;
|
|
69031
|
-
}
|
|
69032
|
-
}
|
|
69033
|
-
if (routeChanged) {
|
|
69034
|
-
db.pcb_trace.update(trace.pcb_trace_id, { route: nextRoute });
|
|
69035
|
-
}
|
|
69036
|
-
}
|
|
69037
|
-
};
|
|
69038
|
-
|
|
69039
|
-
// lib/components/primitive-components/CopperPour/CopperPour_doInitialPcbCopperPourRender.ts
|
|
69040
|
-
var pendingCopperPourRenders = /* @__PURE__ */ new WeakMap();
|
|
69041
|
-
var DEFAULT_THERMAL_RELIEF_SPOKE_WIDTH_MM = 0.3;
|
|
69042
|
-
var renderAllCopperPoursForSubcircuit = async (subcircuit) => {
|
|
69043
|
-
if (!subcircuit.root) return;
|
|
69044
|
-
const { db } = subcircuit.root;
|
|
69045
|
-
const copperPours = subcircuit.selectAll("copperpour").filter((copperPour) => copperPour.getSubcircuit() === subcircuit);
|
|
69046
|
-
const resolvedCopperPours = [];
|
|
69047
|
-
for (const copperPour of copperPours) {
|
|
69048
|
-
const { _parsedProps: props } = copperPour;
|
|
69049
|
-
const net = subcircuit.selectOne(props.connectsTo);
|
|
69050
|
-
const sourceNetId = net?.source_net_id;
|
|
69051
|
-
if (!sourceNetId) {
|
|
69052
|
-
copperPour.renderError(
|
|
69053
|
-
`Net "${props.connectsTo}" not found for copper pour`
|
|
69054
|
-
);
|
|
69055
|
-
continue;
|
|
69056
|
-
}
|
|
69057
|
-
resolvedCopperPours.push({ copperPour, sourceNetId });
|
|
69058
|
-
}
|
|
69059
|
-
if (resolvedCopperPours.length === 0) return;
|
|
69060
|
-
const circuitJson = db.toArray();
|
|
69061
|
-
const boardComponent = subcircuit._getBoard();
|
|
69062
|
-
const pcbBoard = boardComponent?.pcb_board_id ? db.pcb_board.get(boardComponent.pcb_board_id) : void 0;
|
|
69063
|
-
let resolvedPcbBoardOutline = pcbBoard?.outline?.length ? pcbBoard.outline : void 0;
|
|
69064
|
-
if (!resolvedPcbBoardOutline && pcbBoard?.width !== void 0 && pcbBoard.height !== void 0) {
|
|
69065
|
-
const { center, width, height } = pcbBoard;
|
|
69066
|
-
resolvedPcbBoardOutline = [
|
|
69067
|
-
{ x: center.x - width / 2, y: center.y - height / 2 },
|
|
69068
|
-
{ x: center.x + width / 2, y: center.y - height / 2 },
|
|
69069
|
-
{ x: center.x + width / 2, y: center.y + height / 2 },
|
|
69070
|
-
{ x: center.x - width / 2, y: center.y + height / 2 }
|
|
69071
|
-
];
|
|
69072
|
-
}
|
|
69073
|
-
const inputProblem = convertCircuitJsonToInputProblem(
|
|
69074
|
-
circuitJson,
|
|
69075
|
-
resolvedCopperPours.map(({ copperPour, sourceNetId }) => {
|
|
69076
|
-
const { _parsedProps: props } = copperPour;
|
|
69077
|
-
const clearance = props.clearance ?? 0.2;
|
|
69078
|
-
return {
|
|
69079
|
-
layer: props.layer,
|
|
69080
|
-
subcircuit_id: subcircuit.subcircuit_id ?? void 0,
|
|
69081
|
-
source_net_id: sourceNetId,
|
|
69082
|
-
pad_margin: props.padMargin ?? clearance,
|
|
69083
|
-
trace_margin: props.traceMargin ?? clearance,
|
|
69084
|
-
pour_margin: clearance,
|
|
69085
|
-
board_edge_margin: props.boardEdgeMargin ?? clearance,
|
|
69086
|
-
board_edge_outline: copperPour._isImplicitCopperPour ? resolvedPcbBoardOutline : void 0,
|
|
69087
|
-
cutout_margin: props.cutoutMargin ?? clearance,
|
|
69088
|
-
...props.useThermalReliefs ? {
|
|
69089
|
-
use_thermal_reliefs: true,
|
|
69090
|
-
thermal_relief_spoke_width: DEFAULT_THERMAL_RELIEF_SPOKE_WIDTH_MM
|
|
69091
|
-
} : {},
|
|
69092
|
-
outline: props.outline ?? resolvedPcbBoardOutline
|
|
69093
|
-
};
|
|
69094
|
-
})
|
|
69095
|
-
);
|
|
69096
|
-
await initializeManifoldGeometry();
|
|
69097
|
-
const solver = new CopperPourPipelineSolver2(inputProblem);
|
|
69098
|
-
subcircuit.root.emit("solver:started", {
|
|
69099
|
-
type: "solver:started",
|
|
69100
|
-
solverName: "CopperPourPipelineSolver",
|
|
69101
|
-
solverParams: inputProblem,
|
|
69102
|
-
solverConstructorArgs: [inputProblem],
|
|
69103
|
-
componentName: subcircuit.getString()
|
|
69104
|
-
});
|
|
69105
|
-
const { brep_shapes_by_region } = solver.getOutput();
|
|
69106
|
-
for (const [
|
|
69107
|
-
regionIndex,
|
|
69108
|
-
{ copperPour, sourceNetId }
|
|
69109
|
-
] of resolvedCopperPours.entries()) {
|
|
69110
|
-
const { _parsedProps: props } = copperPour;
|
|
69111
|
-
const coveredWithSolderMask = props.coveredWithSolderMask ?? false;
|
|
69112
|
-
for (const brepShape of brep_shapes_by_region[regionIndex] ?? []) {
|
|
69113
|
-
const insertedPour = db.pcb_copper_pour.insert({
|
|
69114
|
-
shape: "brep",
|
|
69115
|
-
layer: props.layer,
|
|
69116
|
-
brep_shape: brepShape,
|
|
69117
|
-
source_net_id: sourceNetId,
|
|
69118
|
-
subcircuit_id: subcircuit.subcircuit_id ?? void 0,
|
|
69119
|
-
covered_with_solder_mask: coveredWithSolderMask
|
|
69120
|
-
});
|
|
69121
|
-
markTraceSegmentsInsideCopperPour({
|
|
69122
|
-
db,
|
|
69123
|
-
copperPour: insertedPour
|
|
69124
|
-
});
|
|
69125
|
-
}
|
|
69126
|
-
}
|
|
69127
|
-
};
|
|
69128
|
-
function CopperPour_doInitialPcbCopperPourRender(copperPour) {
|
|
69129
|
-
if (copperPour.root?.pcbDisabled) return;
|
|
69130
|
-
copperPour._queueAsyncEffect("PcbCopperPourRender", async () => {
|
|
69131
|
-
const subcircuit = copperPour.getSubcircuit();
|
|
69132
|
-
const pendingRender = pendingCopperPourRenders.get(subcircuit);
|
|
69133
|
-
if (pendingRender) {
|
|
69134
|
-
await pendingRender;
|
|
69135
|
-
return;
|
|
69136
|
-
}
|
|
69137
|
-
const renderPromise = renderAllCopperPoursForSubcircuit(subcircuit);
|
|
69138
|
-
pendingCopperPourRenders.set(subcircuit, renderPromise);
|
|
69139
|
-
try {
|
|
69140
|
-
await renderPromise;
|
|
69141
|
-
} finally {
|
|
69142
|
-
pendingCopperPourRenders.delete(subcircuit);
|
|
69143
|
-
}
|
|
69144
|
-
});
|
|
69145
|
-
}
|
|
69146
|
-
|
|
69147
|
-
// lib/components/primitive-components/CopperPour/CopperPour_doInitialPcbViaStitchRender.ts
|
|
69148
|
-
import { pcb_via as pcb_via3 } from "circuit-json";
|
|
69149
|
-
var renderViaStitchingForCopperPours = (copperPour) => {
|
|
69150
|
-
const subcircuit = copperPour.getSubcircuit();
|
|
69151
|
-
if (!subcircuit.root) return;
|
|
69152
|
-
const copperPours = subcircuit.selectAll("copperpour").filter(
|
|
69153
|
-
(candidateCopperPour) => candidateCopperPour.getSubcircuit() === subcircuit
|
|
69154
|
-
);
|
|
69155
|
-
if (copperPours[0] !== copperPour) return;
|
|
69156
|
-
const sourceNetIds = copperPours.flatMap((candidateCopperPour) => {
|
|
69157
|
-
const net = subcircuit.selectOne(
|
|
69158
|
-
candidateCopperPour._parsedProps.connectsTo
|
|
69159
|
-
);
|
|
69160
|
-
return net?.source_net_id ? [net.source_net_id] : [];
|
|
69161
|
-
});
|
|
69162
|
-
if (sourceNetIds.length === 0) return;
|
|
69163
|
-
const { db } = subcircuit.root;
|
|
69164
|
-
const pcbStyle = copperPour.getInheritedMergedProperty("pcbStyle");
|
|
69165
|
-
const { holeDiameter, padDiameter } = getViaDiameterDefaults(pcbStyle);
|
|
69166
|
-
const boardComponent = copperPour._getBoard();
|
|
69167
|
-
const pcbBoard = boardComponent?.pcb_board_id ? db.pcb_board.get(boardComponent.pcb_board_id) : void 0;
|
|
69168
|
-
const solverInput = {
|
|
69169
|
-
circuitJson: db.toArray(),
|
|
69170
|
-
options: {
|
|
69171
|
-
sourceNetIds: [...new Set(sourceNetIds)],
|
|
69172
|
-
viaHoleDiameter: pcbBoard?.min_via_hole_diameter ?? holeDiameter,
|
|
69173
|
-
viaOuterDiameter: pcbBoard?.min_via_pad_diameter ?? padDiameter,
|
|
69174
|
-
viaStitchPitch: boardComponent?._parsedProps.viaStitchPitch
|
|
69175
|
-
}
|
|
69176
|
-
};
|
|
69177
|
-
const solver = new ViaStitchSolver(solverInput);
|
|
69178
|
-
subcircuit.root.emit("solver:started", {
|
|
69179
|
-
type: "solver:started",
|
|
69180
|
-
solverName: "ViaStitchSolver",
|
|
69181
|
-
solverParams: solverInput,
|
|
69182
|
-
solverConstructorArgs: [solverInput],
|
|
69183
|
-
componentName: subcircuit.getString()
|
|
69184
|
-
});
|
|
69185
|
-
solver.solve();
|
|
69186
|
-
if (solver.failed) {
|
|
69187
|
-
throw new Error(solver.error ?? "Via stitching solver failed");
|
|
69188
|
-
}
|
|
69189
|
-
for (const pcbVia of solver.getOutput().pcbVias) {
|
|
69190
|
-
const { pcb_via_id: _solverViaId, ...pcbViaInput } = pcb_via3.parse(pcbVia);
|
|
69191
|
-
const insertedVia = db.pcb_via.insert({
|
|
69192
|
-
...pcbViaInput,
|
|
69193
|
-
tented_on_top: void 0,
|
|
69194
|
-
tented_on_bottom: void 0
|
|
69195
|
-
});
|
|
69196
|
-
boardComponent?._generatedStitchingViaIds?.add(insertedVia.pcb_via_id);
|
|
69197
|
-
}
|
|
69198
|
-
};
|
|
69199
|
-
function CopperPour_doInitialPcbViaStitchRender(copperPour) {
|
|
69200
|
-
if (copperPour.root?.pcbDisabled || !copperPour.root?._featurePcbViaStitching)
|
|
69201
|
-
return;
|
|
69202
|
-
if (!copperPour._getBoard()?._parsedProps.enableViaStitching) return;
|
|
69203
|
-
copperPour._queueAsyncEffect("PcbViaStitchRender", async () => {
|
|
69204
|
-
renderViaStitchingForCopperPours(copperPour);
|
|
69205
|
-
});
|
|
69206
|
-
}
|
|
69207
|
-
|
|
69208
|
-
// lib/components/primitive-components/CopperPour/CopperPour.ts
|
|
69209
|
-
var CopperPour = class extends PrimitiveComponent2 {
|
|
69210
|
-
isPcbPrimitive = true;
|
|
69211
|
-
_isImplicitCopperPour = false;
|
|
69212
|
-
get config() {
|
|
69213
|
-
return {
|
|
69214
|
-
componentName: "CopperPour",
|
|
69215
|
-
zodProps: copperPourProps
|
|
69216
|
-
};
|
|
69217
|
-
}
|
|
69218
|
-
getPcbSize() {
|
|
69219
|
-
return { width: 0, height: 0 };
|
|
69220
|
-
}
|
|
69221
|
-
doInitialCreateNetsFromProps() {
|
|
69222
|
-
const { _parsedProps: props } = this;
|
|
69223
|
-
createNetsFromProps(this, [props.connectsTo]);
|
|
69224
|
-
}
|
|
69225
|
-
doInitialPcbCopperPourRender() {
|
|
69226
|
-
CopperPour_doInitialPcbCopperPourRender(this);
|
|
69227
|
-
}
|
|
69228
|
-
doInitialPcbViaStitchRender() {
|
|
69229
|
-
CopperPour_doInitialPcbViaStitchRender(this);
|
|
69230
|
-
}
|
|
69231
|
-
};
|
|
69232
|
-
|
|
69233
|
-
// lib/components/normal-components/Board_doInitialPcbImplicitCopperPourRender.ts
|
|
69234
|
-
var Board_doInitialPcbImplicitCopperPourRender = (board) => {
|
|
69235
|
-
const { root } = board;
|
|
69236
|
-
if (!root || root.pcbDisabled) return;
|
|
69237
|
-
if (!board._parsedProps.automaticPoursEnabled) return;
|
|
69238
|
-
if (root.pcbRoutingDisabled || board.getInheritedProperty("routingDisabled"))
|
|
69239
|
-
return;
|
|
69240
|
-
const { db } = root;
|
|
69241
|
-
const circuitJson = db.subtree({ subcircuit_id: board.subcircuit_id }).toArray();
|
|
69242
|
-
const hasPowerNet = circuitJson.some(
|
|
69243
|
-
(element) => element.type === "source_net" && (element.is_power || element.is_ground || element.is_positive_voltage_source)
|
|
69244
|
-
);
|
|
69245
|
-
if (!hasPowerNet) return;
|
|
69246
|
-
const inputProblem = {
|
|
69247
|
-
circuitJson,
|
|
69248
|
-
layers: [...board.allLayers]
|
|
69249
|
-
};
|
|
69250
|
-
const solver = new ImplicitCopperPourPipelineSolver(inputProblem);
|
|
69251
|
-
const solverConstructorArgs = solver.getConstructorParams();
|
|
69252
|
-
root.emit("solver:started", {
|
|
69253
|
-
type: "solver:started",
|
|
69254
|
-
solverName: "ImplicitCopperPourPipelineSolver",
|
|
69255
|
-
solverParams: solverConstructorArgs[0],
|
|
69256
|
-
solverConstructorArgs,
|
|
69257
|
-
componentName: board.getString()
|
|
69258
|
-
});
|
|
69259
|
-
solver.solve();
|
|
69260
|
-
const boardNets = board.selectAll("net");
|
|
69261
|
-
for (const implicitRegion of solver.getOutput()) {
|
|
69262
|
-
if (implicitRegion.shape !== "polygon") continue;
|
|
69263
|
-
const owningNet = boardNets.find(
|
|
69264
|
-
(net) => net.source_net_id === implicitRegion.source_net_id
|
|
69265
|
-
);
|
|
69266
|
-
if (!owningNet) {
|
|
69267
|
-
throw new Error(
|
|
69268
|
-
`Unable to find the power net for implicit copper region ${implicitRegion.pcb_copper_pour_id}`
|
|
69269
|
-
);
|
|
69270
|
-
}
|
|
69271
|
-
const copperPour = new CopperPour({
|
|
69272
|
-
layer: implicitRegion.layer,
|
|
69273
|
-
connectsTo: owningNet.getPortSelector(),
|
|
69274
|
-
outline: implicitRegion.points,
|
|
69275
|
-
coveredWithSolderMask: implicitRegion.covered_with_solder_mask
|
|
69276
|
-
});
|
|
69277
|
-
copperPour._isImplicitCopperPour = true;
|
|
69278
|
-
owningNet.getSubcircuit().add(copperPour);
|
|
69279
|
-
}
|
|
69280
|
-
};
|
|
69281
|
-
|
|
69282
68894
|
// lib/utils/copper-pour-connectivity/find-floating-copper.ts
|
|
69283
68895
|
import {
|
|
69284
68896
|
getFullConnectivityMapFromCircuitJson as getFullConnectivityMapFromCircuitJson5
|
|
@@ -70112,9 +69724,6 @@ var Board = class extends Group5 {
|
|
|
70112
69724
|
doInitialPcbPlacementDesignRuleChecks() {
|
|
70113
69725
|
Board_doInitialPcbPlacementDesignRuleChecks(this);
|
|
70114
69726
|
}
|
|
70115
|
-
doInitialPcbImplicitCopperPourRender() {
|
|
70116
|
-
Board_doInitialPcbImplicitCopperPourRender(this);
|
|
70117
|
-
}
|
|
70118
69727
|
_generatedStitchingViaIds = /* @__PURE__ */ new Set();
|
|
70119
69728
|
doInitialPcbCopperPourCleanup() {
|
|
70120
69729
|
Board_doInitialPcbCopperPourCleanup(this);
|
|
@@ -75753,6 +75362,333 @@ var Fiducial = class extends PrimitiveComponent2 {
|
|
|
75753
75362
|
}
|
|
75754
75363
|
};
|
|
75755
75364
|
|
|
75365
|
+
// lib/components/primitive-components/CopperPour/CopperPour.ts
|
|
75366
|
+
import { copperPourProps } from "@tscircuit/props";
|
|
75367
|
+
|
|
75368
|
+
// lib/components/primitive-components/CopperPour/CopperPour_doInitialPcbCopperPourRender.ts
|
|
75369
|
+
import {
|
|
75370
|
+
CopperPourPipelineSolver as CopperPourPipelineSolver2,
|
|
75371
|
+
convertCircuitJsonToInputProblem,
|
|
75372
|
+
initializeManifoldGeometry
|
|
75373
|
+
} from "@tscircuit/copper-pour-solver";
|
|
75374
|
+
|
|
75375
|
+
// lib/components/primitive-components/CopperPour/utils/mark-trace-segments-inside-copper-pour.ts
|
|
75376
|
+
var EPSILON24 = 1e-9;
|
|
75377
|
+
var isWireRoutePoint = (routePoint) => routePoint.route_type === "wire";
|
|
75378
|
+
var isPointOnSegment2 = (p, a, b) => {
|
|
75379
|
+
const cross4 = (p.y - a.y) * (b.x - a.x) - (p.x - a.x) * (b.y - a.y);
|
|
75380
|
+
if (Math.abs(cross4) > EPSILON24) return false;
|
|
75381
|
+
const dot = (p.x - a.x) * (b.x - a.x) + (p.y - a.y) * (b.y - a.y);
|
|
75382
|
+
if (dot < -EPSILON24) return false;
|
|
75383
|
+
const squaredLength = (b.x - a.x) ** 2 + (b.y - a.y) ** 2;
|
|
75384
|
+
if (dot - squaredLength > EPSILON24) return false;
|
|
75385
|
+
return true;
|
|
75386
|
+
};
|
|
75387
|
+
var isPointInRing2 = (point6, ring) => {
|
|
75388
|
+
if (ring.length < 3) return false;
|
|
75389
|
+
let inside2 = false;
|
|
75390
|
+
let previous = ring[ring.length - 1];
|
|
75391
|
+
for (const current of ring) {
|
|
75392
|
+
if (isPointOnSegment2(point6, previous, current)) return true;
|
|
75393
|
+
const intersects = current.y > point6.y !== previous.y > point6.y && point6.x < (previous.x - current.x) * (point6.y - current.y) / (previous.y - current.y) + current.x;
|
|
75394
|
+
if (intersects) inside2 = !inside2;
|
|
75395
|
+
previous = current;
|
|
75396
|
+
}
|
|
75397
|
+
return inside2;
|
|
75398
|
+
};
|
|
75399
|
+
var isPointInRectPour = (p, pour) => {
|
|
75400
|
+
const { center, width, height } = pour;
|
|
75401
|
+
const rotationRad = (pour.rotation ?? 0) * Math.PI / 180;
|
|
75402
|
+
const cosR = Math.cos(-rotationRad);
|
|
75403
|
+
const sinR = Math.sin(-rotationRad);
|
|
75404
|
+
const dx = p.x - center.x;
|
|
75405
|
+
const dy = p.y - center.y;
|
|
75406
|
+
const localX = dx * cosR - dy * sinR;
|
|
75407
|
+
const localY = dx * sinR + dy * cosR;
|
|
75408
|
+
return Math.abs(localX) <= width / 2 + EPSILON24 && Math.abs(localY) <= height / 2 + EPSILON24;
|
|
75409
|
+
};
|
|
75410
|
+
var isPointInBrepPour = (p, pour) => {
|
|
75411
|
+
const outerRing = pour.brep_shape.outer_ring.vertices.map((v) => ({
|
|
75412
|
+
x: v.x,
|
|
75413
|
+
y: v.y
|
|
75414
|
+
}));
|
|
75415
|
+
if (!isPointInRing2(p, outerRing)) return false;
|
|
75416
|
+
for (const innerRing of pour.brep_shape.inner_rings) {
|
|
75417
|
+
const points = innerRing.vertices.map((v) => ({ x: v.x, y: v.y }));
|
|
75418
|
+
if (isPointInRing2(p, points)) return false;
|
|
75419
|
+
}
|
|
75420
|
+
return true;
|
|
75421
|
+
};
|
|
75422
|
+
var isPointInCopperPour = (point6, pour) => {
|
|
75423
|
+
if (pour.shape === "rect") {
|
|
75424
|
+
return isPointInRectPour(point6, pour);
|
|
75425
|
+
}
|
|
75426
|
+
if (pour.shape === "brep") {
|
|
75427
|
+
return isPointInBrepPour(point6, pour);
|
|
75428
|
+
}
|
|
75429
|
+
return false;
|
|
75430
|
+
};
|
|
75431
|
+
var isTraceConnectedToSourceNet = (trace, sourceNetId, sourceTraceById) => {
|
|
75432
|
+
if (trace.source_trace_id === sourceNetId) return true;
|
|
75433
|
+
if (!trace.source_trace_id) return false;
|
|
75434
|
+
const sourceTrace = sourceTraceById.get(trace.source_trace_id);
|
|
75435
|
+
if (!sourceTrace) return false;
|
|
75436
|
+
return sourceTrace.connected_source_net_ids.includes(sourceNetId);
|
|
75437
|
+
};
|
|
75438
|
+
var isSegmentFullyInsideCopperPour = (start, end, pour) => {
|
|
75439
|
+
const dx = end.x - start.x;
|
|
75440
|
+
const dy = end.y - start.y;
|
|
75441
|
+
const length8 = Math.hypot(dx, dy);
|
|
75442
|
+
if (length8 <= EPSILON24) return false;
|
|
75443
|
+
const samples = [0, 0.25, 0.5, 0.75, 1];
|
|
75444
|
+
return samples.every(
|
|
75445
|
+
(t) => isPointInCopperPour(
|
|
75446
|
+
{
|
|
75447
|
+
x: start.x + dx * t,
|
|
75448
|
+
y: start.y + dy * t
|
|
75449
|
+
},
|
|
75450
|
+
pour
|
|
75451
|
+
)
|
|
75452
|
+
);
|
|
75453
|
+
};
|
|
75454
|
+
var markTraceSegmentsInsideCopperPour = ({
|
|
75455
|
+
db,
|
|
75456
|
+
copperPour
|
|
75457
|
+
}) => {
|
|
75458
|
+
if (!copperPour.source_net_id) return;
|
|
75459
|
+
const sourceTraceById = new Map(
|
|
75460
|
+
db.source_trace.list().map((sourceTrace) => [sourceTrace.source_trace_id, sourceTrace])
|
|
75461
|
+
);
|
|
75462
|
+
for (const trace of db.pcb_trace.list()) {
|
|
75463
|
+
if (!isTraceConnectedToSourceNet(
|
|
75464
|
+
trace,
|
|
75465
|
+
copperPour.source_net_id,
|
|
75466
|
+
sourceTraceById
|
|
75467
|
+
)) {
|
|
75468
|
+
continue;
|
|
75469
|
+
}
|
|
75470
|
+
let routeChanged = false;
|
|
75471
|
+
const nextRoute = trace.route.map((routePoint) => ({ ...routePoint }));
|
|
75472
|
+
for (let i = 0; i < nextRoute.length - 1; i++) {
|
|
75473
|
+
const fromRoutePoint = nextRoute[i];
|
|
75474
|
+
const toRoutePoint = nextRoute[i + 1];
|
|
75475
|
+
if (!fromRoutePoint || !toRoutePoint) continue;
|
|
75476
|
+
if (!isWireRoutePoint(fromRoutePoint) || !isWireRoutePoint(toRoutePoint))
|
|
75477
|
+
continue;
|
|
75478
|
+
if (fromRoutePoint.layer !== copperPour.layer || toRoutePoint.layer !== copperPour.layer)
|
|
75479
|
+
continue;
|
|
75480
|
+
if (isSegmentFullyInsideCopperPour(
|
|
75481
|
+
{ x: fromRoutePoint.x, y: fromRoutePoint.y },
|
|
75482
|
+
{ x: toRoutePoint.x, y: toRoutePoint.y },
|
|
75483
|
+
copperPour
|
|
75484
|
+
)) {
|
|
75485
|
+
fromRoutePoint.is_inside_copper_pour = true;
|
|
75486
|
+
fromRoutePoint.copper_pour_id = copperPour.pcb_copper_pour_id;
|
|
75487
|
+
toRoutePoint.is_inside_copper_pour = true;
|
|
75488
|
+
toRoutePoint.copper_pour_id = copperPour.pcb_copper_pour_id;
|
|
75489
|
+
routeChanged = true;
|
|
75490
|
+
}
|
|
75491
|
+
}
|
|
75492
|
+
if (routeChanged) {
|
|
75493
|
+
db.pcb_trace.update(trace.pcb_trace_id, { route: nextRoute });
|
|
75494
|
+
}
|
|
75495
|
+
}
|
|
75496
|
+
};
|
|
75497
|
+
|
|
75498
|
+
// lib/components/primitive-components/CopperPour/CopperPour_doInitialPcbCopperPourRender.ts
|
|
75499
|
+
var pendingCopperPourRenders = /* @__PURE__ */ new WeakMap();
|
|
75500
|
+
var DEFAULT_THERMAL_RELIEF_SPOKE_WIDTH_MM = 0.3;
|
|
75501
|
+
var renderAllCopperPoursForSubcircuit = async (subcircuit) => {
|
|
75502
|
+
if (!subcircuit.root) return;
|
|
75503
|
+
const { db } = subcircuit.root;
|
|
75504
|
+
const copperPours = subcircuit.selectAll("copperpour").filter((copperPour) => copperPour.getSubcircuit() === subcircuit);
|
|
75505
|
+
const resolvedCopperPours = [];
|
|
75506
|
+
for (const copperPour of copperPours) {
|
|
75507
|
+
const { _parsedProps: props } = copperPour;
|
|
75508
|
+
const net = subcircuit.selectOne(props.connectsTo);
|
|
75509
|
+
const sourceNetId = net?.source_net_id;
|
|
75510
|
+
if (!sourceNetId) {
|
|
75511
|
+
copperPour.renderError(
|
|
75512
|
+
`Net "${props.connectsTo}" not found for copper pour`
|
|
75513
|
+
);
|
|
75514
|
+
continue;
|
|
75515
|
+
}
|
|
75516
|
+
resolvedCopperPours.push({ copperPour, sourceNetId });
|
|
75517
|
+
}
|
|
75518
|
+
if (resolvedCopperPours.length === 0) return;
|
|
75519
|
+
const circuitJson = db.toArray();
|
|
75520
|
+
const boardComponent = subcircuit._getBoard();
|
|
75521
|
+
const pcbBoard = boardComponent?.pcb_board_id ? db.pcb_board.get(boardComponent.pcb_board_id) : void 0;
|
|
75522
|
+
let resolvedPcbBoardOutline = pcbBoard?.outline?.length ? pcbBoard.outline : void 0;
|
|
75523
|
+
if (!resolvedPcbBoardOutline && pcbBoard?.width !== void 0 && pcbBoard.height !== void 0) {
|
|
75524
|
+
const { center, width, height } = pcbBoard;
|
|
75525
|
+
resolvedPcbBoardOutline = [
|
|
75526
|
+
{ x: center.x - width / 2, y: center.y - height / 2 },
|
|
75527
|
+
{ x: center.x + width / 2, y: center.y - height / 2 },
|
|
75528
|
+
{ x: center.x + width / 2, y: center.y + height / 2 },
|
|
75529
|
+
{ x: center.x - width / 2, y: center.y + height / 2 }
|
|
75530
|
+
];
|
|
75531
|
+
}
|
|
75532
|
+
const inputProblem = convertCircuitJsonToInputProblem(
|
|
75533
|
+
circuitJson,
|
|
75534
|
+
resolvedCopperPours.map(({ copperPour, sourceNetId }) => {
|
|
75535
|
+
const { _parsedProps: props } = copperPour;
|
|
75536
|
+
const clearance = props.clearance ?? 0.2;
|
|
75537
|
+
return {
|
|
75538
|
+
layer: props.layer,
|
|
75539
|
+
subcircuit_id: subcircuit.subcircuit_id ?? void 0,
|
|
75540
|
+
source_net_id: sourceNetId,
|
|
75541
|
+
pad_margin: props.padMargin ?? clearance,
|
|
75542
|
+
trace_margin: props.traceMargin ?? clearance,
|
|
75543
|
+
pour_margin: clearance,
|
|
75544
|
+
board_edge_margin: props.boardEdgeMargin ?? clearance,
|
|
75545
|
+
board_edge_outline: copperPour._isImplicitCopperPour ? resolvedPcbBoardOutline : void 0,
|
|
75546
|
+
cutout_margin: props.cutoutMargin ?? clearance,
|
|
75547
|
+
...props.useThermalReliefs ? {
|
|
75548
|
+
use_thermal_reliefs: true,
|
|
75549
|
+
thermal_relief_spoke_width: DEFAULT_THERMAL_RELIEF_SPOKE_WIDTH_MM
|
|
75550
|
+
} : {},
|
|
75551
|
+
outline: props.outline ?? resolvedPcbBoardOutline
|
|
75552
|
+
};
|
|
75553
|
+
})
|
|
75554
|
+
);
|
|
75555
|
+
await initializeManifoldGeometry();
|
|
75556
|
+
const solver = new CopperPourPipelineSolver2(inputProblem);
|
|
75557
|
+
subcircuit.root.emit("solver:started", {
|
|
75558
|
+
type: "solver:started",
|
|
75559
|
+
solverName: "CopperPourPipelineSolver",
|
|
75560
|
+
solverParams: inputProblem,
|
|
75561
|
+
solverConstructorArgs: [inputProblem],
|
|
75562
|
+
componentName: subcircuit.getString()
|
|
75563
|
+
});
|
|
75564
|
+
const { brep_shapes_by_region } = solver.getOutput();
|
|
75565
|
+
for (const [
|
|
75566
|
+
regionIndex,
|
|
75567
|
+
{ copperPour, sourceNetId }
|
|
75568
|
+
] of resolvedCopperPours.entries()) {
|
|
75569
|
+
const { _parsedProps: props } = copperPour;
|
|
75570
|
+
const coveredWithSolderMask = props.coveredWithSolderMask ?? false;
|
|
75571
|
+
for (const brepShape of brep_shapes_by_region[regionIndex] ?? []) {
|
|
75572
|
+
const insertedPour = db.pcb_copper_pour.insert({
|
|
75573
|
+
shape: "brep",
|
|
75574
|
+
layer: props.layer,
|
|
75575
|
+
brep_shape: brepShape,
|
|
75576
|
+
source_net_id: sourceNetId,
|
|
75577
|
+
subcircuit_id: subcircuit.subcircuit_id ?? void 0,
|
|
75578
|
+
covered_with_solder_mask: coveredWithSolderMask
|
|
75579
|
+
});
|
|
75580
|
+
markTraceSegmentsInsideCopperPour({
|
|
75581
|
+
db,
|
|
75582
|
+
copperPour: insertedPour
|
|
75583
|
+
});
|
|
75584
|
+
}
|
|
75585
|
+
}
|
|
75586
|
+
};
|
|
75587
|
+
function CopperPour_doInitialPcbCopperPourRender(copperPour) {
|
|
75588
|
+
if (copperPour.root?.pcbDisabled) return;
|
|
75589
|
+
copperPour._queueAsyncEffect("PcbCopperPourRender", async () => {
|
|
75590
|
+
const subcircuit = copperPour.getSubcircuit();
|
|
75591
|
+
const pendingRender = pendingCopperPourRenders.get(subcircuit);
|
|
75592
|
+
if (pendingRender) {
|
|
75593
|
+
await pendingRender;
|
|
75594
|
+
return;
|
|
75595
|
+
}
|
|
75596
|
+
const renderPromise = renderAllCopperPoursForSubcircuit(subcircuit);
|
|
75597
|
+
pendingCopperPourRenders.set(subcircuit, renderPromise);
|
|
75598
|
+
try {
|
|
75599
|
+
await renderPromise;
|
|
75600
|
+
} finally {
|
|
75601
|
+
pendingCopperPourRenders.delete(subcircuit);
|
|
75602
|
+
}
|
|
75603
|
+
});
|
|
75604
|
+
}
|
|
75605
|
+
|
|
75606
|
+
// lib/components/primitive-components/CopperPour/CopperPour_doInitialPcbViaStitchRender.ts
|
|
75607
|
+
import { pcb_via as pcb_via3 } from "circuit-json";
|
|
75608
|
+
var renderViaStitchingForCopperPours = (copperPour) => {
|
|
75609
|
+
const subcircuit = copperPour.getSubcircuit();
|
|
75610
|
+
if (!subcircuit.root) return;
|
|
75611
|
+
const copperPours = subcircuit.selectAll("copperpour").filter(
|
|
75612
|
+
(candidateCopperPour) => candidateCopperPour.getSubcircuit() === subcircuit
|
|
75613
|
+
);
|
|
75614
|
+
if (copperPours[0] !== copperPour) return;
|
|
75615
|
+
const sourceNetIds = copperPours.flatMap((candidateCopperPour) => {
|
|
75616
|
+
const net = subcircuit.selectOne(
|
|
75617
|
+
candidateCopperPour._parsedProps.connectsTo
|
|
75618
|
+
);
|
|
75619
|
+
return net?.source_net_id ? [net.source_net_id] : [];
|
|
75620
|
+
});
|
|
75621
|
+
if (sourceNetIds.length === 0) return;
|
|
75622
|
+
const { db } = subcircuit.root;
|
|
75623
|
+
const pcbStyle = copperPour.getInheritedMergedProperty("pcbStyle");
|
|
75624
|
+
const { holeDiameter, padDiameter } = getViaDiameterDefaults(pcbStyle);
|
|
75625
|
+
const boardComponent = copperPour._getBoard();
|
|
75626
|
+
const pcbBoard = boardComponent?.pcb_board_id ? db.pcb_board.get(boardComponent.pcb_board_id) : void 0;
|
|
75627
|
+
const solverInput = {
|
|
75628
|
+
circuitJson: db.toArray(),
|
|
75629
|
+
options: {
|
|
75630
|
+
sourceNetIds: [...new Set(sourceNetIds)],
|
|
75631
|
+
viaHoleDiameter: pcbBoard?.min_via_hole_diameter ?? holeDiameter,
|
|
75632
|
+
viaOuterDiameter: pcbBoard?.min_via_pad_diameter ?? padDiameter,
|
|
75633
|
+
viaStitchPitch: boardComponent?._parsedProps.viaStitchPitch
|
|
75634
|
+
}
|
|
75635
|
+
};
|
|
75636
|
+
const solver = new ViaStitchSolver(solverInput);
|
|
75637
|
+
subcircuit.root.emit("solver:started", {
|
|
75638
|
+
type: "solver:started",
|
|
75639
|
+
solverName: "ViaStitchSolver",
|
|
75640
|
+
solverParams: solverInput,
|
|
75641
|
+
solverConstructorArgs: [solverInput],
|
|
75642
|
+
componentName: subcircuit.getString()
|
|
75643
|
+
});
|
|
75644
|
+
solver.solve();
|
|
75645
|
+
if (solver.failed) {
|
|
75646
|
+
throw new Error(solver.error ?? "Via stitching solver failed");
|
|
75647
|
+
}
|
|
75648
|
+
for (const pcbVia of solver.getOutput().pcbVias) {
|
|
75649
|
+
const { pcb_via_id: _solverViaId, ...pcbViaInput } = pcb_via3.parse(pcbVia);
|
|
75650
|
+
const insertedVia = db.pcb_via.insert({
|
|
75651
|
+
...pcbViaInput,
|
|
75652
|
+
tented_on_top: void 0,
|
|
75653
|
+
tented_on_bottom: void 0
|
|
75654
|
+
});
|
|
75655
|
+
boardComponent?._generatedStitchingViaIds?.add(insertedVia.pcb_via_id);
|
|
75656
|
+
}
|
|
75657
|
+
};
|
|
75658
|
+
function CopperPour_doInitialPcbViaStitchRender(copperPour) {
|
|
75659
|
+
if (copperPour.root?.pcbDisabled || !copperPour.root?._featurePcbViaStitching)
|
|
75660
|
+
return;
|
|
75661
|
+
if (!copperPour._getBoard()?._parsedProps.enableViaStitching) return;
|
|
75662
|
+
copperPour._queueAsyncEffect("PcbViaStitchRender", async () => {
|
|
75663
|
+
renderViaStitchingForCopperPours(copperPour);
|
|
75664
|
+
});
|
|
75665
|
+
}
|
|
75666
|
+
|
|
75667
|
+
// lib/components/primitive-components/CopperPour/CopperPour.ts
|
|
75668
|
+
var CopperPour = class extends PrimitiveComponent2 {
|
|
75669
|
+
isPcbPrimitive = true;
|
|
75670
|
+
_isImplicitCopperPour = false;
|
|
75671
|
+
get config() {
|
|
75672
|
+
return {
|
|
75673
|
+
componentName: "CopperPour",
|
|
75674
|
+
zodProps: copperPourProps
|
|
75675
|
+
};
|
|
75676
|
+
}
|
|
75677
|
+
getPcbSize() {
|
|
75678
|
+
return { width: 0, height: 0 };
|
|
75679
|
+
}
|
|
75680
|
+
doInitialCreateNetsFromProps() {
|
|
75681
|
+
const { _parsedProps: props } = this;
|
|
75682
|
+
createNetsFromProps(this, [props.connectsTo]);
|
|
75683
|
+
}
|
|
75684
|
+
doInitialPcbCopperPourRender() {
|
|
75685
|
+
CopperPour_doInitialPcbCopperPourRender(this);
|
|
75686
|
+
}
|
|
75687
|
+
doInitialPcbViaStitchRender() {
|
|
75688
|
+
CopperPour_doInitialPcbViaStitchRender(this);
|
|
75689
|
+
}
|
|
75690
|
+
};
|
|
75691
|
+
|
|
75756
75692
|
// lib/components/primitive-components/AssemblyDevice.ts
|
|
75757
75693
|
import { assemblyDeviceProps } from "@tscircuit/props";
|
|
75758
75694
|
import { identity as identity10 } from "transformation-matrix";
|
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.1969",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@tscircuit/checks": "^0.0.208",
|
|
41
41
|
"@tscircuit/circuit-json-util": "^0.0.116",
|
|
42
42
|
"@tscircuit/common": "^0.0.20",
|
|
43
|
-
"@tscircuit/copper-pour-solver": "^0.0.
|
|
43
|
+
"@tscircuit/copper-pour-solver": "^0.0.57",
|
|
44
44
|
"@tscircuit/create-fdm-enclosure": "0.0.4",
|
|
45
45
|
"@tscircuit/fanout-solver": "0.0.78",
|
|
46
46
|
"@tscircuit/footprinter": "^0.0.426",
|