@tscircuit/core 0.0.79 → 0.0.81
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 +22 -1
- package/dist/index.js +87 -24
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as zod from 'zod';
|
|
2
2
|
import { ZodType, z } from 'zod';
|
|
3
3
|
import { AnySoupElement, PCBTraceError, PCBPlacementError, AnySourceComponent, RouteHintPoint } from '@tscircuit/soup';
|
|
4
|
+
import { LayerRef } from 'circuit-json';
|
|
4
5
|
import { SoupUtilObjects } from '@tscircuit/soup-util';
|
|
5
6
|
import { ReactElement } from 'react';
|
|
6
7
|
import { Matrix } from 'transformation-matrix';
|
|
@@ -22,6 +23,7 @@ declare class Circuit {
|
|
|
22
23
|
*/
|
|
23
24
|
_getBoard(): PrimitiveComponent & {
|
|
24
25
|
boardThickness: number;
|
|
26
|
+
allLayers: LayerRef[];
|
|
25
27
|
};
|
|
26
28
|
_guessRootComponent(): void;
|
|
27
29
|
render(): void;
|
|
@@ -164,6 +166,17 @@ declare abstract class PrimitiveComponent<ZodProps extends ZodType = any> extend
|
|
|
164
166
|
width: number;
|
|
165
167
|
height: number;
|
|
166
168
|
};
|
|
169
|
+
/**
|
|
170
|
+
* Determine if this pcb primitive should be flipped because the primitive
|
|
171
|
+
* container is flipped
|
|
172
|
+
*
|
|
173
|
+
* TODO use footprint.originalLayer instead of assuming everything is defined
|
|
174
|
+
* relative to the top layer
|
|
175
|
+
*/
|
|
176
|
+
_getPcbPrimitiveFlippedHelpers(): {
|
|
177
|
+
isFlipped: boolean;
|
|
178
|
+
maybeFlipLayer: (layer: LayerRef) => LayerRef;
|
|
179
|
+
};
|
|
167
180
|
/**
|
|
168
181
|
* Set the position of this component from the layout solver. This method
|
|
169
182
|
* should operate using CircuitJson associated with this component, like
|
|
@@ -714,6 +727,10 @@ declare class Board extends Group<typeof boardProps> {
|
|
|
714
727
|
}>;
|
|
715
728
|
};
|
|
716
729
|
get boardThickness(): number;
|
|
730
|
+
/**
|
|
731
|
+
* Get all available layers for the board
|
|
732
|
+
*/
|
|
733
|
+
get allLayers(): string[];
|
|
717
734
|
doInitialPcbComponentRender(): void;
|
|
718
735
|
removePcbComponentRender(): void;
|
|
719
736
|
_computePcbGlobalTransformBeforeLayout(): Matrix;
|
|
@@ -808,7 +825,6 @@ declare class SmtPad extends PrimitiveComponent<typeof smtPadProps> {
|
|
|
808
825
|
height: number;
|
|
809
826
|
};
|
|
810
827
|
doInitialPortMatching(): void;
|
|
811
|
-
getAvailablePcbLayers(): string[];
|
|
812
828
|
doInitialPcbPrimitiveRender(): void;
|
|
813
829
|
doInitialPcbPortAttachment(): void;
|
|
814
830
|
_getPcbCircuitJsonBounds(): {
|
|
@@ -4082,7 +4098,12 @@ declare class Hole extends PrimitiveComponent<typeof holeProps> {
|
|
|
4082
4098
|
}
|
|
4083
4099
|
|
|
4084
4100
|
declare class SilkscreenText extends PrimitiveComponent<typeof silkscreenTextProps> {
|
|
4101
|
+
isPcbPrimitive: boolean;
|
|
4085
4102
|
doInitialPcbPrimitiveRender(): void;
|
|
4103
|
+
getPcbSize(): {
|
|
4104
|
+
width: number;
|
|
4105
|
+
height: number;
|
|
4106
|
+
};
|
|
4086
4107
|
}
|
|
4087
4108
|
|
|
4088
4109
|
declare class Keepout extends PrimitiveComponent<typeof pcbKeepoutProps> {
|
package/dist/index.js
CHANGED
|
@@ -135,6 +135,7 @@ var Renderable = class {
|
|
|
135
135
|
import {
|
|
136
136
|
applyToPoint,
|
|
137
137
|
compose,
|
|
138
|
+
flipY,
|
|
138
139
|
identity,
|
|
139
140
|
rotate,
|
|
140
141
|
translate
|
|
@@ -270,6 +271,25 @@ var PrimitiveComponent = class extends Renderable {
|
|
|
270
271
|
)
|
|
271
272
|
);
|
|
272
273
|
}
|
|
274
|
+
if (this.isPcbPrimitive) {
|
|
275
|
+
const primitiveContainer = this.getPrimitiveContainer();
|
|
276
|
+
if (primitiveContainer) {
|
|
277
|
+
const isFlipped = primitiveContainer._parsedProps.layer === "bottom";
|
|
278
|
+
const containerCenter = primitiveContainer._getGlobalPcbPositionBeforeLayout();
|
|
279
|
+
if (isFlipped) {
|
|
280
|
+
const flipOperation = compose(
|
|
281
|
+
translate(containerCenter.x, containerCenter.y),
|
|
282
|
+
flipY(),
|
|
283
|
+
translate(-containerCenter.x, -containerCenter.y)
|
|
284
|
+
);
|
|
285
|
+
return compose(
|
|
286
|
+
this.parent?._computePcbGlobalTransformBeforeLayout() ?? identity(),
|
|
287
|
+
flipY(),
|
|
288
|
+
this.computePcbPropsTransform()
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
273
293
|
return compose(
|
|
274
294
|
this.parent?._computePcbGlobalTransformBeforeLayout() ?? identity(),
|
|
275
295
|
this.computePcbPropsTransform()
|
|
@@ -291,6 +311,24 @@ var PrimitiveComponent = class extends Renderable {
|
|
|
291
311
|
height: 0
|
|
292
312
|
};
|
|
293
313
|
}
|
|
314
|
+
/**
|
|
315
|
+
* Determine if this pcb primitive should be flipped because the primitive
|
|
316
|
+
* container is flipped
|
|
317
|
+
*
|
|
318
|
+
* TODO use footprint.originalLayer instead of assuming everything is defined
|
|
319
|
+
* relative to the top layer
|
|
320
|
+
*/
|
|
321
|
+
_getPcbPrimitiveFlippedHelpers() {
|
|
322
|
+
const container = this.getPrimitiveContainer();
|
|
323
|
+
const isFlipped = !container ? false : container._parsedProps.layer === "bottom";
|
|
324
|
+
const maybeFlipLayer = (layer) => {
|
|
325
|
+
if (isFlipped) {
|
|
326
|
+
return layer === "top" ? "bottom" : "top";
|
|
327
|
+
}
|
|
328
|
+
return layer;
|
|
329
|
+
};
|
|
330
|
+
return { isFlipped, maybeFlipLayer };
|
|
331
|
+
}
|
|
294
332
|
/**
|
|
295
333
|
* Set the position of this component from the layout solver. This method
|
|
296
334
|
* should operate using CircuitJson associated with this component, like
|
|
@@ -474,9 +512,16 @@ var PrimitiveComponent = class extends Renderable {
|
|
|
474
512
|
}
|
|
475
513
|
getAvailablePcbLayers() {
|
|
476
514
|
if (this.isPcbPrimitive) {
|
|
477
|
-
|
|
515
|
+
const { maybeFlipLayer } = this._getPcbPrimitiveFlippedHelpers();
|
|
516
|
+
if ("layer" in this._parsedProps) {
|
|
517
|
+
const layer = maybeFlipLayer(this._parsedProps.layer ?? "top");
|
|
518
|
+
return [layer];
|
|
519
|
+
}
|
|
520
|
+
if ("layers" in this._parsedProps) {
|
|
521
|
+
return this._parsedProps.layers;
|
|
522
|
+
}
|
|
478
523
|
if (this.componentName === "PlatedHole") {
|
|
479
|
-
return ["top", "bottom"];
|
|
524
|
+
return this.root?._getBoard()?.allLayers ?? ["top", "bottom"];
|
|
480
525
|
}
|
|
481
526
|
return [];
|
|
482
527
|
}
|
|
@@ -1097,7 +1142,9 @@ function getPortFromHints(hints) {
|
|
|
1097
1142
|
|
|
1098
1143
|
// lib/components/primitive-components/SmtPad.ts
|
|
1099
1144
|
import { smtPadProps } from "@tscircuit/props";
|
|
1100
|
-
import {
|
|
1145
|
+
import {
|
|
1146
|
+
decomposeTSR
|
|
1147
|
+
} from "transformation-matrix";
|
|
1101
1148
|
var SmtPad = class extends PrimitiveComponent {
|
|
1102
1149
|
pcb_smtpad_id = null;
|
|
1103
1150
|
matchedPort = null;
|
|
@@ -1134,18 +1181,18 @@ var SmtPad = class extends PrimitiveComponent {
|
|
|
1134
1181
|
}
|
|
1135
1182
|
}
|
|
1136
1183
|
}
|
|
1137
|
-
getAvailablePcbLayers() {
|
|
1138
|
-
return this.props.layer ? [this.props.layer] : [];
|
|
1139
|
-
}
|
|
1140
1184
|
doInitialPcbPrimitiveRender() {
|
|
1141
1185
|
const { db } = this.root;
|
|
1142
1186
|
const { _parsedProps: props } = this;
|
|
1143
1187
|
if (!props.portHints) return;
|
|
1188
|
+
const container = this.getPrimitiveContainer();
|
|
1144
1189
|
const position = this._getGlobalPcbPositionBeforeLayout();
|
|
1190
|
+
const containerCenter = container?._getGlobalPcbPositionBeforeLayout();
|
|
1145
1191
|
const decomposedMat = decomposeTSR(
|
|
1146
1192
|
this._computePcbGlobalTransformBeforeLayout()
|
|
1147
1193
|
);
|
|
1148
1194
|
const isRotated90 = Math.abs(decomposedMat.rotation.angle * (180 / Math.PI) - 90) < 0.01;
|
|
1195
|
+
const { maybeFlipLayer } = this._getPcbPrimitiveFlippedHelpers();
|
|
1149
1196
|
let pcb_smtpad = null;
|
|
1150
1197
|
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id;
|
|
1151
1198
|
if (props.shape === "circle") {
|
|
@@ -1153,7 +1200,7 @@ var SmtPad = class extends PrimitiveComponent {
|
|
|
1153
1200
|
pcb_component_id,
|
|
1154
1201
|
pcb_port_id: this.matchedPort?.pcb_port_id,
|
|
1155
1202
|
// port likely isn't matched
|
|
1156
|
-
layer: props.layer ?? "top",
|
|
1203
|
+
layer: maybeFlipLayer(props.layer ?? "top"),
|
|
1157
1204
|
shape: "circle",
|
|
1158
1205
|
// @ts-ignore: no idea why this is triggering
|
|
1159
1206
|
radius: props.radius,
|
|
@@ -1166,7 +1213,7 @@ var SmtPad = class extends PrimitiveComponent {
|
|
|
1166
1213
|
pcb_component_id,
|
|
1167
1214
|
pcb_port_id: this.matchedPort?.pcb_port_id,
|
|
1168
1215
|
// port likely isn't matched
|
|
1169
|
-
layer: props.layer ?? "top",
|
|
1216
|
+
layer: maybeFlipLayer(props.layer ?? "top"),
|
|
1170
1217
|
shape: "rect",
|
|
1171
1218
|
...isRotated90 ? { width: props.height, height: props.width } : { width: props.width, height: props.height },
|
|
1172
1219
|
port_hints: props.portHints.map((ph) => ph.toString()),
|
|
@@ -1229,7 +1276,7 @@ var SmtPad = class extends PrimitiveComponent {
|
|
|
1229
1276
|
|
|
1230
1277
|
// lib/components/primitive-components/SilkscreenPath.ts
|
|
1231
1278
|
import { silkscreenPathProps } from "@tscircuit/props";
|
|
1232
|
-
import { applyToPoint as
|
|
1279
|
+
import { applyToPoint as applyToPoint4 } from "transformation-matrix";
|
|
1233
1280
|
var SilkscreenPath = class extends PrimitiveComponent {
|
|
1234
1281
|
pcb_silkscreen_path_id = null;
|
|
1235
1282
|
get config() {
|
|
@@ -1251,7 +1298,7 @@ var SilkscreenPath = class extends PrimitiveComponent {
|
|
|
1251
1298
|
pcb_component_id: this.parent?.pcb_component_id,
|
|
1252
1299
|
layer,
|
|
1253
1300
|
route: props.route.map((p) => {
|
|
1254
|
-
const transformedPosition =
|
|
1301
|
+
const transformedPosition = applyToPoint4(transform, {
|
|
1255
1302
|
x: p.x,
|
|
1256
1303
|
y: p.y
|
|
1257
1304
|
});
|
|
@@ -1736,13 +1783,6 @@ var NormalComponent = class extends PrimitiveComponent {
|
|
|
1736
1783
|
if (!footprint) return;
|
|
1737
1784
|
if (typeof footprint === "string") {
|
|
1738
1785
|
const fpSoup = fp.string(footprint).soup();
|
|
1739
|
-
if (this.props.layer) {
|
|
1740
|
-
for (const elm of fpSoup) {
|
|
1741
|
-
if ("layer" in elm) {
|
|
1742
|
-
elm.layer = this.props.layer;
|
|
1743
|
-
}
|
|
1744
|
-
}
|
|
1745
|
-
}
|
|
1746
1786
|
const fpComponents = createComponentsFromSoup(fpSoup);
|
|
1747
1787
|
this.addAll(fpComponents);
|
|
1748
1788
|
}
|
|
@@ -1988,6 +2028,7 @@ var NormalComponent = class extends PrimitiveComponent {
|
|
|
1988
2028
|
const { _parsedProps: props } = this;
|
|
1989
2029
|
if (props.cadModel) {
|
|
1990
2030
|
const bounds = this._getPcbCircuitJsonBounds();
|
|
2031
|
+
const pcb_component = db.pcb_component.get(this.pcb_component_id);
|
|
1991
2032
|
const cadModel = props.cadModel;
|
|
1992
2033
|
if (typeof cadModel === "string") {
|
|
1993
2034
|
throw new Error("String cadModel not yet implemented");
|
|
@@ -1999,6 +2040,11 @@ var NormalComponent = class extends PrimitiveComponent {
|
|
|
1999
2040
|
y: bounds.center.y,
|
|
2000
2041
|
z: this.props.layer === "bottom" ? -boardThickness / 2 : boardThickness / 2
|
|
2001
2042
|
},
|
|
2043
|
+
rotation: {
|
|
2044
|
+
x: 0,
|
|
2045
|
+
y: this.props.layer === "top" ? 0 : 180,
|
|
2046
|
+
z: pcb_component?.rotation ?? 0
|
|
2047
|
+
},
|
|
2002
2048
|
pcb_component_id: this.pcb_component_id,
|
|
2003
2049
|
source_component_id: this.source_component_id,
|
|
2004
2050
|
model_stl_url: "stlUrl" in cadModel ? cadModel.stlUrl : void 0,
|
|
@@ -2023,7 +2069,7 @@ import "zod";
|
|
|
2023
2069
|
|
|
2024
2070
|
// lib/components/primitive-components/TraceHint.ts
|
|
2025
2071
|
import "@tscircuit/props";
|
|
2026
|
-
import { applyToPoint as
|
|
2072
|
+
import { applyToPoint as applyToPoint5 } from "transformation-matrix";
|
|
2027
2073
|
var TraceHint = class extends PrimitiveComponent {
|
|
2028
2074
|
matchedPort = null;
|
|
2029
2075
|
doInitialPortMatching() {
|
|
@@ -2057,7 +2103,7 @@ var TraceHint = class extends PrimitiveComponent {
|
|
|
2057
2103
|
const globalTransform = this._computePcbGlobalTransformBeforeLayout();
|
|
2058
2104
|
return offsets.map(
|
|
2059
2105
|
(offset) => ({
|
|
2060
|
-
...
|
|
2106
|
+
...applyToPoint5(globalTransform, offset),
|
|
2061
2107
|
via: offset.via,
|
|
2062
2108
|
to_layer: offset.to_layer,
|
|
2063
2109
|
trace_width: offset.trace_width
|
|
@@ -2115,6 +2161,12 @@ var Board = class extends Group {
|
|
|
2115
2161
|
const { _parsedProps: props } = this;
|
|
2116
2162
|
return 1.4;
|
|
2117
2163
|
}
|
|
2164
|
+
/**
|
|
2165
|
+
* Get all available layers for the board
|
|
2166
|
+
*/
|
|
2167
|
+
get allLayers() {
|
|
2168
|
+
return ["top", "bottom", "inner1", "inner2"];
|
|
2169
|
+
}
|
|
2118
2170
|
doInitialPcbComponentRender() {
|
|
2119
2171
|
const { db } = this.root;
|
|
2120
2172
|
const { _parsedProps: props } = this;
|
|
@@ -3445,23 +3497,34 @@ var Hole = class extends PrimitiveComponent {
|
|
|
3445
3497
|
// lib/components/primitive-components/SilkscreenText.ts
|
|
3446
3498
|
import "@tscircuit/props";
|
|
3447
3499
|
var SilkscreenText = class extends PrimitiveComponent {
|
|
3500
|
+
isPcbPrimitive = true;
|
|
3448
3501
|
doInitialPcbPrimitiveRender() {
|
|
3449
3502
|
const { db } = this.root;
|
|
3450
3503
|
const { _parsedProps: props } = this;
|
|
3451
3504
|
const container = this.getPrimitiveContainer();
|
|
3505
|
+
const position = this._getGlobalPcbPositionBeforeLayout();
|
|
3506
|
+
const { maybeFlipLayer } = this._getPcbPrimitiveFlippedHelpers();
|
|
3452
3507
|
db.pcb_silkscreen_text.insert({
|
|
3453
3508
|
anchor_alignment: props.anchorAlignment,
|
|
3454
3509
|
anchor_position: {
|
|
3455
|
-
x:
|
|
3456
|
-
y:
|
|
3510
|
+
x: position.x,
|
|
3511
|
+
y: position.y
|
|
3457
3512
|
},
|
|
3458
3513
|
font: props.font ?? "tscircuit2024",
|
|
3459
3514
|
font_size: props.fontSize ?? 1,
|
|
3460
|
-
layer: "top",
|
|
3515
|
+
layer: maybeFlipLayer(props.layer ?? "top"),
|
|
3461
3516
|
text: props.text ?? "",
|
|
3462
3517
|
pcb_component_id: container.pcb_component_id
|
|
3463
3518
|
});
|
|
3464
3519
|
}
|
|
3520
|
+
getPcbSize() {
|
|
3521
|
+
const { _parsedProps: props } = this;
|
|
3522
|
+
const fontSize = props.fontSize ?? 1;
|
|
3523
|
+
const text = props.text ?? "";
|
|
3524
|
+
const textWidth = text.length * fontSize;
|
|
3525
|
+
const textHeight = fontSize;
|
|
3526
|
+
return { width: textWidth * fontSize, height: textHeight * fontSize };
|
|
3527
|
+
}
|
|
3465
3528
|
};
|
|
3466
3529
|
|
|
3467
3530
|
// lib/components/primitive-components/FabricationNoteText.ts
|
|
@@ -3489,7 +3552,7 @@ var FabricationNoteText = class extends PrimitiveComponent {
|
|
|
3489
3552
|
|
|
3490
3553
|
// lib/components/primitive-components/FabricationNotePath.ts
|
|
3491
3554
|
import { fabricationNotePathProps } from "@tscircuit/props";
|
|
3492
|
-
import { applyToPoint as
|
|
3555
|
+
import { applyToPoint as applyToPoint6 } from "transformation-matrix";
|
|
3493
3556
|
var FabricationNotePath = class extends PrimitiveComponent {
|
|
3494
3557
|
fabrication_note_path_id = null;
|
|
3495
3558
|
get config() {
|
|
@@ -3512,7 +3575,7 @@ var FabricationNotePath = class extends PrimitiveComponent {
|
|
|
3512
3575
|
layer,
|
|
3513
3576
|
color: props.color,
|
|
3514
3577
|
route: props.route.map((p) => {
|
|
3515
|
-
const transformedPosition =
|
|
3578
|
+
const transformedPosition = applyToPoint6(transform, {
|
|
3516
3579
|
x: p.x,
|
|
3517
3580
|
y: p.y
|
|
3518
3581
|
});
|