@tscircuit/pcb-viewer 1.7.0 → 1.8.0

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.js CHANGED
@@ -9818,6 +9818,7 @@ var require_dist = __commonJS({
9818
9818
  schematic_component_id: import_zod23.z.string(),
9819
9819
  pin_spacing: length.optional(),
9820
9820
  box_width: length.optional(),
9821
+ symbol_name: import_zod23.z.string().optional(),
9821
9822
  port_arrangement: import_zod23.z.union([
9822
9823
  import_zod23.z.object({
9823
9824
  left_size: import_zod23.z.number(),
@@ -10094,6 +10095,11 @@ var require_dist = __commonJS({
10094
10095
  source_trace_id: import_zod39.z.string().optional(),
10095
10096
  pcb_component_id: import_zod39.z.string().optional(),
10096
10097
  pcb_trace_id: import_zod39.z.string(),
10098
+ route_thickness_mode: import_zod39.z.enum([
10099
+ "constant",
10100
+ "interpolated"
10101
+ ]).default("interpolated"),
10102
+ should_round_corners: import_zod39.z.boolean().optional(),
10097
10103
  route: import_zod39.z.array(import_zod39.z.union([
10098
10104
  import_zod39.z.object({
10099
10105
  route_type: import_zod39.z.literal("wire"),
@@ -10147,9 +10153,11 @@ var require_dist = __commonJS({
10147
10153
  var import_zod43 = require_lib2();
10148
10154
  var pcb_board = import_zod43.z.object({
10149
10155
  type: import_zod43.z.literal("pcb_board"),
10156
+ pcb_board_id: import_zod43.z.string().default("pcb_board_0"),
10150
10157
  width: length,
10151
10158
  height: length,
10152
- center: point
10159
+ center: point,
10160
+ outline: import_zod43.z.array(point).optional()
10153
10161
  }).describe("Defines the board outline of the PCB");
10154
10162
  var import_zod44 = require_lib2();
10155
10163
  var pcb_placement_error = import_zod44.z.object({
@@ -11786,6 +11794,12 @@ var drawPill = function(drawer, pill) {
11786
11794
  });
11787
11795
  drawer.pill(pill.x, pill.y, pill.w, pill.h);
11788
11796
  };
11797
+ var drawPolygon = function(drawer, polygon) {
11798
+ drawer.equip({
11799
+ color: polygon.layer
11800
+ });
11801
+ drawer.polygon(polygon.points);
11802
+ };
11789
11803
  var drawPrimitive = function(drawer, primitive) {
11790
11804
  switch(primitive.pcb_drawing_type){
11791
11805
  case "line":
@@ -11800,6 +11814,8 @@ var drawPrimitive = function(drawer, primitive) {
11800
11814
  return drawOval(drawer, primitive);
11801
11815
  case "pill":
11802
11816
  return drawPill(drawer, primitive);
11817
+ case "polygon":
11818
+ return drawPolygon(drawer, primitive);
11803
11819
  }
11804
11820
  };
11805
11821
  var drawPrimitives = function(drawer, primitives) {
@@ -12225,6 +12241,34 @@ var Drawer = /*#__PURE__*/ function() {
12225
12241
  ctx.closePath();
12226
12242
  }
12227
12243
  },
12244
+ {
12245
+ key: "polygon",
12246
+ value: function polygon(points) {
12247
+ var _this = this;
12248
+ if (points.length < 3) {
12249
+ console.warn("Polygon must have at least 3 points");
12250
+ return;
12251
+ }
12252
+ this.applyAperture();
12253
+ var ctx = this.getLayerCtx();
12254
+ var transformedPoints = points.map(function(point) {
12255
+ return (0, import_transformation_matrix.applyToPoint)(_this.transform, [
12256
+ point.x,
12257
+ point.y
12258
+ ]);
12259
+ });
12260
+ ctx.beginPath();
12261
+ ctx.moveTo(transformedPoints[0][0], transformedPoints[0][1]);
12262
+ for(var i = 1; i < transformedPoints.length; i++){
12263
+ ctx.lineTo(transformedPoints[i][0], transformedPoints[i][1]);
12264
+ }
12265
+ ctx.closePath();
12266
+ ctx.fill();
12267
+ var lineWidth = scaleOnly(this.transform, this.aperture.size);
12268
+ ctx.lineWidth = lineWidth;
12269
+ ctx.stroke();
12270
+ }
12271
+ },
12228
12272
  {
12229
12273
  /* NOTE: This is not gerber compatible */ key: "debugText",
12230
12274
  value: function debugText(text, x, y) {
@@ -12488,6 +12532,85 @@ var CanvasPrimitiveRenderer = function(param) {
12488
12532
  var import_react14 = require("react");
12489
12533
  // src/lib/convert-element-to-primitive.ts
12490
12534
  var import_soup_util = __toESM(require_dist2());
12535
+ // src/lib/util/expand-stroke.ts
12536
+ function getExpandedStroke(strokeInput, defaultWidth) {
12537
+ if (strokeInput.length < 2) {
12538
+ throw new Error("Stroke must have at least two points");
12539
+ }
12540
+ var stroke = strokeInput.map(function(point) {
12541
+ if (Array.isArray(point)) {
12542
+ return {
12543
+ x: point[0],
12544
+ y: point[1]
12545
+ };
12546
+ }
12547
+ return point;
12548
+ });
12549
+ var leftSide = [];
12550
+ var rightSide = [];
12551
+ function getNormal(p1, p2) {
12552
+ var dx = p2.x - p1.x;
12553
+ var dy = p2.y - p1.y;
12554
+ var length = Math.sqrt(dx * dx + dy * dy);
12555
+ return {
12556
+ x: -dy / length,
12557
+ y: dx / length
12558
+ };
12559
+ }
12560
+ function addPoint(point, normal, factor, width) {
12561
+ var halfWidth = width / 2;
12562
+ var newPoint = {
12563
+ x: point.x + normal.x * halfWidth * factor,
12564
+ y: point.y + normal.y * halfWidth * factor
12565
+ };
12566
+ if (factor > 0) {
12567
+ leftSide.push(newPoint);
12568
+ } else {
12569
+ rightSide.unshift(newPoint);
12570
+ }
12571
+ }
12572
+ var firstNormal = getNormal(stroke[0], stroke[1]);
12573
+ var _stroke__trace_width;
12574
+ var firstWidth = (_stroke__trace_width = stroke[0].trace_width) !== null && _stroke__trace_width !== void 0 ? _stroke__trace_width : defaultWidth;
12575
+ addPoint(stroke[0], firstNormal, 1, firstWidth);
12576
+ addPoint(stroke[0], firstNormal, -1, firstWidth);
12577
+ for(var i = 1; i < stroke.length - 1; i++){
12578
+ var prev = stroke[i - 1];
12579
+ var current = stroke[i];
12580
+ var next = stroke[i + 1];
12581
+ var normalPrev = getNormal(prev, current);
12582
+ var normalNext = getNormal(current, next);
12583
+ var miterX = normalPrev.x + normalNext.x;
12584
+ var miterY = normalPrev.y + normalNext.y;
12585
+ var miterLength = Math.sqrt(miterX * miterX + miterY * miterY);
12586
+ var _current_trace_width;
12587
+ var currentWidth = (_current_trace_width = current.trace_width) !== null && _current_trace_width !== void 0 ? _current_trace_width : defaultWidth;
12588
+ var miterLimit = 2;
12589
+ if (miterLength / 2 > miterLimit * (currentWidth / 2)) {
12590
+ addPoint(current, normalPrev, 1, currentWidth);
12591
+ addPoint(current, normalNext, 1, currentWidth);
12592
+ addPoint(current, normalPrev, -1, currentWidth);
12593
+ addPoint(current, normalNext, -1, currentWidth);
12594
+ } else {
12595
+ var scale2 = 1 / miterLength;
12596
+ addPoint(current, {
12597
+ x: miterX * scale2,
12598
+ y: miterY * scale2
12599
+ }, 1, currentWidth);
12600
+ addPoint(current, {
12601
+ x: miterX * scale2,
12602
+ y: miterY * scale2
12603
+ }, -1, currentWidth);
12604
+ }
12605
+ }
12606
+ var lastNormal = getNormal(stroke[stroke.length - 2], stroke[stroke.length - 1]);
12607
+ var _stroke__trace_width1;
12608
+ var lastWidth = (_stroke__trace_width1 = stroke[stroke.length - 1].trace_width) !== null && _stroke__trace_width1 !== void 0 ? _stroke__trace_width1 : defaultWidth;
12609
+ addPoint(stroke[stroke.length - 1], lastNormal, 1, lastWidth);
12610
+ addPoint(stroke[stroke.length - 1], lastNormal, -1, lastWidth);
12611
+ return _to_consumable_array(leftSide).concat(_to_consumable_array(rightSide));
12612
+ }
12613
+ // src/lib/convert-element-to-primitive.ts
12491
12614
  var convertElementToPrimitives = function(element, allElements) {
12492
12615
  var _pcb_port_get;
12493
12616
  var _parent_pcb_component = "pcb_component_id" in element ? allElements.find(function(elm) {
@@ -12693,42 +12816,70 @@ var convertElementToPrimitives = function(element, allElements) {
12693
12816
  case "pcb_trace":
12694
12817
  {
12695
12818
  var primitives = [];
12696
- var prevX = null;
12697
- var prevY = null;
12698
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
12699
- try {
12700
- for(var _iterator = element.route[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
12701
- var route = _step.value;
12702
- if (route.route_type === "wire") {
12703
- if (prevX !== null && prevY !== null) {
12704
- primitives.push({
12705
- pcb_drawing_type: "line",
12706
- x1: prevX,
12707
- y1: prevY,
12708
- x2: route.x,
12709
- y2: route.y,
12710
- width: route.width,
12711
- squareCap: false,
12712
- layer: route.layer
12713
- });
12714
- }
12715
- prevX = route.x;
12716
- prevY = route.y;
12717
- }
12718
- }
12719
- } catch (err) {
12720
- _didIteratorError = true;
12721
- _iteratorError = err;
12722
- } finally{
12819
+ if (element.route_thickness_mode === "constant") {
12820
+ var prevX = null;
12821
+ var prevY = null;
12822
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
12723
12823
  try {
12724
- if (!_iteratorNormalCompletion && _iterator.return != null) {
12725
- _iterator.return();
12824
+ for(var _iterator = element.route[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
12825
+ var route = _step.value;
12826
+ if (route.route_type === "wire") {
12827
+ if (prevX !== null && prevY !== null) {
12828
+ primitives.push({
12829
+ pcb_drawing_type: "line",
12830
+ x1: prevX,
12831
+ y1: prevY,
12832
+ x2: route.x,
12833
+ y2: route.y,
12834
+ width: route.width,
12835
+ squareCap: false,
12836
+ layer: route.layer
12837
+ });
12838
+ }
12839
+ prevX = route.x;
12840
+ prevY = route.y;
12841
+ }
12726
12842
  }
12843
+ } catch (err) {
12844
+ _didIteratorError = true;
12845
+ _iteratorError = err;
12727
12846
  } finally{
12728
- if (_didIteratorError) {
12729
- throw _iteratorError;
12847
+ try {
12848
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
12849
+ _iterator.return();
12850
+ }
12851
+ } finally{
12852
+ if (_didIteratorError) {
12853
+ throw _iteratorError;
12854
+ }
12730
12855
  }
12731
12856
  }
12857
+ } else if (element.route_thickness_mode === "interpolated") {
12858
+ var strokeInput = element.route.map(function(r) {
12859
+ return {
12860
+ x: r.x,
12861
+ y: r.y,
12862
+ trace_width: r.route_type === "wire" ? r.width : 0.5
12863
+ };
12864
+ });
12865
+ var expandedStroke = getExpandedStroke(strokeInput, 0.5);
12866
+ primitives.push({
12867
+ pcb_drawing_type: "polygon",
12868
+ points: expandedStroke,
12869
+ layer: element.route[0].layer
12870
+ });
12871
+ element.route.forEach(function(r) {
12872
+ if (r.route_type === "via") {
12873
+ primitives.push({
12874
+ pcb_drawing_type: "circle",
12875
+ x: r.x,
12876
+ y: r.y,
12877
+ radius: r.outer_diameter / 2,
12878
+ fill: true,
12879
+ layer: element.route.layer
12880
+ });
12881
+ }
12882
+ });
12732
12883
  }
12733
12884
  return primitives;
12734
12885
  }
@@ -13390,7 +13541,7 @@ var import_soup2 = __toESM(require_dist());
13390
13541
  // package.json
13391
13542
  var package_default = {
13392
13543
  name: "@tscircuit/pcb-viewer",
13393
- version: "1.6.0",
13544
+ version: "1.7.0",
13394
13545
  main: "dist/index.js",
13395
13546
  repository: "tscircuit/pcb-viewer",
13396
13547
  license: "MIT",
@@ -13417,7 +13568,7 @@ var package_default = {
13417
13568
  "@tscircuit/eagle-xml-converter": "^0.0.6",
13418
13569
  "@tscircuit/props": "^0.0.31",
13419
13570
  "@tscircuit/react-fiber": "^1.1.25",
13420
- "@tscircuit/soup": "^0.0.50",
13571
+ "@tscircuit/soup": "^0.0.56",
13421
13572
  "@tscircuit/soup-util": "^0.0.13",
13422
13573
  "@types/node": "18.7.23",
13423
13574
  "@types/react": "^18.3.3",
@@ -14258,57 +14409,40 @@ var EditTraceHintOverlay = function(param) {
14258
14409
  var route = e.route;
14259
14410
  var pcb_port = (0, import_soup_util2.su)(soup).pcb_port.get(e.pcb_port_id);
14260
14411
  var pcb_port_screen = (0, import_transformation_matrix6.applyToPoint)(transform, pcb_port);
14261
- var strokeInput = [
14262
- {
14263
- x: pcb_port_screen.x,
14264
- y: pcb_port_screen.y,
14265
- trace_width: 0.5
14266
- }
14267
- ].concat(// Start with a small width
14268
- _to_consumable_array(route.map(function(r) {
14269
- if (r === void 0) {
14270
- throw new Error("route contains undefined point");
14271
- }
14272
- return {
14273
- x: (0, import_transformation_matrix6.applyToPoint)(transform, r).x,
14274
- y: (0, import_transformation_matrix6.applyToPoint)(transform, r).y,
14275
- trace_width: r.trace_width
14276
- };
14277
- })));
14278
- var expandedStroke = getExpandedStroke(strokeInput, 0.5);
14279
- var expandedPath = expandedStroke.map(function(point, index) {
14280
- return "".concat(index === 0 ? "M" : "L", " ").concat(point.x, ",").concat(point.y);
14281
- }).join(" ") + " Z";
14282
- var originalPath = strokeInput.map(function(point, index) {
14283
- return "".concat(index === 0 ? "M" : "L", " ").concat(point.x, ",").concat(point.y);
14284
- }).join(" ");
14285
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("g", {
14412
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react13.Fragment, {
14286
14413
  children: [
14287
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", {
14288
- d: expandedPath,
14289
- fill: "red"
14290
- }, "expanded-path-".concat(e.pcb_port_id)),
14291
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", {
14292
- d: originalPath,
14293
- style: {
14294
- mixBlendMode: "difference"
14295
- },
14414
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("rect", {
14415
+ x: pcb_port_screen.x - 10,
14416
+ y: pcb_port_screen.y - 10,
14417
+ width: 20,
14418
+ height: 20,
14296
14419
  stroke: "red"
14297
- }, "original-path-".concat(e.pcb_port_id)),
14298
- strokeInput.map(function(r, i) {
14299
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("g", {
14420
+ }, "rect-".concat(e.pcb_port_id)),
14421
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("path", {
14422
+ stroke: "red",
14423
+ d: "M ".concat(pcb_port_screen.x, " ").concat(pcb_port_screen.y, " ").concat(route.map(function(r) {
14424
+ return (0, import_transformation_matrix6.applyToPoint)(transform, r);
14425
+ }).map(function(r) {
14426
+ return "L ".concat(r.x, " ").concat(r.y);
14427
+ }).join(" "))
14428
+ }, "path-".concat(e.pcb_port_id)),
14429
+ route.map(function(r) {
14430
+ return _object_spread({}, r, (0, import_transformation_matrix6.applyToPoint)(transform, r));
14431
+ }).map(function(r, i) {
14432
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react13.Fragment, {
14300
14433
  children: [
14301
14434
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", {
14302
14435
  cx: r.x,
14303
14436
  cy: r.y,
14304
- r: r.trace_width ? r.trace_width / 2 : 8,
14437
+ r: 8,
14305
14438
  stroke: "red"
14306
14439
  }),
14307
14440
  r.via && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("circle", {
14308
14441
  cx: r.x,
14309
14442
  cy: r.y,
14310
- r: r.trace_width ? r.trace_width / 2 : 8,
14311
- stroke: "red"
14443
+ r: 16,
14444
+ stroke: "red",
14445
+ fill: "transparent"
14312
14446
  })
14313
14447
  ]
14314
14448
  }, i);
@@ -14338,83 +14472,6 @@ var EditTraceHintOverlay = function(param) {
14338
14472
  ]
14339
14473
  });
14340
14474
  };
14341
- function getExpandedStroke(strokeInput, defaultWidth) {
14342
- if (strokeInput.length < 2) {
14343
- throw new Error("Stroke must have at least two points");
14344
- }
14345
- var stroke = strokeInput.map(function(point) {
14346
- if (Array.isArray(point)) {
14347
- return {
14348
- x: point[0],
14349
- y: point[1]
14350
- };
14351
- }
14352
- return point;
14353
- });
14354
- var leftSide = [];
14355
- var rightSide = [];
14356
- function getNormal(p1, p2) {
14357
- var dx = p2.x - p1.x;
14358
- var dy = p2.y - p1.y;
14359
- var length = Math.sqrt(dx * dx + dy * dy);
14360
- return {
14361
- x: -dy / length,
14362
- y: dx / length
14363
- };
14364
- }
14365
- function addPoint(point, normal, factor, width) {
14366
- var halfWidth = width / 2;
14367
- var newPoint = {
14368
- x: point.x + normal.x * halfWidth * factor,
14369
- y: point.y + normal.y * halfWidth * factor
14370
- };
14371
- if (factor > 0) {
14372
- leftSide.push(newPoint);
14373
- } else {
14374
- rightSide.unshift(newPoint);
14375
- }
14376
- }
14377
- var firstNormal = getNormal(stroke[0], stroke[1]);
14378
- var _stroke__trace_width;
14379
- var firstWidth = (_stroke__trace_width = stroke[0].trace_width) !== null && _stroke__trace_width !== void 0 ? _stroke__trace_width : defaultWidth;
14380
- addPoint(stroke[0], firstNormal, 1, firstWidth);
14381
- addPoint(stroke[0], firstNormal, -1, firstWidth);
14382
- for(var i = 1; i < stroke.length - 1; i++){
14383
- var prev = stroke[i - 1];
14384
- var current = stroke[i];
14385
- var next = stroke[i + 1];
14386
- var normalPrev = getNormal(prev, current);
14387
- var normalNext = getNormal(current, next);
14388
- var miterX = normalPrev.x + normalNext.x;
14389
- var miterY = normalPrev.y + normalNext.y;
14390
- var miterLength = Math.sqrt(miterX * miterX + miterY * miterY);
14391
- var _current_trace_width;
14392
- var currentWidth = (_current_trace_width = current.trace_width) !== null && _current_trace_width !== void 0 ? _current_trace_width : defaultWidth;
14393
- var miterLimit = 2;
14394
- if (miterLength / 2 > miterLimit * (currentWidth / 2)) {
14395
- addPoint(current, normalPrev, 1, currentWidth);
14396
- addPoint(current, normalNext, 1, currentWidth);
14397
- addPoint(current, normalPrev, -1, currentWidth);
14398
- addPoint(current, normalNext, -1, currentWidth);
14399
- } else {
14400
- var scale2 = 1 / miterLength;
14401
- addPoint(current, {
14402
- x: miterX * scale2,
14403
- y: miterY * scale2
14404
- }, 1, currentWidth);
14405
- addPoint(current, {
14406
- x: miterX * scale2,
14407
- y: miterY * scale2
14408
- }, -1, currentWidth);
14409
- }
14410
- }
14411
- var lastNormal = getNormal(stroke[stroke.length - 2], stroke[stroke.length - 1]);
14412
- var _stroke__trace_width1;
14413
- var lastWidth = (_stroke__trace_width1 = stroke[stroke.length - 1].trace_width) !== null && _stroke__trace_width1 !== void 0 ? _stroke__trace_width1 : defaultWidth;
14414
- addPoint(stroke[stroke.length - 1], lastNormal, 1, lastWidth);
14415
- addPoint(stroke[stroke.length - 1], lastNormal, -1, lastWidth);
14416
- return _to_consumable_array(leftSide).concat(_to_consumable_array(rightSide));
14417
- }
14418
14475
  // src/components/RatsNestOverlay.tsx
14419
14476
  var import_transformation_matrix7 = require("transformation-matrix");
14420
14477
  var import_soup_util3 = __toESM(require_dist2());