@tscircuit/copper-pour-solver 0.0.11 → 0.0.13
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/.github/workflows/bun-test.yml +1 -1
- package/dist/index.js +3 -32
- package/lib/circuit-json/convert-circuit-json-to-input-problem.ts +0 -6
- package/lib/solvers/copper-pour/get-board-polygon.ts +4 -0
- package/lib/solvers/copper-pour/process-obstacles.ts +0 -26
- package/package.json +1 -1
- package/tests/__snapshots__/polygon-board-2.snap.svg +1 -0
- package/tests/assets/polygon-board-2.json +1422 -0
- package/tests/polygon-board-2.test.ts +16 -0
package/dist/index.js
CHANGED
|
@@ -9,6 +9,9 @@ var getBoardPolygon = (region) => {
|
|
|
9
9
|
const polygon = new Flatten.Polygon(
|
|
10
10
|
region.outline.map((p) => Flatten.point(p.x, p.y))
|
|
11
11
|
);
|
|
12
|
+
if (polygon.orientation() === Flatten.ORIENTATION.CW) {
|
|
13
|
+
polygon.reverse();
|
|
14
|
+
}
|
|
12
15
|
return polygon;
|
|
13
16
|
}
|
|
14
17
|
const { bounds } = region;
|
|
@@ -127,15 +130,6 @@ var processObstaclesForPour = (pads, pourConnectivityKey, margins, boardOutline)
|
|
|
127
130
|
const isHoleOrCutout = pad.connectivityKey.startsWith("hole:") || pad.connectivityKey.startsWith("cutout:");
|
|
128
131
|
if (isCircularPad(pad)) {
|
|
129
132
|
const margin = isHoleOrCutout ? cutoutMargin ?? 0 : padMargin;
|
|
130
|
-
if (isHoleOrCutout) {
|
|
131
|
-
console.log(
|
|
132
|
-
`Applying cutout margin to circular pad/hole/cutout: ${pad.padId}, margin: ${margin}`
|
|
133
|
-
);
|
|
134
|
-
} else {
|
|
135
|
-
console.log(
|
|
136
|
-
`Applying pad margin to circular pad: ${pad.padId}, margin: ${margin}`
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
133
|
const circle = new Flatten3.Circle(
|
|
140
134
|
new Flatten3.Point(pad.x, pad.y),
|
|
141
135
|
pad.radius + margin
|
|
@@ -145,15 +139,6 @@ var processObstaclesForPour = (pads, pourConnectivityKey, margins, boardOutline)
|
|
|
145
139
|
}
|
|
146
140
|
if (isRectPad(pad)) {
|
|
147
141
|
const margin = isHoleOrCutout ? cutoutMargin ?? 0 : padMargin;
|
|
148
|
-
if (isHoleOrCutout) {
|
|
149
|
-
console.log(
|
|
150
|
-
`Applying cutout margin to rect pad/cutout: ${pad.padId}, margin: ${margin}`
|
|
151
|
-
);
|
|
152
|
-
} else {
|
|
153
|
-
console.log(
|
|
154
|
-
`Applying pad margin to rect pad: ${pad.padId}, margin: ${margin}`
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
142
|
const { bounds } = pad;
|
|
158
143
|
const b = new Flatten3.Box(
|
|
159
144
|
bounds.minX - margin,
|
|
@@ -166,18 +151,10 @@ var processObstaclesForPour = (pads, pourConnectivityKey, margins, boardOutline)
|
|
|
166
151
|
}
|
|
167
152
|
if (isPolygonPad(pad)) {
|
|
168
153
|
const margin = isHoleOrCutout ? cutoutMargin ?? 0 : 0;
|
|
169
|
-
if (isHoleOrCutout) {
|
|
170
|
-
console.log(
|
|
171
|
-
`Applying cutout margin to polygon cutout: ${pad.padId}, margin: ${margin}`
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
154
|
const seen = /* @__PURE__ */ new Set();
|
|
175
155
|
const uniquePoints = pad.points.filter((p) => {
|
|
176
156
|
const key = `${p.x},${p.y}`;
|
|
177
157
|
if (seen.has(key)) {
|
|
178
|
-
console.log(
|
|
179
|
-
`Duplicate point detected and removed for ${pad.padId}: (${p.x}, ${p.y})`
|
|
180
|
-
);
|
|
181
158
|
return false;
|
|
182
159
|
}
|
|
183
160
|
seen.add(key);
|
|
@@ -490,9 +467,6 @@ var convertCircuitJsonToInputProblem = (circuitJson, options) => {
|
|
|
490
467
|
});
|
|
491
468
|
} else if (elm.type === "pcb_cutout") {
|
|
492
469
|
const cutout = elm;
|
|
493
|
-
console.log(
|
|
494
|
-
`Processing cutout: ${cutout.pcb_cutout_id} (shape: ${cutout.shape})`
|
|
495
|
-
);
|
|
496
470
|
if (cutout.shape === "rect") {
|
|
497
471
|
pads.push({
|
|
498
472
|
shape: "rect",
|
|
@@ -519,9 +493,6 @@ var convertCircuitJsonToInputProblem = (circuitJson, options) => {
|
|
|
519
493
|
radius: cutout.radius
|
|
520
494
|
});
|
|
521
495
|
} else if (cutout.shape === "polygon") {
|
|
522
|
-
console.log(
|
|
523
|
-
`Polygon cutout points for ${cutout.pcb_cutout_id}: ${JSON.stringify(cutout.points)}`
|
|
524
|
-
);
|
|
525
496
|
pads.push({
|
|
526
497
|
shape: "polygon",
|
|
527
498
|
padId: cutout.pcb_cutout_id,
|
|
@@ -184,9 +184,6 @@ export const convertCircuitJsonToInputProblem = (
|
|
|
184
184
|
} as InputCircularPad)
|
|
185
185
|
} else if (elm.type === "pcb_cutout") {
|
|
186
186
|
const cutout = elm as any
|
|
187
|
-
console.log(
|
|
188
|
-
`Processing cutout: ${cutout.pcb_cutout_id} (shape: ${cutout.shape})`,
|
|
189
|
-
)
|
|
190
187
|
if (cutout.shape === "rect") {
|
|
191
188
|
pads.push({
|
|
192
189
|
shape: "rect",
|
|
@@ -211,9 +208,6 @@ export const convertCircuitJsonToInputProblem = (
|
|
|
211
208
|
radius: cutout.radius,
|
|
212
209
|
} as InputCircularPad)
|
|
213
210
|
} else if (cutout.shape === "polygon") {
|
|
214
|
-
console.log(
|
|
215
|
-
`Polygon cutout points for ${cutout.pcb_cutout_id}: ${JSON.stringify(cutout.points)}`,
|
|
216
|
-
)
|
|
217
211
|
pads.push({
|
|
218
212
|
shape: "polygon",
|
|
219
213
|
padId: cutout.pcb_cutout_id,
|
|
@@ -8,6 +8,10 @@ export const getBoardPolygon = (region: InputPourRegion): Flatten.Polygon => {
|
|
|
8
8
|
const polygon = new Flatten.Polygon(
|
|
9
9
|
region.outline.map((p) => Flatten.point(p.x, p.y)),
|
|
10
10
|
)
|
|
11
|
+
// Ensure polygon is CCW for consistent boolean operations
|
|
12
|
+
if (polygon.orientation() === Flatten.ORIENTATION.CW) {
|
|
13
|
+
polygon.reverse()
|
|
14
|
+
}
|
|
11
15
|
return polygon
|
|
12
16
|
}
|
|
13
17
|
|
|
@@ -130,15 +130,6 @@ export const processObstaclesForPour = (
|
|
|
130
130
|
|
|
131
131
|
if (isCircularPad(pad)) {
|
|
132
132
|
const margin = isHoleOrCutout ? (cutoutMargin ?? 0) : padMargin
|
|
133
|
-
if (isHoleOrCutout) {
|
|
134
|
-
console.log(
|
|
135
|
-
`Applying cutout margin to circular pad/hole/cutout: ${pad.padId}, margin: ${margin}`,
|
|
136
|
-
)
|
|
137
|
-
} else {
|
|
138
|
-
console.log(
|
|
139
|
-
`Applying pad margin to circular pad: ${pad.padId}, margin: ${margin}`,
|
|
140
|
-
)
|
|
141
|
-
}
|
|
142
133
|
const circle = new Flatten.Circle(
|
|
143
134
|
new Flatten.Point(pad.x, pad.y),
|
|
144
135
|
pad.radius + margin,
|
|
@@ -149,15 +140,6 @@ export const processObstaclesForPour = (
|
|
|
149
140
|
|
|
150
141
|
if (isRectPad(pad)) {
|
|
151
142
|
const margin = isHoleOrCutout ? (cutoutMargin ?? 0) : padMargin
|
|
152
|
-
if (isHoleOrCutout) {
|
|
153
|
-
console.log(
|
|
154
|
-
`Applying cutout margin to rect pad/cutout: ${pad.padId}, margin: ${margin}`,
|
|
155
|
-
)
|
|
156
|
-
} else {
|
|
157
|
-
console.log(
|
|
158
|
-
`Applying pad margin to rect pad: ${pad.padId}, margin: ${margin}`,
|
|
159
|
-
)
|
|
160
|
-
}
|
|
161
143
|
const { bounds } = pad
|
|
162
144
|
const b = new Flatten.Box(
|
|
163
145
|
bounds.minX - margin,
|
|
@@ -171,19 +153,11 @@ export const processObstaclesForPour = (
|
|
|
171
153
|
|
|
172
154
|
if (isPolygonPad(pad)) {
|
|
173
155
|
const margin = isHoleOrCutout ? (cutoutMargin ?? 0) : 0
|
|
174
|
-
if (isHoleOrCutout) {
|
|
175
|
-
console.log(
|
|
176
|
-
`Applying cutout margin to polygon cutout: ${pad.padId}, margin: ${margin}`,
|
|
177
|
-
)
|
|
178
|
-
}
|
|
179
156
|
|
|
180
157
|
const seen = new Set<string>()
|
|
181
158
|
const uniquePoints = pad.points.filter((p) => {
|
|
182
159
|
const key = `${p.x},${p.y}`
|
|
183
160
|
if (seen.has(key)) {
|
|
184
|
-
console.log(
|
|
185
|
-
`Duplicate point detected and removed for ${pad.padId}: (${p.x}, ${p.y})`,
|
|
186
|
-
)
|
|
187
161
|
return false
|
|
188
162
|
}
|
|
189
163
|
seen.add(key)
|
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="800" height="600" data-software-used-string="@tscircuit/core@0.0.852"><style></style><rect class="boundary" x="0" y="0" fill="#000" width="800" height="600" data-type="pcb_background" data-pcb-layer="global"/><rect class="pcb-boundary" fill="none" stroke="#fff" stroke-width="0.3" x="25" y="50" width="750" height="500" data-type="pcb_boundary" data-pcb-layer="global"/><path class="pcb-board" d="M 75 50 L 725 50 L 775 100 L 775 500 L 725 550 L 75 550 L 25 500 L 25 100 Z" fill="none" stroke="rgba(255, 255, 255, 0.5)" stroke-width="2.5" data-type="pcb_board" data-pcb-layer="board"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="183.75" y="244.875" width="25" height="15" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="183.75" y="276.625" width="25" height="15" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="183.75" y="308.375" width="25" height="15" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="183.75" y="340.125" width="25" height="15" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="291.25" y="340.125" width="25" height="15" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="291.25" y="308.375" width="25" height="15" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="291.25" y="276.625" width="25" height="15" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="291.25" y="244.875" width="25" height="15" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="530.5" y="292" width="13.5" height="16" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="556" y="292" width="13.5" height="16" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="530.5" y="392" width="13.5" height="16" data-type="pcb_smtpad" data-pcb-layer="top"/><rect class="pcb-pad" fill="rgb(200, 52, 52)" x="556" y="392" width="13.5" height="16" data-type="pcb_smtpad" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 562.75 400 L 562.75 300" stroke-width="3.75" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 562.75 300 L 562.75 300" stroke-width="3.75" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 562.75 300 L 527.9515350550832 334.79846494491676" stroke-width="3.75" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 527.9515350550832 334.79846494491676 L 209.67952397049152 334.79846494491676" stroke-width="3.75" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 209.67952397049152 334.79846494491676 L 209.07653505508324 334.79846494491676" stroke-width="3.75" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-trace" stroke="rgb(200, 52, 52)" fill="none" d="M 209.07653505508324 334.79846494491676 L 196.25 347.625" stroke-width="3.75" stroke-linecap="round" stroke-linejoin="round" shape-rendering="crispEdges" data-type="pcb_trace" data-pcb-layer="top"/><path class="pcb-copper-pour pcb-copper-pour-brep" d="M 30 102.07106781186539 L 77.07106781186542 54.99999999999997 L 80 54.99999999999997 L 720 54.99999999999997 L 722.9289321881346 54.99999999999997 L 770 102.07106781186539 L 770 105 L 770 495 L 770 497.9289321881346 L 722.9289321881345 545 L 720 545 L 80 545 L 77.07106781186542 545 L 30 497.9289321881346 L 30 495 L 30 105 L 30 102.07106781186539 Z M 286.25 360.125 L 321.25 360.125 L 321.25 335.125 L 286.25 335.125 L 286.25 360.125 Z M 286.25 264.875 L 321.25 264.875 L 321.25 239.875 L 286.25 239.875 L 286.25 264.875 Z M 286.25 328.375 L 321.25 328.375 L 321.25 303.375 L 286.25 303.375 L 286.25 328.375 Z M 286.25 296.625 L 321.25 296.625 L 321.25 271.625 L 286.25 271.625 L 286.25 296.625 Z M 178.75 264.875 L 213.75 264.875 L 213.75 239.875 L 178.75 239.875 L 178.75 264.875 Z M 178.75 296.625 L 213.75 296.625 L 213.75 271.625 L 178.75 271.625 L 178.75 296.625 Z M 178.75 328.375 L 213.75 328.375 L 213.75 303.375 L 178.75 303.375 L 178.75 328.375 Z M 525.5 413 L 549 413 L 549 387 L 525.5 387 L 525.5 413 Z M 525.5 313 L 549 313 L 549 287 L 525.5 287 L 525.5 313 Z" fill="rgb(200, 52, 52)" fill-rule="evenodd" fill-opacity="0.5" data-type="pcb_copper_pour" data-pcb-layer="top"/><path class="pcb-silkscreen pcb-silkscreen-top" d="M 211.25 363.0625 L 211.25 236.9375 L 237.08333333333334 236.9375 L 238.06655603839587 241.88049433471576 L 240.86653740967375 246.07096259032625 L 245.05700566528427 248.87094396160413 L 250 249.85416666666666 L 254.94299433471573 248.87094396160413 L 259.13346259032625 246.07096259032625 L 261.9334439616041 241.88049433471576 L 262.91666666666663 236.9375 L 288.75 236.9375 L 288.75 363.0625 L 211.25 363.0625 Z" fill="none" stroke="#f2eda1" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" data-pcb-component-id="pcb_component_0" data-pcb-silkscreen-path-id="pcb_silkscreen_path_0" data-type="pcb_silkscreen_path" data-pcb-layer="top"/><text x="0" y="0" dx="0" dy="0" fill="#f2eda1" font-family="Arial, sans-serif" font-size="15.510416666666666" text-anchor="middle" dominant-baseline="central" transform="matrix(1,0,0,1,250,226.9375)" class="pcb-silkscreen-text pcb-silkscreen-top" data-pcb-silkscreen-text-id="pcb_component_0" stroke="none" data-type="pcb_silkscreen_text" data-pcb-layer="top">U1</text><path class="pcb-silkscreen pcb-silkscreen-top" d="M 562.75 282 L 525.5 282 L 525.5 318 L 562.75 318" fill="none" stroke="#f2eda1" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" data-pcb-component-id="pcb_component_1" data-pcb-silkscreen-path-id="pcb_silkscreen_path_1" data-type="pcb_silkscreen_path" data-pcb-layer="top"/><text x="0" y="0" dx="0" dy="0" fill="#f2eda1" font-family="Arial, sans-serif" font-size="10" text-anchor="middle" dominant-baseline="central" transform="matrix(1,0,0,1,550,269.5)" class="pcb-silkscreen-text pcb-silkscreen-top" data-pcb-silkscreen-text-id="pcb_component_1" stroke="none" data-type="pcb_silkscreen_text" data-pcb-layer="top">R1</text><path class="pcb-silkscreen pcb-silkscreen-top" d="M 562.75 382 L 525.5 382 L 525.5 418 L 562.75 418" fill="none" stroke="#f2eda1" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" data-pcb-component-id="pcb_component_2" data-pcb-silkscreen-path-id="pcb_silkscreen_path_2" data-type="pcb_silkscreen_path" data-pcb-layer="top"/><text x="0" y="0" dx="0" dy="0" fill="#f2eda1" font-family="Arial, sans-serif" font-size="10" text-anchor="middle" dominant-baseline="central" transform="matrix(1,0,0,1,550,369.5)" class="pcb-silkscreen-text pcb-silkscreen-top" data-pcb-silkscreen-text-id="pcb_component_2" stroke="none" data-type="pcb_silkscreen_text" data-pcb-layer="top">C1</text></svg>
|