@tscircuit/core 0.0.841 → 0.0.843
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 +11 -10
- package/dist/index.js +238 -166
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -55,9 +55,10 @@ declare abstract class Renderable implements IRenderable {
|
|
|
55
55
|
protected _emitRenderLifecycleEvent(phase: RenderPhase, startOrEnd: "start" | "end"): void;
|
|
56
56
|
getString(): string;
|
|
57
57
|
_hasIncompleteAsyncEffects(): boolean;
|
|
58
|
-
|
|
58
|
+
_hasIncompleteAsyncEffectsInSubtreeForPhase(phase: RenderPhase): boolean;
|
|
59
59
|
getCurrentRenderPhase(): RenderPhase | null;
|
|
60
60
|
getRenderGraph(): Record<string, any>;
|
|
61
|
+
getTopLevelRenderable(): Renderable;
|
|
61
62
|
runRenderCycle(): void;
|
|
62
63
|
/**
|
|
63
64
|
* This runs all the render methods for a given phase, calling one of:
|
|
@@ -24638,21 +24639,21 @@ declare class CopperPour extends PrimitiveComponent<typeof copperPourProps> {
|
|
|
24638
24639
|
isPcbPrimitive: boolean;
|
|
24639
24640
|
get config(): {
|
|
24640
24641
|
componentName: string;
|
|
24641
|
-
zodProps:
|
|
24642
|
-
name:
|
|
24643
|
-
layer:
|
|
24644
|
-
name:
|
|
24645
|
-
}, "strip",
|
|
24642
|
+
zodProps: zod.ZodObject<{
|
|
24643
|
+
name: zod.ZodOptional<zod.ZodString>;
|
|
24644
|
+
layer: zod.ZodEffects<zod.ZodUnion<[zod.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>, zod.ZodObject<{
|
|
24645
|
+
name: zod.ZodEnum<["top", "bottom", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6"]>;
|
|
24646
|
+
}, "strip", zod.ZodTypeAny, {
|
|
24646
24647
|
name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
|
|
24647
24648
|
}, {
|
|
24648
24649
|
name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
|
|
24649
24650
|
}>]>, "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6", "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6" | {
|
|
24650
24651
|
name: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
|
|
24651
24652
|
}>;
|
|
24652
|
-
connectsTo:
|
|
24653
|
-
padMargin:
|
|
24654
|
-
traceMargin:
|
|
24655
|
-
}, "strip",
|
|
24653
|
+
connectsTo: zod.ZodString;
|
|
24654
|
+
padMargin: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
|
|
24655
|
+
traceMargin: zod.ZodOptional<zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>>;
|
|
24656
|
+
}, "strip", zod.ZodTypeAny, {
|
|
24656
24657
|
layer: "top" | "bottom" | "inner1" | "inner2" | "inner3" | "inner4" | "inner5" | "inner6";
|
|
24657
24658
|
connectsTo: string;
|
|
24658
24659
|
name?: string | undefined;
|
package/dist/index.js
CHANGED
|
@@ -174,7 +174,7 @@ var asyncPhaseDependencies = {
|
|
|
174
174
|
PcbComponentAnchorAlignment: ["PcbFootprintStringRender"]
|
|
175
175
|
};
|
|
176
176
|
var globalRenderCounter = 0;
|
|
177
|
-
var Renderable = class {
|
|
177
|
+
var Renderable = class _Renderable {
|
|
178
178
|
renderPhaseStates;
|
|
179
179
|
shouldBeRemoved = false;
|
|
180
180
|
children;
|
|
@@ -299,6 +299,13 @@ ${error.stack}`
|
|
|
299
299
|
)
|
|
300
300
|
};
|
|
301
301
|
}
|
|
302
|
+
getTopLevelRenderable() {
|
|
303
|
+
let current = this;
|
|
304
|
+
while (current.parent && current.parent instanceof _Renderable) {
|
|
305
|
+
current = current.parent;
|
|
306
|
+
}
|
|
307
|
+
return current;
|
|
308
|
+
}
|
|
302
309
|
runRenderCycle() {
|
|
303
310
|
for (const renderPhase of orderedRenderPhases) {
|
|
304
311
|
this.runRenderPhaseForChildren(renderPhase);
|
|
@@ -333,8 +340,13 @@ ${error.stack}`
|
|
|
333
340
|
if (hasIncompleteEffects) return;
|
|
334
341
|
}
|
|
335
342
|
const deps = asyncPhaseDependencies[phase] || [];
|
|
336
|
-
|
|
337
|
-
|
|
343
|
+
if (deps.length > 0) {
|
|
344
|
+
const root = this.getTopLevelRenderable();
|
|
345
|
+
for (const depPhase of deps) {
|
|
346
|
+
if (root._hasIncompleteAsyncEffectsInSubtreeForPhase(depPhase)) {
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
338
350
|
}
|
|
339
351
|
this._emitRenderLifecycleEvent(phase, "start");
|
|
340
352
|
if (isInitialized) {
|
|
@@ -16302,11 +16314,218 @@ var Via = class extends PrimitiveComponent2 {
|
|
|
16302
16314
|
}
|
|
16303
16315
|
};
|
|
16304
16316
|
|
|
16305
|
-
// lib/components/primitive-components/CopperPour.ts
|
|
16317
|
+
// lib/components/primitive-components/CopperPour/CopperPour.ts
|
|
16306
16318
|
import { copperPourProps } from "@tscircuit/props";
|
|
16307
|
-
import "zod";
|
|
16308
|
-
import Flatten from "@flatten-js/core";
|
|
16309
16319
|
import { getFullConnectivityMapFromCircuitJson as getFullConnectivityMapFromCircuitJson4 } from "circuit-json-to-connectivity-map";
|
|
16320
|
+
import Flatten4 from "@flatten-js/core";
|
|
16321
|
+
|
|
16322
|
+
// lib/components/primitive-components/CopperPour/utils/get-board-polygon.ts
|
|
16323
|
+
import Flatten from "@flatten-js/core";
|
|
16324
|
+
var getBoardPolygon = (board) => {
|
|
16325
|
+
if (board.outline && board.outline.length > 0) {
|
|
16326
|
+
return new Flatten.Polygon(
|
|
16327
|
+
board.outline.map((p) => Flatten.point(p.x, p.y))
|
|
16328
|
+
);
|
|
16329
|
+
}
|
|
16330
|
+
return new Flatten.Polygon(
|
|
16331
|
+
new Flatten.Box(
|
|
16332
|
+
board.center.x - board.width / 2,
|
|
16333
|
+
board.center.y - board.height / 2,
|
|
16334
|
+
board.center.x + board.width / 2,
|
|
16335
|
+
board.center.y + board.height / 2
|
|
16336
|
+
).toPoints()
|
|
16337
|
+
);
|
|
16338
|
+
};
|
|
16339
|
+
|
|
16340
|
+
// lib/components/primitive-components/CopperPour/utils/get-trace-obstacles.ts
|
|
16341
|
+
var getTraceObstacles = (db, layer) => {
|
|
16342
|
+
const traceObstacles = [];
|
|
16343
|
+
for (const pcb_trace of db.pcb_trace.list()) {
|
|
16344
|
+
if (!pcb_trace.route) continue;
|
|
16345
|
+
const source_trace = pcb_trace.source_trace_id ? db.source_trace.get(pcb_trace.source_trace_id) : null;
|
|
16346
|
+
const connectedToIds = /* @__PURE__ */ new Set();
|
|
16347
|
+
if (pcb_trace.source_trace_id) {
|
|
16348
|
+
connectedToIds.add(pcb_trace.source_trace_id);
|
|
16349
|
+
}
|
|
16350
|
+
if (source_trace) {
|
|
16351
|
+
for (const id of source_trace.connected_source_net_ids)
|
|
16352
|
+
connectedToIds.add(id);
|
|
16353
|
+
for (const id of source_trace.connected_source_port_ids)
|
|
16354
|
+
connectedToIds.add(id);
|
|
16355
|
+
}
|
|
16356
|
+
for (const pt of pcb_trace.route) {
|
|
16357
|
+
if (pt.route_type === "wire") {
|
|
16358
|
+
if (pt.start_pcb_port_id) {
|
|
16359
|
+
const pcb_port = db.pcb_port.get(pt.start_pcb_port_id);
|
|
16360
|
+
if (pcb_port?.source_port_id)
|
|
16361
|
+
connectedToIds.add(pcb_port.source_port_id);
|
|
16362
|
+
}
|
|
16363
|
+
if (pt.end_pcb_port_id) {
|
|
16364
|
+
const pcb_port = db.pcb_port.get(pt.end_pcb_port_id);
|
|
16365
|
+
if (pcb_port?.source_port_id)
|
|
16366
|
+
connectedToIds.add(pcb_port.source_port_id);
|
|
16367
|
+
}
|
|
16368
|
+
}
|
|
16369
|
+
}
|
|
16370
|
+
const connectedTo = Array.from(connectedToIds);
|
|
16371
|
+
for (let i = 0; i < pcb_trace.route.length - 1; i++) {
|
|
16372
|
+
const p1 = pcb_trace.route[i];
|
|
16373
|
+
const p2 = pcb_trace.route[i + 1];
|
|
16374
|
+
if (p1.route_type !== "wire" || p2.route_type !== "wire") continue;
|
|
16375
|
+
if (p1.layer !== layer) continue;
|
|
16376
|
+
const segmentWidth = p1.width;
|
|
16377
|
+
if (segmentWidth === 0) continue;
|
|
16378
|
+
const segmentLength = Math.hypot(p1.x - p2.x, p1.y - p2.y);
|
|
16379
|
+
if (segmentLength === 0) continue;
|
|
16380
|
+
const centerX = (p1.x + p2.x) / 2;
|
|
16381
|
+
const centerY = (p1.y + p2.y) / 2;
|
|
16382
|
+
const rotationDeg = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;
|
|
16383
|
+
const rotatedRect = {
|
|
16384
|
+
center: { x: centerX, y: centerY },
|
|
16385
|
+
width: segmentLength,
|
|
16386
|
+
height: segmentWidth,
|
|
16387
|
+
rotation: rotationDeg
|
|
16388
|
+
};
|
|
16389
|
+
const approximatingRects = generateApproximatingRects(rotatedRect);
|
|
16390
|
+
for (const rect of approximatingRects) {
|
|
16391
|
+
traceObstacles.push({
|
|
16392
|
+
type: "rect",
|
|
16393
|
+
layers: [p1.layer],
|
|
16394
|
+
center: rect.center,
|
|
16395
|
+
width: rect.width,
|
|
16396
|
+
height: rect.height,
|
|
16397
|
+
connectedTo,
|
|
16398
|
+
obstacle_type: "trace"
|
|
16399
|
+
});
|
|
16400
|
+
}
|
|
16401
|
+
}
|
|
16402
|
+
}
|
|
16403
|
+
return traceObstacles;
|
|
16404
|
+
};
|
|
16405
|
+
|
|
16406
|
+
// lib/components/primitive-components/CopperPour/utils/process-obstacles.ts
|
|
16407
|
+
import Flatten2 from "@flatten-js/core";
|
|
16408
|
+
var processObstaclesForPour = (obstacles, connMap, net, margins) => {
|
|
16409
|
+
const rectObstaclesToSubtract = [];
|
|
16410
|
+
const circularObstacles = [];
|
|
16411
|
+
const { traceMargin, padMargin } = margins;
|
|
16412
|
+
for (const obs of obstacles) {
|
|
16413
|
+
const isOnNet = obs.connectedTo.some(
|
|
16414
|
+
(id) => connMap.areIdsConnected(id, net.source_net_id)
|
|
16415
|
+
);
|
|
16416
|
+
if (isOnNet) {
|
|
16417
|
+
continue;
|
|
16418
|
+
}
|
|
16419
|
+
if (obs.type === "oval" && obs.width === obs.height) {
|
|
16420
|
+
const radius = obs.width / 2 + padMargin;
|
|
16421
|
+
circularObstacles.push({
|
|
16422
|
+
center: obs.center,
|
|
16423
|
+
radius
|
|
16424
|
+
});
|
|
16425
|
+
continue;
|
|
16426
|
+
}
|
|
16427
|
+
if (obs.type === "rect" && obs.width === obs.height && obs.connectedTo.length === 0) {
|
|
16428
|
+
const radius = obs.width / 2;
|
|
16429
|
+
circularObstacles.push({
|
|
16430
|
+
center: obs.center,
|
|
16431
|
+
radius
|
|
16432
|
+
});
|
|
16433
|
+
continue;
|
|
16434
|
+
}
|
|
16435
|
+
const margin = traceMargin;
|
|
16436
|
+
const b = new Flatten2.Box(
|
|
16437
|
+
obs.center.x - obs.width / 2 - margin,
|
|
16438
|
+
obs.center.y - obs.height / 2 - margin,
|
|
16439
|
+
obs.center.x + obs.width / 2 + margin,
|
|
16440
|
+
obs.center.y + obs.height / 2 + margin
|
|
16441
|
+
);
|
|
16442
|
+
rectObstaclesToSubtract.push(new Flatten2.Polygon(b.toPoints()));
|
|
16443
|
+
}
|
|
16444
|
+
return { rectObstaclesToSubtract, circularObstacles };
|
|
16445
|
+
};
|
|
16446
|
+
|
|
16447
|
+
// lib/components/primitive-components/CopperPour/utils/generate-and-insert-brep.ts
|
|
16448
|
+
import Flatten3 from "@flatten-js/core";
|
|
16449
|
+
var faceToVertices = (face) => face.edges.map((e) => {
|
|
16450
|
+
const pt = {
|
|
16451
|
+
x: e.start.x,
|
|
16452
|
+
y: e.start.y
|
|
16453
|
+
};
|
|
16454
|
+
if (e.isArc) {
|
|
16455
|
+
const bulge = Math.tan(e.shape.sweep / 4);
|
|
16456
|
+
if (Math.abs(bulge) > 1e-9) {
|
|
16457
|
+
pt.bulge = bulge;
|
|
16458
|
+
}
|
|
16459
|
+
}
|
|
16460
|
+
return pt;
|
|
16461
|
+
});
|
|
16462
|
+
var generateAndInsertBRep = (pourPolygons, circularObstacles, {
|
|
16463
|
+
db,
|
|
16464
|
+
copperPour
|
|
16465
|
+
}) => {
|
|
16466
|
+
const props = copperPour._parsedProps;
|
|
16467
|
+
const net = copperPour.getSubcircuit().selectOne(props.connectsTo);
|
|
16468
|
+
const subcircuit = copperPour.getSubcircuit();
|
|
16469
|
+
const polygons = Array.isArray(pourPolygons) ? pourPolygons : [pourPolygons];
|
|
16470
|
+
for (const p of polygons) {
|
|
16471
|
+
const islands = p.splitToIslands();
|
|
16472
|
+
for (const island of islands) {
|
|
16473
|
+
if (island.isEmpty()) continue;
|
|
16474
|
+
const faces = [...island.faces];
|
|
16475
|
+
const outer_face_ccw = faces.find(
|
|
16476
|
+
(f) => f.orientation() === Flatten3.ORIENTATION.CCW
|
|
16477
|
+
);
|
|
16478
|
+
const inner_faces_cw = faces.filter(
|
|
16479
|
+
(f) => f.orientation() === Flatten3.ORIENTATION.CW
|
|
16480
|
+
);
|
|
16481
|
+
if (!outer_face_ccw) continue;
|
|
16482
|
+
if (!db.pcb_copper_pour) {
|
|
16483
|
+
copperPour.renderError(
|
|
16484
|
+
"db.pcb_copper_pour not found. The database schema may be outdated."
|
|
16485
|
+
);
|
|
16486
|
+
return;
|
|
16487
|
+
}
|
|
16488
|
+
outer_face_ccw.reverse();
|
|
16489
|
+
const outer_ring_vertices = faceToVertices(outer_face_ccw);
|
|
16490
|
+
const inner_rings = inner_faces_cw.map((f) => {
|
|
16491
|
+
f.reverse();
|
|
16492
|
+
return { vertices: faceToVertices(f) };
|
|
16493
|
+
});
|
|
16494
|
+
for (const circle of circularObstacles) {
|
|
16495
|
+
const centerPoint = Flatten3.point(circle.center.x, circle.center.y);
|
|
16496
|
+
const isContained = island.contains(centerPoint);
|
|
16497
|
+
if (isContained) {
|
|
16498
|
+
inner_rings.push({
|
|
16499
|
+
vertices: [
|
|
16500
|
+
{
|
|
16501
|
+
x: circle.center.x,
|
|
16502
|
+
y: circle.center.y - circle.radius,
|
|
16503
|
+
bulge: 1
|
|
16504
|
+
},
|
|
16505
|
+
{
|
|
16506
|
+
x: circle.center.x,
|
|
16507
|
+
y: circle.center.y + circle.radius,
|
|
16508
|
+
bulge: 1
|
|
16509
|
+
}
|
|
16510
|
+
]
|
|
16511
|
+
});
|
|
16512
|
+
}
|
|
16513
|
+
}
|
|
16514
|
+
db.pcb_copper_pour.insert({
|
|
16515
|
+
shape: "brep",
|
|
16516
|
+
layer: props.layer,
|
|
16517
|
+
brep_shape: {
|
|
16518
|
+
outer_ring: { vertices: outer_ring_vertices },
|
|
16519
|
+
inner_rings
|
|
16520
|
+
},
|
|
16521
|
+
source_net_id: net.source_net_id,
|
|
16522
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0
|
|
16523
|
+
});
|
|
16524
|
+
}
|
|
16525
|
+
}
|
|
16526
|
+
};
|
|
16527
|
+
|
|
16528
|
+
// lib/components/primitive-components/CopperPour/CopperPour.ts
|
|
16310
16529
|
var CopperPour = class extends PrimitiveComponent2 {
|
|
16311
16530
|
isPcbPrimitive = true;
|
|
16312
16531
|
get config() {
|
|
@@ -16333,180 +16552,33 @@ var CopperPour = class extends PrimitiveComponent2 {
|
|
|
16333
16552
|
this.renderError("No board found for copper pour");
|
|
16334
16553
|
return;
|
|
16335
16554
|
}
|
|
16336
|
-
|
|
16337
|
-
if (board.outline && board.outline.length > 0) {
|
|
16338
|
-
boardPolygon = new Flatten.Polygon(
|
|
16339
|
-
board.outline.map((p) => Flatten.point(p.x, p.y))
|
|
16340
|
-
);
|
|
16341
|
-
} else {
|
|
16342
|
-
boardPolygon = new Flatten.Polygon(
|
|
16343
|
-
new Flatten.Box(
|
|
16344
|
-
board.center.x - board.width / 2,
|
|
16345
|
-
board.center.y - board.height / 2,
|
|
16346
|
-
board.center.x + board.width / 2,
|
|
16347
|
-
board.center.y + board.height / 2
|
|
16348
|
-
).toPoints()
|
|
16349
|
-
);
|
|
16350
|
-
}
|
|
16555
|
+
const boardPolygon = getBoardPolygon(board);
|
|
16351
16556
|
const connMap = getFullConnectivityMapFromCircuitJson4(db.toArray());
|
|
16352
16557
|
const obstaclesRaw = getObstaclesFromCircuitJson(
|
|
16353
16558
|
db.toArray(),
|
|
16354
16559
|
connMap
|
|
16355
16560
|
).filter((o) => o.layers.includes(props.layer));
|
|
16356
|
-
|
|
16357
|
-
|
|
16358
|
-
|
|
16359
|
-
|
|
16360
|
-
|
|
16361
|
-
if (p1.route_type !== "wire" || p2.route_type !== "wire") continue;
|
|
16362
|
-
if (p1.layer !== props.layer) continue;
|
|
16363
|
-
const segmentWidth = p1.width;
|
|
16364
|
-
if (segmentWidth === 0) continue;
|
|
16365
|
-
const segmentLength = Math.hypot(p1.x - p2.x, p1.y - p2.y);
|
|
16366
|
-
if (segmentLength === 0) continue;
|
|
16367
|
-
const centerX = (p1.x + p2.x) / 2;
|
|
16368
|
-
const centerY = (p1.y + p2.y) / 2;
|
|
16369
|
-
const rotationDeg = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;
|
|
16370
|
-
const rotatedRect = {
|
|
16371
|
-
center: { x: centerX, y: centerY },
|
|
16372
|
-
width: segmentLength,
|
|
16373
|
-
height: segmentWidth,
|
|
16374
|
-
rotation: rotationDeg
|
|
16375
|
-
};
|
|
16376
|
-
const approximatingRects = generateApproximatingRects(rotatedRect);
|
|
16377
|
-
for (const rect of approximatingRects) {
|
|
16378
|
-
obstaclesRaw.push({
|
|
16379
|
-
type: "rect",
|
|
16380
|
-
layers: [p1.layer],
|
|
16381
|
-
center: rect.center,
|
|
16382
|
-
width: rect.width,
|
|
16383
|
-
height: rect.height,
|
|
16384
|
-
connectedTo: pcb_trace.source_trace_id ? [pcb_trace.source_trace_id] : [],
|
|
16385
|
-
obstacle_type: "trace"
|
|
16386
|
-
});
|
|
16387
|
-
}
|
|
16388
|
-
}
|
|
16389
|
-
}
|
|
16390
|
-
const rectObstaclesToSubtract = [];
|
|
16391
|
-
const circularObstacles = [];
|
|
16392
|
-
const traceMargin = props.traceMargin ?? 0.2;
|
|
16393
|
-
const padMargin = props.padMargin ?? 0.2;
|
|
16394
|
-
for (const obs of obstaclesRaw) {
|
|
16395
|
-
const isOnNet = obs.connectedTo.some(
|
|
16396
|
-
(id) => connMap.areIdsConnected(id, net.source_net_id)
|
|
16397
|
-
);
|
|
16398
|
-
if (isOnNet) {
|
|
16399
|
-
continue;
|
|
16400
|
-
}
|
|
16401
|
-
if (obs.type === "oval" && obs.width === obs.height) {
|
|
16402
|
-
const radius = obs.width / 2 + padMargin;
|
|
16403
|
-
circularObstacles.push({
|
|
16404
|
-
center: obs.center,
|
|
16405
|
-
radius
|
|
16406
|
-
});
|
|
16407
|
-
continue;
|
|
16408
|
-
}
|
|
16409
|
-
if (obs.type === "rect" && obs.width === obs.height && obs.connectedTo.length === 0) {
|
|
16410
|
-
const radius = obs.width / 2;
|
|
16411
|
-
circularObstacles.push({
|
|
16412
|
-
center: obs.center,
|
|
16413
|
-
radius
|
|
16414
|
-
});
|
|
16415
|
-
continue;
|
|
16416
|
-
}
|
|
16417
|
-
const margin = traceMargin;
|
|
16418
|
-
const b = new Flatten.Box(
|
|
16419
|
-
obs.center.x - obs.width / 2 - margin,
|
|
16420
|
-
obs.center.y - obs.height / 2 - margin,
|
|
16421
|
-
obs.center.x + obs.width / 2 + margin,
|
|
16422
|
-
obs.center.y + obs.height / 2 + margin
|
|
16423
|
-
);
|
|
16424
|
-
rectObstaclesToSubtract.push(new Flatten.Polygon(b.toPoints()));
|
|
16425
|
-
}
|
|
16561
|
+
obstaclesRaw.push(...getTraceObstacles(db, props.layer));
|
|
16562
|
+
const { rectObstaclesToSubtract, circularObstacles } = processObstaclesForPour(obstaclesRaw, connMap, net, {
|
|
16563
|
+
traceMargin: props.traceMargin ?? 0.2,
|
|
16564
|
+
padMargin: props.padMargin ?? 0.2
|
|
16565
|
+
});
|
|
16426
16566
|
let pourPolygons = boardPolygon;
|
|
16427
16567
|
if (rectObstaclesToSubtract.length > 0) {
|
|
16428
16568
|
const obstacleUnion = rectObstaclesToSubtract.reduce(
|
|
16429
|
-
(acc, p) =>
|
|
16569
|
+
(acc, p) => Flatten4.BooleanOperations.unify(acc, p)
|
|
16430
16570
|
);
|
|
16431
16571
|
if (obstacleUnion && !obstacleUnion.isEmpty()) {
|
|
16432
|
-
pourPolygons =
|
|
16572
|
+
pourPolygons = Flatten4.BooleanOperations.subtract(
|
|
16433
16573
|
boardPolygon,
|
|
16434
16574
|
obstacleUnion
|
|
16435
16575
|
);
|
|
16436
16576
|
}
|
|
16437
16577
|
}
|
|
16438
|
-
|
|
16439
|
-
|
|
16440
|
-
|
|
16441
|
-
|
|
16442
|
-
const islands = p.splitToIslands();
|
|
16443
|
-
for (const island of islands) {
|
|
16444
|
-
if (island.isEmpty()) continue;
|
|
16445
|
-
const faces = [...island.faces];
|
|
16446
|
-
const outer_face_ccw = faces.find(
|
|
16447
|
-
(f) => f.orientation() === Flatten.ORIENTATION.CCW
|
|
16448
|
-
);
|
|
16449
|
-
const inner_faces_cw = faces.filter(
|
|
16450
|
-
(f) => f.orientation() === Flatten.ORIENTATION.CW
|
|
16451
|
-
);
|
|
16452
|
-
if (!outer_face_ccw) continue;
|
|
16453
|
-
if (!db.pcb_copper_pour) {
|
|
16454
|
-
this.renderError(
|
|
16455
|
-
"db.pcb_copper_pour not found. The database schema may be outdated."
|
|
16456
|
-
);
|
|
16457
|
-
return;
|
|
16458
|
-
}
|
|
16459
|
-
const faceToVertices = (face) => face.edges.map((e) => {
|
|
16460
|
-
const pt = {
|
|
16461
|
-
x: e.start.x,
|
|
16462
|
-
y: e.start.y
|
|
16463
|
-
};
|
|
16464
|
-
if (e.isArc) {
|
|
16465
|
-
const bulge = Math.tan(e.shape.sweep / 4);
|
|
16466
|
-
if (Math.abs(bulge) > 1e-9) {
|
|
16467
|
-
pt.bulge = bulge;
|
|
16468
|
-
}
|
|
16469
|
-
}
|
|
16470
|
-
return pt;
|
|
16471
|
-
});
|
|
16472
|
-
outer_face_ccw.reverse();
|
|
16473
|
-
const outer_ring_vertices = faceToVertices(outer_face_ccw);
|
|
16474
|
-
const inner_rings = inner_faces_cw.map((f) => {
|
|
16475
|
-
f.reverse();
|
|
16476
|
-
return { vertices: faceToVertices(f) };
|
|
16477
|
-
});
|
|
16478
|
-
for (const circle of circularObstacles) {
|
|
16479
|
-
const centerPoint = Flatten.point(circle.center.x, circle.center.y);
|
|
16480
|
-
const isContained = island.contains(centerPoint);
|
|
16481
|
-
if (isContained) {
|
|
16482
|
-
inner_rings.push({
|
|
16483
|
-
vertices: [
|
|
16484
|
-
{
|
|
16485
|
-
x: circle.center.x,
|
|
16486
|
-
y: circle.center.y - circle.radius,
|
|
16487
|
-
bulge: 1
|
|
16488
|
-
},
|
|
16489
|
-
{
|
|
16490
|
-
x: circle.center.x,
|
|
16491
|
-
y: circle.center.y + circle.radius,
|
|
16492
|
-
bulge: 1
|
|
16493
|
-
}
|
|
16494
|
-
]
|
|
16495
|
-
});
|
|
16496
|
-
}
|
|
16497
|
-
}
|
|
16498
|
-
db.pcb_copper_pour.insert({
|
|
16499
|
-
shape: "brep",
|
|
16500
|
-
layer: props.layer,
|
|
16501
|
-
brep_shape: {
|
|
16502
|
-
outer_ring: { vertices: outer_ring_vertices },
|
|
16503
|
-
inner_rings
|
|
16504
|
-
},
|
|
16505
|
-
source_net_id: net.source_net_id,
|
|
16506
|
-
subcircuit_id: this.getSubcircuit()?.subcircuit_id ?? void 0
|
|
16507
|
-
});
|
|
16508
|
-
}
|
|
16509
|
-
}
|
|
16578
|
+
generateAndInsertBRep(pourPolygons, circularObstacles, {
|
|
16579
|
+
db,
|
|
16580
|
+
copperPour: this
|
|
16581
|
+
});
|
|
16510
16582
|
});
|
|
16511
16583
|
}
|
|
16512
16584
|
};
|
|
@@ -17749,7 +17821,7 @@ import { identity as identity6 } from "transformation-matrix";
|
|
|
17749
17821
|
var package_default = {
|
|
17750
17822
|
name: "@tscircuit/core",
|
|
17751
17823
|
type: "module",
|
|
17752
|
-
version: "0.0.
|
|
17824
|
+
version: "0.0.842",
|
|
17753
17825
|
types: "dist/index.d.ts",
|
|
17754
17826
|
main: "dist/index.js",
|
|
17755
17827
|
module: "dist/index.js",
|