@tscircuit/3d-viewer 0.0.458 → 0.0.460
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 +153 -30
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28509,7 +28509,7 @@ import * as THREE15 from "three";
|
|
|
28509
28509
|
// package.json
|
|
28510
28510
|
var package_default = {
|
|
28511
28511
|
name: "@tscircuit/3d-viewer",
|
|
28512
|
-
version: "0.0.
|
|
28512
|
+
version: "0.0.459",
|
|
28513
28513
|
main: "./dist/index.js",
|
|
28514
28514
|
module: "./dist/index.js",
|
|
28515
28515
|
type: "module",
|
|
@@ -34040,10 +34040,22 @@ function createSoldermaskTextureForLayer({
|
|
|
34040
34040
|
ctx.translate(0, canvasHeight);
|
|
34041
34041
|
ctx.scale(1, -1);
|
|
34042
34042
|
}
|
|
34043
|
-
ctx.fillStyle = soldermaskColor;
|
|
34044
|
-
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
|
|
34045
34043
|
const canvasXFromPcb = (pcbX) => (pcbX - boardData.center.x + boardData.width / 2) * traceTextureResolution;
|
|
34046
34044
|
const canvasYFromPcb = (pcbY) => (-(pcbY - boardData.center.y) + boardData.height / 2) * traceTextureResolution;
|
|
34045
|
+
ctx.fillStyle = soldermaskColor;
|
|
34046
|
+
if (boardData.outline && boardData.outline.length >= 3) {
|
|
34047
|
+
ctx.beginPath();
|
|
34048
|
+
const firstPoint = boardData.outline[0];
|
|
34049
|
+
ctx.moveTo(canvasXFromPcb(firstPoint.x), canvasYFromPcb(firstPoint.y));
|
|
34050
|
+
for (let i = 1; i < boardData.outline.length; i++) {
|
|
34051
|
+
const point2 = boardData.outline[i];
|
|
34052
|
+
ctx.lineTo(canvasXFromPcb(point2.x), canvasYFromPcb(point2.y));
|
|
34053
|
+
}
|
|
34054
|
+
ctx.closePath();
|
|
34055
|
+
ctx.fill();
|
|
34056
|
+
} else {
|
|
34057
|
+
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
|
|
34058
|
+
}
|
|
34047
34059
|
ctx.globalCompositeOperation = "destination-out";
|
|
34048
34060
|
ctx.fillStyle = "black";
|
|
34049
34061
|
const pcbSmtPads = su13(circuitJson).pcb_smtpad.list();
|
|
@@ -34065,6 +34077,12 @@ function createSoldermaskTextureForLayer({
|
|
|
34065
34077
|
return;
|
|
34066
34078
|
}
|
|
34067
34079
|
if (pad2.x === void 0 || pad2.y === void 0) return;
|
|
34080
|
+
if (Number.isNaN(pad2.x) || Number.isNaN(pad2.y)) {
|
|
34081
|
+
console.warn(
|
|
34082
|
+
`[soldermask-texture] Skipping pad ${pad2.pcb_smtpad_id} with NaN coordinates`
|
|
34083
|
+
);
|
|
34084
|
+
return;
|
|
34085
|
+
}
|
|
34068
34086
|
const x = pad2.x;
|
|
34069
34087
|
const y = pad2.y;
|
|
34070
34088
|
const canvasX = canvasXFromPcb(x);
|
|
@@ -34072,25 +34090,67 @@ function createSoldermaskTextureForLayer({
|
|
|
34072
34090
|
if (pad2.shape === "rect") {
|
|
34073
34091
|
const width10 = pad2.width * traceTextureResolution;
|
|
34074
34092
|
const height10 = pad2.height * traceTextureResolution;
|
|
34075
|
-
|
|
34093
|
+
const rawRadius = extractRectBorderRadius(pad2);
|
|
34094
|
+
const borderRadius = clampRectBorderRadius(
|
|
34095
|
+
pad2.width,
|
|
34096
|
+
pad2.height,
|
|
34097
|
+
rawRadius
|
|
34098
|
+
) * traceTextureResolution;
|
|
34099
|
+
if (borderRadius > 0) {
|
|
34100
|
+
ctx.beginPath();
|
|
34101
|
+
ctx.roundRect(
|
|
34102
|
+
canvasX - width10 / 2,
|
|
34103
|
+
canvasY - height10 / 2,
|
|
34104
|
+
width10,
|
|
34105
|
+
height10,
|
|
34106
|
+
borderRadius
|
|
34107
|
+
);
|
|
34108
|
+
ctx.fill();
|
|
34109
|
+
} else {
|
|
34110
|
+
ctx.fillRect(canvasX - width10 / 2, canvasY - height10 / 2, width10, height10);
|
|
34111
|
+
}
|
|
34076
34112
|
} else if (pad2.shape === "circle") {
|
|
34077
34113
|
const radius = (pad2.radius ?? pad2.width / 2) * traceTextureResolution;
|
|
34078
34114
|
ctx.beginPath();
|
|
34079
34115
|
ctx.arc(canvasX, canvasY, radius, 0, 2 * Math.PI);
|
|
34080
34116
|
ctx.fill();
|
|
34081
|
-
} else if (pad2.shape === "pill"
|
|
34117
|
+
} else if (pad2.shape === "pill") {
|
|
34082
34118
|
const width10 = pad2.width * traceTextureResolution;
|
|
34083
34119
|
const height10 = pad2.height * traceTextureResolution;
|
|
34084
|
-
const
|
|
34120
|
+
const rawRadius = extractRectBorderRadius(pad2);
|
|
34121
|
+
const borderRadius = clampRectBorderRadius(
|
|
34122
|
+
pad2.width,
|
|
34123
|
+
pad2.height,
|
|
34124
|
+
rawRadius
|
|
34125
|
+
) * traceTextureResolution;
|
|
34085
34126
|
ctx.beginPath();
|
|
34086
34127
|
ctx.roundRect(
|
|
34087
34128
|
canvasX - width10 / 2,
|
|
34088
34129
|
canvasY - height10 / 2,
|
|
34089
34130
|
width10,
|
|
34090
34131
|
height10,
|
|
34091
|
-
|
|
34132
|
+
borderRadius
|
|
34092
34133
|
);
|
|
34093
34134
|
ctx.fill();
|
|
34135
|
+
} else if (pad2.shape === "rotated_rect") {
|
|
34136
|
+
const width10 = pad2.width * traceTextureResolution;
|
|
34137
|
+
const height10 = pad2.height * traceTextureResolution;
|
|
34138
|
+
const rawRadius = extractRectBorderRadius(pad2);
|
|
34139
|
+
const borderRadius = clampRectBorderRadius(
|
|
34140
|
+
pad2.width,
|
|
34141
|
+
pad2.height,
|
|
34142
|
+
rawRadius
|
|
34143
|
+
) * traceTextureResolution;
|
|
34144
|
+
const ccwRotation = pad2.ccw_rotation || 0;
|
|
34145
|
+
const rotationRadians = ccwRotation * (Math.PI / 180);
|
|
34146
|
+
const rotation2 = layer === "bottom" ? -rotationRadians : rotationRadians;
|
|
34147
|
+
ctx.save();
|
|
34148
|
+
ctx.translate(canvasX, canvasY);
|
|
34149
|
+
ctx.rotate(rotation2);
|
|
34150
|
+
ctx.beginPath();
|
|
34151
|
+
ctx.roundRect(-width10 / 2, -height10 / 2, width10, height10, borderRadius);
|
|
34152
|
+
ctx.fill();
|
|
34153
|
+
ctx.restore();
|
|
34094
34154
|
}
|
|
34095
34155
|
});
|
|
34096
34156
|
const pcbVias = su13(circuitJson).pcb_via.list();
|
|
@@ -34234,6 +34294,71 @@ function createSoldermaskTextureForLayer({
|
|
|
34234
34294
|
ctx.arc(adjustedCanvasX, adjustedCanvasY, canvasRadius, 0, 2 * Math.PI);
|
|
34235
34295
|
ctx.fill();
|
|
34236
34296
|
}
|
|
34297
|
+
} else if (hole.shape === "circular_hole_with_rect_pad") {
|
|
34298
|
+
const padWidth = (hole.rect_pad_width ?? hole.hole_diameter ?? 0) * traceTextureResolution;
|
|
34299
|
+
const padHeight = (hole.rect_pad_height ?? hole.hole_diameter ?? 0) * traceTextureResolution;
|
|
34300
|
+
const rawRadius = extractRectBorderRadius(hole);
|
|
34301
|
+
const borderRadius = clampRectBorderRadius(
|
|
34302
|
+
hole.rect_pad_width ?? hole.hole_diameter ?? 0,
|
|
34303
|
+
hole.rect_pad_height ?? hole.hole_diameter ?? 0,
|
|
34304
|
+
rawRadius
|
|
34305
|
+
) * traceTextureResolution;
|
|
34306
|
+
if (borderRadius > 0) {
|
|
34307
|
+
ctx.beginPath();
|
|
34308
|
+
ctx.roundRect(
|
|
34309
|
+
canvasX - padWidth / 2,
|
|
34310
|
+
canvasY - padHeight / 2,
|
|
34311
|
+
padWidth,
|
|
34312
|
+
padHeight,
|
|
34313
|
+
borderRadius
|
|
34314
|
+
);
|
|
34315
|
+
ctx.fill();
|
|
34316
|
+
} else {
|
|
34317
|
+
ctx.fillRect(
|
|
34318
|
+
canvasX - padWidth / 2,
|
|
34319
|
+
canvasY - padHeight / 2,
|
|
34320
|
+
padWidth,
|
|
34321
|
+
padHeight
|
|
34322
|
+
);
|
|
34323
|
+
}
|
|
34324
|
+
} else if (hole.shape === "pill_hole_with_rect_pad") {
|
|
34325
|
+
const padWidth = (hole.rect_pad_width ?? hole.hole_width ?? 0) * traceTextureResolution;
|
|
34326
|
+
const padHeight = (hole.rect_pad_height ?? hole.hole_height ?? 0) * traceTextureResolution;
|
|
34327
|
+
const rawRadius = extractRectBorderRadius(hole);
|
|
34328
|
+
const borderRadius = clampRectBorderRadius(
|
|
34329
|
+
hole.rect_pad_width ?? hole.hole_width ?? 0,
|
|
34330
|
+
hole.rect_pad_height ?? hole.hole_height ?? 0,
|
|
34331
|
+
rawRadius
|
|
34332
|
+
) * traceTextureResolution;
|
|
34333
|
+
let rotation2 = hole.ccw_rotation || 0;
|
|
34334
|
+
if (layer === "bottom") {
|
|
34335
|
+
rotation2 = -rotation2;
|
|
34336
|
+
}
|
|
34337
|
+
if (rotation2) {
|
|
34338
|
+
ctx.save();
|
|
34339
|
+
ctx.translate(canvasX, canvasY);
|
|
34340
|
+
ctx.rotate(rotation2 * Math.PI / 180);
|
|
34341
|
+
ctx.beginPath();
|
|
34342
|
+
ctx.roundRect(
|
|
34343
|
+
-padWidth / 2,
|
|
34344
|
+
-padHeight / 2,
|
|
34345
|
+
padWidth,
|
|
34346
|
+
padHeight,
|
|
34347
|
+
borderRadius
|
|
34348
|
+
);
|
|
34349
|
+
ctx.fill();
|
|
34350
|
+
ctx.restore();
|
|
34351
|
+
} else {
|
|
34352
|
+
ctx.beginPath();
|
|
34353
|
+
ctx.roundRect(
|
|
34354
|
+
canvasX - padWidth / 2,
|
|
34355
|
+
canvasY - padHeight / 2,
|
|
34356
|
+
padWidth,
|
|
34357
|
+
padHeight,
|
|
34358
|
+
borderRadius
|
|
34359
|
+
);
|
|
34360
|
+
ctx.fill();
|
|
34361
|
+
}
|
|
34237
34362
|
}
|
|
34238
34363
|
});
|
|
34239
34364
|
const pcbHoles = su13(circuitJson).pcb_hole.list();
|
|
@@ -34248,35 +34373,33 @@ function createSoldermaskTextureForLayer({
|
|
|
34248
34373
|
ctx.beginPath();
|
|
34249
34374
|
ctx.arc(canvasX, canvasY, canvasRadius, 0, 2 * Math.PI);
|
|
34250
34375
|
ctx.fill();
|
|
34251
|
-
} else if (holeShape === "pill" && typeof hole.hole_width === "number" && typeof hole.hole_height === "number") {
|
|
34376
|
+
} else if ((holeShape === "pill" || holeShape === "rotated_pill") && typeof hole.hole_width === "number" && typeof hole.hole_height === "number") {
|
|
34252
34377
|
const width10 = hole.hole_width * traceTextureResolution;
|
|
34253
34378
|
const height10 = hole.hole_height * traceTextureResolution;
|
|
34254
34379
|
const radius = Math.min(width10, height10) / 2;
|
|
34255
|
-
|
|
34256
|
-
ctx.roundRect(
|
|
34257
|
-
canvasX - width10 / 2,
|
|
34258
|
-
canvasY - height10 / 2,
|
|
34259
|
-
width10,
|
|
34260
|
-
height10,
|
|
34261
|
-
radius
|
|
34262
|
-
);
|
|
34263
|
-
ctx.fill();
|
|
34264
|
-
} else if (holeShape === "rotated_pill" && typeof hole.hole_width === "number" && typeof hole.hole_height === "number") {
|
|
34265
|
-
const width10 = hole.hole_width * traceTextureResolution;
|
|
34266
|
-
const height10 = hole.hole_height * traceTextureResolution;
|
|
34267
|
-
const radius = Math.min(width10, height10) / 2;
|
|
34268
|
-
const rotation2 = (hole.ccw_rotation || 0) * (Math.PI / 180);
|
|
34269
|
-
ctx.save();
|
|
34270
|
-
ctx.translate(canvasX, canvasY);
|
|
34380
|
+
let rotation2 = (hole.ccw_rotation || 0) * (Math.PI / 180);
|
|
34271
34381
|
if (layer === "bottom") {
|
|
34272
|
-
|
|
34273
|
-
}
|
|
34382
|
+
rotation2 = -rotation2;
|
|
34383
|
+
}
|
|
34384
|
+
if (rotation2) {
|
|
34385
|
+
ctx.save();
|
|
34386
|
+
ctx.translate(canvasX, canvasY);
|
|
34274
34387
|
ctx.rotate(rotation2);
|
|
34388
|
+
ctx.beginPath();
|
|
34389
|
+
ctx.roundRect(-width10 / 2, -height10 / 2, width10, height10, radius);
|
|
34390
|
+
ctx.fill();
|
|
34391
|
+
ctx.restore();
|
|
34392
|
+
} else {
|
|
34393
|
+
ctx.beginPath();
|
|
34394
|
+
ctx.roundRect(
|
|
34395
|
+
canvasX - width10 / 2,
|
|
34396
|
+
canvasY - height10 / 2,
|
|
34397
|
+
width10,
|
|
34398
|
+
height10,
|
|
34399
|
+
radius
|
|
34400
|
+
);
|
|
34401
|
+
ctx.fill();
|
|
34275
34402
|
}
|
|
34276
|
-
ctx.beginPath();
|
|
34277
|
-
ctx.roundRect(-width10 / 2, -height10 / 2, width10, height10, radius);
|
|
34278
|
-
ctx.fill();
|
|
34279
|
-
ctx.restore();
|
|
34280
34403
|
}
|
|
34281
34404
|
});
|
|
34282
34405
|
const pcbCopperPours = su13(circuitJson).pcb_copper_pour.list();
|