@tscircuit/core 0.0.522 → 0.0.524

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 CHANGED
@@ -7407,7 +7407,9 @@ declare class NetLabel extends PrimitiveComponent<typeof netLabelProps> {
7407
7407
  anchorSide?: "left" | "right" | "top" | "bottom" | undefined;
7408
7408
  }>;
7409
7409
  };
7410
- doInitialSchematicComponentRender(): void;
7410
+ _getAnchorSide(): "top" | "bottom" | "left" | "right";
7411
+ _getConnectedPorts(): Port[];
7412
+ doInitialSchematicPrimitiveRender(): void;
7411
7413
  _resolveConnectsTo(): string[] | undefined;
7412
7414
  _getNetName(): string;
7413
7415
  doInitialCreateNetsFromProps(): void;
package/dist/index.js CHANGED
@@ -4419,6 +4419,71 @@ function generateApproximatingRects(rotatedRect, numRects = 4) {
4419
4419
  return rects;
4420
4420
  }
4421
4421
 
4422
+ // lib/utils/obstacles/fillPolygonWithRects.ts
4423
+ function fillPolygonWithRects(polygon, options = {}) {
4424
+ if (polygon.length < 3) return [];
4425
+ const { rectHeight = 0.1 } = options;
4426
+ const rects = [];
4427
+ const yCoords = polygon.map((p) => p.y);
4428
+ const minY = Math.min(...yCoords);
4429
+ const maxY = Math.max(...yCoords);
4430
+ for (let y = minY; y < maxY; y += rectHeight) {
4431
+ const scanlineY = y + rectHeight / 2;
4432
+ const intersections = [];
4433
+ for (let i = 0; i < polygon.length; i++) {
4434
+ const p1 = polygon[i];
4435
+ const p2 = polygon[(i + 1) % polygon.length];
4436
+ if (p1.y <= scanlineY && p2.y > scanlineY || p2.y <= scanlineY && p1.y > scanlineY) {
4437
+ const x = (scanlineY - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
4438
+ intersections.push(x);
4439
+ }
4440
+ }
4441
+ intersections.sort((a, b) => a - b);
4442
+ for (let i = 0; i < intersections.length; i += 2) {
4443
+ if (i + 1 < intersections.length) {
4444
+ const x1 = intersections[i];
4445
+ const x2 = intersections[i + 1];
4446
+ const width = x2 - x1;
4447
+ if (width > 1e-6) {
4448
+ rects.push({
4449
+ center: {
4450
+ x: x1 + width / 2,
4451
+ y: scanlineY
4452
+ },
4453
+ width,
4454
+ height: rectHeight
4455
+ });
4456
+ }
4457
+ }
4458
+ }
4459
+ }
4460
+ return rects;
4461
+ }
4462
+
4463
+ // lib/utils/obstacles/fillCircleWithRects.ts
4464
+ function fillCircleWithRects(circle, options = {}) {
4465
+ const { center, radius } = circle;
4466
+ const { rectHeight = 0.1 } = options;
4467
+ const rects = [];
4468
+ const numSlices = Math.ceil(radius * 2 / rectHeight);
4469
+ for (let i = 0; i < numSlices; i++) {
4470
+ const y = center.y - radius + (i + 0.5) * rectHeight;
4471
+ const dy = y - center.y;
4472
+ const halfWidth = Math.sqrt(radius * radius - dy * dy);
4473
+ if (halfWidth > 0) {
4474
+ rects.push({
4475
+ center: {
4476
+ x: center.x,
4477
+ y
4478
+ },
4479
+ width: halfWidth * 2,
4480
+ height: rectHeight
4481
+ });
4482
+ }
4483
+ }
4484
+ return rects;
4485
+ }
4486
+
4422
4487
  // lib/utils/obstacles/getObstaclesFromCircuitJson.ts
4423
4488
  var EVERY_LAYER = ["top", "inner1", "inner2", "bottom"];
4424
4489
  var getObstaclesFromCircuitJson = (soup, connMap) => {
@@ -4499,6 +4564,52 @@ var getObstaclesFromCircuitJson = (soup, connMap) => {
4499
4564
  connectedTo: []
4500
4565
  });
4501
4566
  }
4567
+ } else if (element.type === "pcb_cutout") {
4568
+ if (element.shape === "rect") {
4569
+ obstacles.push({
4570
+ type: "rect",
4571
+ layers: EVERY_LAYER,
4572
+ center: {
4573
+ x: element.center.x,
4574
+ y: element.center.y
4575
+ },
4576
+ width: element.width,
4577
+ height: element.height,
4578
+ connectedTo: []
4579
+ });
4580
+ } else if (element.shape === "circle") {
4581
+ const approximatingRects = fillCircleWithRects(
4582
+ {
4583
+ center: element.center,
4584
+ radius: element.radius
4585
+ },
4586
+ { rectHeight: 0.6 }
4587
+ );
4588
+ for (const rect of approximatingRects) {
4589
+ obstacles.push({
4590
+ type: "rect",
4591
+ layers: EVERY_LAYER,
4592
+ center: rect.center,
4593
+ width: rect.width,
4594
+ height: rect.height,
4595
+ connectedTo: []
4596
+ });
4597
+ }
4598
+ } else if (element.shape === "polygon") {
4599
+ const approximatingRects = fillPolygonWithRects(element.points, {
4600
+ rectHeight: 0.6
4601
+ });
4602
+ for (const rect of approximatingRects) {
4603
+ obstacles.push({
4604
+ type: "rect",
4605
+ layers: EVERY_LAYER,
4606
+ center: rect.center,
4607
+ width: rect.width,
4608
+ height: rect.height,
4609
+ connectedTo: []
4610
+ });
4611
+ }
4612
+ }
4502
4613
  } else if (element.type === "pcb_hole") {
4503
4614
  if (element.hole_shape === "oval") {
4504
4615
  obstacles.push({
@@ -9297,18 +9408,50 @@ var NetLabel = class extends PrimitiveComponent2 {
9297
9408
  zodProps: netLabelProps
9298
9409
  };
9299
9410
  }
9300
- doInitialSchematicComponentRender() {
9411
+ _getAnchorSide() {
9412
+ const { _parsedProps: props } = this;
9413
+ if (props.anchorSide) return props.anchorSide;
9414
+ const connectsTo = this._resolveConnectsTo();
9415
+ if (!connectsTo) return "right";
9416
+ const anchorPos = this._getGlobalSchematicPositionBeforeLayout();
9417
+ const connectedPorts = this._getConnectedPorts();
9418
+ if (connectedPorts.length === 0) return "right";
9419
+ const connectedPortPosition = connectedPorts[0]._getGlobalSchematicPositionBeforeLayout();
9420
+ const dx = connectedPortPosition.x - anchorPos.x;
9421
+ const dy = connectedPortPosition.y - anchorPos.y;
9422
+ if (Math.abs(dx) > Math.abs(dy)) {
9423
+ if (dx > 0) return "right";
9424
+ if (dx < 0) return "left";
9425
+ } else {
9426
+ if (dy > 0) return "top";
9427
+ if (dy < 0) return "bottom";
9428
+ }
9429
+ return "right";
9430
+ }
9431
+ _getConnectedPorts() {
9432
+ const connectsTo = this._resolveConnectsTo();
9433
+ if (!connectsTo) return [];
9434
+ const connectedPorts = [];
9435
+ for (const connection of connectsTo) {
9436
+ const port = this.getSubcircuit().selectOne(connection);
9437
+ if (port) {
9438
+ connectedPorts.push(port);
9439
+ }
9440
+ }
9441
+ return connectedPorts;
9442
+ }
9443
+ doInitialSchematicPrimitiveRender() {
9301
9444
  if (this.root?.schematicDisabled) return;
9302
9445
  const { db } = this.root;
9303
9446
  const { _parsedProps: props } = this;
9304
- const anchorPos = { x: props.schX ?? 0, y: props.schY ?? 0 };
9447
+ const anchorPos = this._getGlobalSchematicPositionBeforeLayout();
9305
9448
  const netLabel = db.schematic_net_label.insert({
9306
9449
  text: props.net,
9307
9450
  source_net_id: props.net,
9308
9451
  anchor_position: anchorPos,
9309
9452
  // TODO compute the center based on the text size
9310
9453
  center: anchorPos,
9311
- anchor_side: props.anchorSide ?? "right"
9454
+ anchor_side: this._getAnchorSide()
9312
9455
  });
9313
9456
  this.source_net_label_id = netLabel.source_net_id;
9314
9457
  }
@@ -10452,7 +10595,7 @@ import { identity as identity4 } from "transformation-matrix";
10452
10595
  var package_default = {
10453
10596
  name: "@tscircuit/core",
10454
10597
  type: "module",
10455
- version: "0.0.521",
10598
+ version: "0.0.523",
10456
10599
  types: "dist/index.d.ts",
10457
10600
  main: "dist/index.js",
10458
10601
  module: "dist/index.js",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.522",
4
+ "version": "0.0.524",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",