@tscircuit/3d-viewer 0.0.476 → 0.0.478
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 +19 -21
- package/dist/index.js +694 -553
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -805,13 +805,13 @@ var require_cross = __commonJS({
|
|
|
805
805
|
var require_distance = __commonJS({
|
|
806
806
|
"node_modules/@jscad/modeling/src/maths/vec3/distance.js"(exports, module) {
|
|
807
807
|
"use strict";
|
|
808
|
-
var
|
|
808
|
+
var distance3 = (a, b) => {
|
|
809
809
|
const x = b[0] - a[0];
|
|
810
810
|
const y = b[1] - a[1];
|
|
811
811
|
const z138 = b[2] - a[2];
|
|
812
812
|
return Math.sqrt(x * x + y * y + z138 * z138);
|
|
813
813
|
};
|
|
814
|
-
module.exports =
|
|
814
|
+
module.exports = distance3;
|
|
815
815
|
}
|
|
816
816
|
});
|
|
817
817
|
|
|
@@ -1933,12 +1933,12 @@ var require_cross2 = __commonJS({
|
|
|
1933
1933
|
var require_distance2 = __commonJS({
|
|
1934
1934
|
"node_modules/@jscad/modeling/src/maths/vec2/distance.js"(exports, module) {
|
|
1935
1935
|
"use strict";
|
|
1936
|
-
var
|
|
1936
|
+
var distance3 = (a, b) => {
|
|
1937
1937
|
const x = b[0] - a[0];
|
|
1938
1938
|
const y = b[1] - a[1];
|
|
1939
1939
|
return Math.sqrt(x * x + y * y);
|
|
1940
1940
|
};
|
|
1941
|
-
module.exports =
|
|
1941
|
+
module.exports = distance3;
|
|
1942
1942
|
}
|
|
1943
1943
|
});
|
|
1944
1944
|
|
|
@@ -2861,7 +2861,7 @@ var require_Vertex = __commonJS({
|
|
|
2861
2861
|
var require_HalfEdge = __commonJS({
|
|
2862
2862
|
"node_modules/@jscad/modeling/src/operations/hulls/quickhull/HalfEdge.js"(exports, module) {
|
|
2863
2863
|
"use strict";
|
|
2864
|
-
var
|
|
2864
|
+
var distance3 = require_distance();
|
|
2865
2865
|
var squaredDistance = require_squaredDistance();
|
|
2866
2866
|
var HalfEdge = class {
|
|
2867
2867
|
constructor(vertex, face) {
|
|
@@ -2879,7 +2879,7 @@ var require_HalfEdge = __commonJS({
|
|
|
2879
2879
|
}
|
|
2880
2880
|
length() {
|
|
2881
2881
|
if (this.tail()) {
|
|
2882
|
-
return
|
|
2882
|
+
return distance3(
|
|
2883
2883
|
this.tail().point,
|
|
2884
2884
|
this.head().point
|
|
2885
2885
|
);
|
|
@@ -3216,8 +3216,8 @@ var require_QuickHull = __commonJS({
|
|
|
3216
3216
|
let nextVertex;
|
|
3217
3217
|
for (let vertex = faceVertices; vertex; vertex = nextVertex) {
|
|
3218
3218
|
nextVertex = vertex.next;
|
|
3219
|
-
const
|
|
3220
|
-
if (
|
|
3219
|
+
const distance3 = absorbingFace.distanceToPlane(vertex.point);
|
|
3220
|
+
if (distance3 > this.tolerance) {
|
|
3221
3221
|
this.addVertexToFace(vertex, absorbingFace);
|
|
3222
3222
|
} else {
|
|
3223
3223
|
this.unclaimed.add(vertex);
|
|
@@ -3304,9 +3304,9 @@ var require_QuickHull = __commonJS({
|
|
|
3304
3304
|
let maxDistance = 0;
|
|
3305
3305
|
let indexMax = 0;
|
|
3306
3306
|
for (i = 0; i < 3; i += 1) {
|
|
3307
|
-
const
|
|
3308
|
-
if (
|
|
3309
|
-
maxDistance =
|
|
3307
|
+
const distance3 = max2[i].point[i] - min2[i].point[i];
|
|
3308
|
+
if (distance3 > maxDistance) {
|
|
3309
|
+
maxDistance = distance3;
|
|
3310
3310
|
indexMax = i;
|
|
3311
3311
|
}
|
|
3312
3312
|
}
|
|
@@ -3316,13 +3316,13 @@ var require_QuickHull = __commonJS({
|
|
|
3316
3316
|
for (i = 0; i < this.vertices.length; i += 1) {
|
|
3317
3317
|
const vertex = this.vertices[i];
|
|
3318
3318
|
if (vertex !== v0 && vertex !== v1) {
|
|
3319
|
-
const
|
|
3319
|
+
const distance3 = pointLineDistance(
|
|
3320
3320
|
vertex.point,
|
|
3321
3321
|
v0.point,
|
|
3322
3322
|
v1.point
|
|
3323
3323
|
);
|
|
3324
|
-
if (
|
|
3325
|
-
maxDistance =
|
|
3324
|
+
if (distance3 > maxDistance) {
|
|
3325
|
+
maxDistance = distance3;
|
|
3326
3326
|
v2 = vertex;
|
|
3327
3327
|
}
|
|
3328
3328
|
}
|
|
@@ -3333,9 +3333,9 @@ var require_QuickHull = __commonJS({
|
|
|
3333
3333
|
for (i = 0; i < this.vertices.length; i += 1) {
|
|
3334
3334
|
const vertex = this.vertices[i];
|
|
3335
3335
|
if (vertex !== v0 && vertex !== v1 && vertex !== v2) {
|
|
3336
|
-
const
|
|
3337
|
-
if (
|
|
3338
|
-
maxDistance =
|
|
3336
|
+
const distance3 = Math.abs(dot(normal, vertex.point) - distPO);
|
|
3337
|
+
if (distance3 > maxDistance) {
|
|
3338
|
+
maxDistance = distance3;
|
|
3339
3339
|
v3 = vertex;
|
|
3340
3340
|
}
|
|
3341
3341
|
}
|
|
@@ -3375,9 +3375,9 @@ var require_QuickHull = __commonJS({
|
|
|
3375
3375
|
maxDistance = this.tolerance;
|
|
3376
3376
|
let maxFace;
|
|
3377
3377
|
for (j = 0; j < 4; j += 1) {
|
|
3378
|
-
const
|
|
3379
|
-
if (
|
|
3380
|
-
maxDistance =
|
|
3378
|
+
const distance3 = faces[j].distanceToPlane(vertex.point);
|
|
3379
|
+
if (distance3 > maxDistance) {
|
|
3380
|
+
maxDistance = distance3;
|
|
3381
3381
|
maxFace = faces[j];
|
|
3382
3382
|
}
|
|
3383
3383
|
}
|
|
@@ -3433,9 +3433,9 @@ var require_QuickHull = __commonJS({
|
|
|
3433
3433
|
let maxDistance = 0;
|
|
3434
3434
|
const eyeFace = this.claimed.first().face;
|
|
3435
3435
|
for (vertex = eyeFace.outside; vertex && vertex.face === eyeFace; vertex = vertex.next) {
|
|
3436
|
-
const
|
|
3437
|
-
if (
|
|
3438
|
-
maxDistance =
|
|
3436
|
+
const distance3 = eyeFace.distanceToPlane(vertex.point);
|
|
3437
|
+
if (distance3 > maxDistance) {
|
|
3438
|
+
maxDistance = distance3;
|
|
3439
3439
|
eyeVertex = vertex;
|
|
3440
3440
|
}
|
|
3441
3441
|
}
|
|
@@ -6069,13 +6069,13 @@ var require_arcLengthToT = __commonJS({
|
|
|
6069
6069
|
distance: 0,
|
|
6070
6070
|
segments: 100
|
|
6071
6071
|
};
|
|
6072
|
-
const { distance:
|
|
6072
|
+
const { distance: distance3, segments } = Object.assign({}, defaults, options);
|
|
6073
6073
|
const arcLengths = lengths(segments, bezier);
|
|
6074
6074
|
let startIndex = 0;
|
|
6075
6075
|
let endIndex = segments;
|
|
6076
6076
|
while (startIndex <= endIndex) {
|
|
6077
6077
|
const middleIndex = Math.floor(startIndex + (endIndex - startIndex) / 2);
|
|
6078
|
-
const diff = arcLengths[middleIndex] -
|
|
6078
|
+
const diff = arcLengths[middleIndex] - distance3;
|
|
6079
6079
|
if (diff < 0) {
|
|
6080
6080
|
startIndex = middleIndex + 1;
|
|
6081
6081
|
} else if (diff > 0) {
|
|
@@ -6086,13 +6086,13 @@ var require_arcLengthToT = __commonJS({
|
|
|
6086
6086
|
}
|
|
6087
6087
|
}
|
|
6088
6088
|
const targetIndex = endIndex;
|
|
6089
|
-
if (arcLengths[targetIndex] ===
|
|
6089
|
+
if (arcLengths[targetIndex] === distance3) {
|
|
6090
6090
|
return targetIndex / segments;
|
|
6091
6091
|
}
|
|
6092
6092
|
const lengthBefore = arcLengths[targetIndex];
|
|
6093
6093
|
const lengthAfter = arcLengths[targetIndex + 1];
|
|
6094
6094
|
const segmentLength = lengthAfter - lengthBefore;
|
|
6095
|
-
const segmentFraction = (
|
|
6095
|
+
const segmentFraction = (distance3 - lengthBefore) / segmentLength;
|
|
6096
6096
|
return (targetIndex + segmentFraction) / segments;
|
|
6097
6097
|
};
|
|
6098
6098
|
module.exports = arcLengthToT;
|
|
@@ -6342,9 +6342,9 @@ var require_distanceToPoint = __commonJS({
|
|
|
6342
6342
|
"use strict";
|
|
6343
6343
|
var vec2 = require_vec2();
|
|
6344
6344
|
var distanceToPoint = (line2, point2) => {
|
|
6345
|
-
let
|
|
6346
|
-
|
|
6347
|
-
return
|
|
6345
|
+
let distance3 = vec2.dot(point2, line2);
|
|
6346
|
+
distance3 = Math.abs(distance3 - line2[2]);
|
|
6347
|
+
return distance3;
|
|
6348
6348
|
};
|
|
6349
6349
|
module.exports = distanceToPoint;
|
|
6350
6350
|
}
|
|
@@ -6368,10 +6368,10 @@ var require_fromPoints6 = __commonJS({
|
|
|
6368
6368
|
const vector = vec2.subtract(vec2.create(), point2, point1);
|
|
6369
6369
|
vec2.normal(vector, vector);
|
|
6370
6370
|
vec2.normalize(vector, vector);
|
|
6371
|
-
const
|
|
6371
|
+
const distance3 = vec2.dot(point1, vector);
|
|
6372
6372
|
out[0] = vector[0];
|
|
6373
6373
|
out[1] = vector[1];
|
|
6374
|
-
out[2] =
|
|
6374
|
+
out[2] = distance3;
|
|
6375
6375
|
return out;
|
|
6376
6376
|
};
|
|
6377
6377
|
module.exports = fromPoints;
|
|
@@ -6513,8 +6513,8 @@ var require_reverse3 = __commonJS({
|
|
|
6513
6513
|
var fromValues = require_fromValues5();
|
|
6514
6514
|
var reverse = (out, line2) => {
|
|
6515
6515
|
const normal = vec2.negate(vec2.create(), line2);
|
|
6516
|
-
const
|
|
6517
|
-
return copy(out, fromValues(normal[0], normal[1],
|
|
6516
|
+
const distance3 = -line2[2];
|
|
6517
|
+
return copy(out, fromValues(normal[0], normal[1], distance3));
|
|
6518
6518
|
};
|
|
6519
6519
|
module.exports = reverse;
|
|
6520
6520
|
}
|
|
@@ -7862,7 +7862,7 @@ var require_polyhedron = __commonJS({
|
|
|
7862
7862
|
colors: void 0,
|
|
7863
7863
|
orientation: "outward"
|
|
7864
7864
|
};
|
|
7865
|
-
const { points, faces, colors: colors2, orientation } = Object.assign({}, defaults, options);
|
|
7865
|
+
const { points, faces, colors: colors2, orientation: orientation2 } = Object.assign({}, defaults, options);
|
|
7866
7866
|
if (!(Array.isArray(points) && Array.isArray(faces))) {
|
|
7867
7867
|
throw new Error("points and faces must be arrays");
|
|
7868
7868
|
}
|
|
@@ -7887,7 +7887,7 @@ var require_polyhedron = __commonJS({
|
|
|
7887
7887
|
if (face.length < 3) throw new Error(`face ${i} must contain 3 or more indexes`);
|
|
7888
7888
|
if (!isNumberArray(face, face.length)) throw new Error(`face ${i} must be an array of numbers`);
|
|
7889
7889
|
});
|
|
7890
|
-
if (
|
|
7890
|
+
if (orientation2 !== "outward") {
|
|
7891
7891
|
faces.forEach((face) => face.reverse());
|
|
7892
7892
|
}
|
|
7893
7893
|
const polygons = faces.map((face, findex) => {
|
|
@@ -8052,7 +8052,7 @@ var require_polygon = __commonJS({
|
|
|
8052
8052
|
paths: [],
|
|
8053
8053
|
orientation: "counterclockwise"
|
|
8054
8054
|
};
|
|
8055
|
-
const { points, paths, orientation } = Object.assign({}, defaults, options);
|
|
8055
|
+
const { points, paths, orientation: orientation2 } = Object.assign({}, defaults, options);
|
|
8056
8056
|
if (!(Array.isArray(points) && Array.isArray(paths))) throw new Error("points and paths must be arrays");
|
|
8057
8057
|
let listofpolys = points;
|
|
8058
8058
|
if (Array.isArray(points[0])) {
|
|
@@ -8082,7 +8082,7 @@ var require_polygon = __commonJS({
|
|
|
8082
8082
|
sides2 = sides2.concat(geom2.toSides(geometry2));
|
|
8083
8083
|
});
|
|
8084
8084
|
let geometry = geom2.create(sides2);
|
|
8085
|
-
if (
|
|
8085
|
+
if (orientation2 === "clockwise") {
|
|
8086
8086
|
geometry = geom2.reverse(geometry);
|
|
8087
8087
|
}
|
|
8088
8088
|
return geometry;
|
|
@@ -8597,16 +8597,16 @@ var require_calculatePlane = __commonJS({
|
|
|
8597
8597
|
var calculatePlane = (slice) => {
|
|
8598
8598
|
const edges = slice.edges;
|
|
8599
8599
|
if (edges.length < 3) throw new Error("slices must have 3 or more edges to calculate a plane");
|
|
8600
|
-
const
|
|
8601
|
-
vec3.scale(
|
|
8600
|
+
const midpoint2 = edges.reduce((point2, edge) => vec3.add(vec3.create(), point2, edge[0]), vec3.create());
|
|
8601
|
+
vec3.scale(midpoint2, midpoint2, 1 / edges.length);
|
|
8602
8602
|
let farthestEdge;
|
|
8603
|
-
let
|
|
8603
|
+
let distance3 = 0;
|
|
8604
8604
|
edges.forEach((edge) => {
|
|
8605
8605
|
if (!vec3.equals(edge[0], edge[1])) {
|
|
8606
|
-
const d = vec3.squaredDistance(
|
|
8607
|
-
if (d >
|
|
8606
|
+
const d = vec3.squaredDistance(midpoint2, edge[0]);
|
|
8607
|
+
if (d > distance3) {
|
|
8608
8608
|
farthestEdge = edge;
|
|
8609
|
-
|
|
8609
|
+
distance3 = d;
|
|
8610
8610
|
}
|
|
8611
8611
|
}
|
|
8612
8612
|
});
|
|
@@ -8969,13 +8969,13 @@ var require_linkedPolygon = __commonJS({
|
|
|
8969
8969
|
const o3 = Math.sign(area(p2, q2, p1));
|
|
8970
8970
|
const o4 = Math.sign(area(p2, q2, q1));
|
|
8971
8971
|
if (o1 !== o2 && o3 !== o4) return true;
|
|
8972
|
-
if (o1 === 0 &&
|
|
8973
|
-
if (o2 === 0 &&
|
|
8974
|
-
if (o3 === 0 &&
|
|
8975
|
-
if (o4 === 0 &&
|
|
8972
|
+
if (o1 === 0 && onSegment2(p1, p2, q1)) return true;
|
|
8973
|
+
if (o2 === 0 && onSegment2(p1, q2, q1)) return true;
|
|
8974
|
+
if (o3 === 0 && onSegment2(p2, p1, q2)) return true;
|
|
8975
|
+
if (o4 === 0 && onSegment2(p2, q1, q2)) return true;
|
|
8976
8976
|
return false;
|
|
8977
8977
|
};
|
|
8978
|
-
var
|
|
8978
|
+
var onSegment2 = (p, q, r) => q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
|
|
8979
8979
|
var signedArea = (data, start, end, dim) => {
|
|
8980
8980
|
let sum = 0;
|
|
8981
8981
|
for (let i = start, j = end - dim; i < end; i += dim) {
|
|
@@ -9454,9 +9454,9 @@ var require_repair = __commonJS({
|
|
|
9454
9454
|
let bestReplacement;
|
|
9455
9455
|
missingOut.forEach((key2) => {
|
|
9456
9456
|
const v2 = vertexMap.get(key2);
|
|
9457
|
-
const
|
|
9458
|
-
if (
|
|
9459
|
-
bestDistance =
|
|
9457
|
+
const distance3 = vec3.distance(v1, v2);
|
|
9458
|
+
if (distance3 < bestDistance) {
|
|
9459
|
+
bestDistance = distance3;
|
|
9460
9460
|
bestReplacement = v2;
|
|
9461
9461
|
}
|
|
9462
9462
|
});
|
|
@@ -11802,7 +11802,7 @@ var require_offsetFromPoints = __commonJS({
|
|
|
11802
11802
|
if (Math.abs(delta) < EPS) return points;
|
|
11803
11803
|
let rotation2 = options.closed ? area(points) : 1;
|
|
11804
11804
|
if (rotation2 === 0) rotation2 = 1;
|
|
11805
|
-
const
|
|
11805
|
+
const orientation2 = rotation2 > 0 && delta >= 0 || rotation2 < 0 && delta < 0;
|
|
11806
11806
|
delta = Math.abs(delta);
|
|
11807
11807
|
let previousSegment = null;
|
|
11808
11808
|
let newPoints = [];
|
|
@@ -11813,7 +11813,7 @@ var require_offsetFromPoints = __commonJS({
|
|
|
11813
11813
|
const j = (i + 1) % n;
|
|
11814
11814
|
const p0 = points[i];
|
|
11815
11815
|
const p1 = points[j];
|
|
11816
|
-
|
|
11816
|
+
orientation2 ? vec2.subtract(of, p0, p1) : vec2.subtract(of, p1, p0);
|
|
11817
11817
|
vec2.normal(of, of);
|
|
11818
11818
|
vec2.normalize(of, of);
|
|
11819
11819
|
vec2.scale(of, of, delta);
|
|
@@ -11877,11 +11877,11 @@ var require_offsetFromPoints = __commonJS({
|
|
|
11877
11877
|
newCorners.forEach((corner) => {
|
|
11878
11878
|
let rotation3 = vec2.angle(vec2.subtract(v0, corner.s1[0], corner.c));
|
|
11879
11879
|
rotation3 -= vec2.angle(vec2.subtract(v0, corner.s0[1], corner.c));
|
|
11880
|
-
if (
|
|
11880
|
+
if (orientation2 && rotation3 < 0) {
|
|
11881
11881
|
rotation3 = rotation3 + Math.PI;
|
|
11882
11882
|
if (rotation3 < 0) rotation3 = rotation3 + Math.PI;
|
|
11883
11883
|
}
|
|
11884
|
-
if (!
|
|
11884
|
+
if (!orientation2 && rotation3 > 0) {
|
|
11885
11885
|
rotation3 = rotation3 - Math.PI;
|
|
11886
11886
|
if (rotation3 > 0) rotation3 = rotation3 - Math.PI;
|
|
11887
11887
|
}
|
|
@@ -12718,8 +12718,8 @@ var require_hullPoints2 = __commonJS({
|
|
|
12718
12718
|
const points = [];
|
|
12719
12719
|
uniquePoints.forEach((point2) => {
|
|
12720
12720
|
const angle = fakeAtan2(point2[1] - min2[1], point2[0] - min2[0]);
|
|
12721
|
-
const
|
|
12722
|
-
points.push({ point: point2, angle, distSq });
|
|
12721
|
+
const distSq2 = vec2.squaredDistance(point2, min2);
|
|
12722
|
+
points.push({ point: point2, angle, distSq: distSq2 });
|
|
12723
12723
|
});
|
|
12724
12724
|
points.sort((pt1, pt2) => pt1.angle !== pt2.angle ? pt1.angle - pt2.angle : pt1.distSq - pt2.distSq);
|
|
12725
12725
|
const stack = [];
|
|
@@ -13361,11 +13361,11 @@ var require_triangulatePolygons = __commonJS({
|
|
|
13361
13361
|
const nv = polygon3.vertices.length;
|
|
13362
13362
|
if (nv > 3) {
|
|
13363
13363
|
if (nv > 4) {
|
|
13364
|
-
const
|
|
13365
|
-
polygon3.vertices.forEach((vertice) => vec3.add(
|
|
13366
|
-
vec3.snap(
|
|
13364
|
+
const midpoint2 = [0, 0, 0];
|
|
13365
|
+
polygon3.vertices.forEach((vertice) => vec3.add(midpoint2, midpoint2, vertice));
|
|
13366
|
+
vec3.snap(midpoint2, vec3.divide(midpoint2, midpoint2, [nv, nv, nv]), epsilon);
|
|
13367
13367
|
for (let i = 0; i < nv; i++) {
|
|
13368
|
-
const poly = poly3.create([
|
|
13368
|
+
const poly = poly3.create([midpoint2, polygon3.vertices[i], polygon3.vertices[(i + 1) % nv]]);
|
|
13369
13369
|
if (polygon3.color) poly.color = polygon3.color;
|
|
13370
13370
|
triangles.push(poly);
|
|
13371
13371
|
}
|
|
@@ -18225,12 +18225,12 @@ var bga_def = z510.object({
|
|
|
18225
18225
|
});
|
|
18226
18226
|
var bga = (raw_params) => {
|
|
18227
18227
|
const parameters = bga_def.parse(raw_params);
|
|
18228
|
-
let { num_pins, grid, p, w, h: h2, ball, pad: pad2, missing } = parameters;
|
|
18228
|
+
let { num_pins, grid: grid2, p, w, h: h2, ball, pad: pad2, missing } = parameters;
|
|
18229
18229
|
ball ??= 0.75 / 1.27 * p;
|
|
18230
18230
|
pad2 ??= ball * 0.8;
|
|
18231
18231
|
const pads = [];
|
|
18232
18232
|
const missing_pin_nums = (missing ?? []).filter((a) => typeof a === "number");
|
|
18233
|
-
const num_pins_missing =
|
|
18233
|
+
const num_pins_missing = grid2.x * grid2.y - num_pins;
|
|
18234
18234
|
if (missing.length === 0 && num_pins_missing > 0) {
|
|
18235
18235
|
if (Math.sqrt(num_pins_missing) % 1 === 0) {
|
|
18236
18236
|
missing.push("center");
|
|
@@ -18240,11 +18240,11 @@ var bga = (raw_params) => {
|
|
|
18240
18240
|
}
|
|
18241
18241
|
if (missing?.includes("center")) {
|
|
18242
18242
|
const square_size = Math.floor(Math.sqrt(num_pins_missing));
|
|
18243
|
-
const inner_square_x = Math.floor((
|
|
18244
|
-
const inner_square_y = Math.floor((
|
|
18243
|
+
const inner_square_x = Math.floor((grid2.x - square_size) / 2);
|
|
18244
|
+
const inner_square_y = Math.floor((grid2.y - square_size) / 2);
|
|
18245
18245
|
for (let y = inner_square_y; y < inner_square_y + square_size; y++) {
|
|
18246
18246
|
for (let x = inner_square_x; x < inner_square_x + square_size; x++) {
|
|
18247
|
-
missing_pin_nums.push(y *
|
|
18247
|
+
missing_pin_nums.push(y * grid2.x + x + 1);
|
|
18248
18248
|
}
|
|
18249
18249
|
}
|
|
18250
18250
|
}
|
|
@@ -18253,30 +18253,30 @@ var bga = (raw_params) => {
|
|
|
18253
18253
|
}
|
|
18254
18254
|
const missing_pin_nums_set = new Set(missing_pin_nums);
|
|
18255
18255
|
let missing_pins_passed = 0;
|
|
18256
|
-
for (let y = 0; y <
|
|
18257
|
-
for (let x = 0; x <
|
|
18258
|
-
const pad_x = (x - (
|
|
18259
|
-
const pad_y = (y - (
|
|
18256
|
+
for (let y = 0; y < grid2.y; y++) {
|
|
18257
|
+
for (let x = 0; x < grid2.x; x++) {
|
|
18258
|
+
const pad_x = (x - (grid2.x - 1) / 2) * p;
|
|
18259
|
+
const pad_y = (y - (grid2.y - 1) / 2) * p;
|
|
18260
18260
|
let pin_x = x;
|
|
18261
18261
|
let pin_y = y;
|
|
18262
18262
|
switch (parameters.origin) {
|
|
18263
18263
|
case "bl":
|
|
18264
18264
|
pin_x = x;
|
|
18265
|
-
pin_y =
|
|
18265
|
+
pin_y = grid2.y - 1 - y;
|
|
18266
18266
|
break;
|
|
18267
18267
|
case "br":
|
|
18268
|
-
pin_x =
|
|
18269
|
-
pin_y =
|
|
18268
|
+
pin_x = grid2.x - 1 - x;
|
|
18269
|
+
pin_y = grid2.y - 1 - y;
|
|
18270
18270
|
break;
|
|
18271
18271
|
case "tr":
|
|
18272
|
-
pin_x =
|
|
18272
|
+
pin_x = grid2.x - 1 - x;
|
|
18273
18273
|
pin_y = y;
|
|
18274
18274
|
break;
|
|
18275
18275
|
case "tl":
|
|
18276
18276
|
default:
|
|
18277
18277
|
break;
|
|
18278
18278
|
}
|
|
18279
|
-
let pin_num = pin_y *
|
|
18279
|
+
let pin_num = pin_y * grid2.x + pin_x + 1;
|
|
18280
18280
|
if (missing_pin_nums_set.has(pin_num)) {
|
|
18281
18281
|
missing_pins_passed++;
|
|
18282
18282
|
continue;
|
|
@@ -18294,13 +18294,13 @@ var bga = (raw_params) => {
|
|
|
18294
18294
|
}
|
|
18295
18295
|
const silkscreenRefText = silkscreenRef(
|
|
18296
18296
|
0,
|
|
18297
|
-
|
|
18297
|
+
grid2.y * p / 2,
|
|
18298
18298
|
0.2
|
|
18299
18299
|
);
|
|
18300
18300
|
const pin1MarkerSize = p / 6;
|
|
18301
18301
|
let markerRoute;
|
|
18302
|
-
const edgeX =
|
|
18303
|
-
const edgeY =
|
|
18302
|
+
const edgeX = grid2.x * p / 2;
|
|
18303
|
+
const edgeY = grid2.y * p / 2;
|
|
18304
18304
|
switch (parameters.origin) {
|
|
18305
18305
|
case "bl":
|
|
18306
18306
|
markerRoute = [
|
|
@@ -18614,7 +18614,7 @@ var quad = (raw_params) => {
|
|
|
18614
18614
|
const {
|
|
18615
18615
|
x,
|
|
18616
18616
|
y,
|
|
18617
|
-
o:
|
|
18617
|
+
o: orientation2
|
|
18618
18618
|
} = getQuadCoords({
|
|
18619
18619
|
pin_count: parameters.num_pins,
|
|
18620
18620
|
pn: i + 1,
|
|
@@ -18626,7 +18626,7 @@ var quad = (raw_params) => {
|
|
|
18626
18626
|
});
|
|
18627
18627
|
let pw = parameters.pw;
|
|
18628
18628
|
let pl = parameters.pl;
|
|
18629
|
-
if (
|
|
18629
|
+
if (orientation2 === "vert") {
|
|
18630
18630
|
;
|
|
18631
18631
|
[pw, pl] = [pl, pw];
|
|
18632
18632
|
}
|
|
@@ -25622,7 +25622,7 @@ var QFN = ({
|
|
|
25622
25622
|
const {
|
|
25623
25623
|
x,
|
|
25624
25624
|
y,
|
|
25625
|
-
o:
|
|
25625
|
+
o: orientation2
|
|
25626
25626
|
} = getQuadCoords2({
|
|
25627
25627
|
pin_count: num_pins,
|
|
25628
25628
|
pn: i + 1,
|
|
@@ -25634,7 +25634,7 @@ var QFN = ({
|
|
|
25634
25634
|
});
|
|
25635
25635
|
let pw = padWidth;
|
|
25636
25636
|
let pl = padLength;
|
|
25637
|
-
if (
|
|
25637
|
+
if (orientation2 === "vert") {
|
|
25638
25638
|
;
|
|
25639
25639
|
[pw, pl] = [pl, pw];
|
|
25640
25640
|
}
|
|
@@ -29492,7 +29492,7 @@ import * as THREE15 from "three";
|
|
|
29492
29492
|
// package.json
|
|
29493
29493
|
var package_default = {
|
|
29494
29494
|
name: "@tscircuit/3d-viewer",
|
|
29495
|
-
version: "0.0.
|
|
29495
|
+
version: "0.0.477",
|
|
29496
29496
|
main: "./dist/index.js",
|
|
29497
29497
|
module: "./dist/index.js",
|
|
29498
29498
|
type: "module",
|
|
@@ -29521,6 +29521,7 @@ var package_default = {
|
|
|
29521
29521
|
dependencies: {
|
|
29522
29522
|
"@jscad/regl-renderer": "^2.6.12",
|
|
29523
29523
|
"@jscad/stl-serializer": "^2.1.20",
|
|
29524
|
+
"circuit-to-canvas": "^0.0.26",
|
|
29524
29525
|
"react-hot-toast": "^2.6.0",
|
|
29525
29526
|
three: "^0.165.0",
|
|
29526
29527
|
"three-stdlib": "^2.36.0",
|
|
@@ -29652,12 +29653,12 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
|
|
|
29652
29653
|
);
|
|
29653
29654
|
const baseDistance = useMemo8(() => {
|
|
29654
29655
|
const [x, y, z138] = initialCameraPosition ?? [5, -5, 5];
|
|
29655
|
-
const
|
|
29656
|
+
const distance3 = Math.hypot(
|
|
29656
29657
|
x - defaultTarget.x,
|
|
29657
29658
|
y - defaultTarget.y,
|
|
29658
29659
|
z138 - defaultTarget.z
|
|
29659
29660
|
);
|
|
29660
|
-
return
|
|
29661
|
+
return distance3 > 0 ? distance3 : 5;
|
|
29661
29662
|
}, [initialCameraPosition, defaultTarget]);
|
|
29662
29663
|
const getPresetConfig = useCallback4(
|
|
29663
29664
|
(preset) => {
|
|
@@ -29668,13 +29669,13 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
|
|
|
29668
29669
|
];
|
|
29669
29670
|
const camera = mainCameraRef.current;
|
|
29670
29671
|
const controls = controlsRef.current;
|
|
29671
|
-
let
|
|
29672
|
+
let distance3 = baseDistance;
|
|
29672
29673
|
if (camera && controls) {
|
|
29673
|
-
|
|
29674
|
+
distance3 = camera.position.distanceTo(controls.target);
|
|
29674
29675
|
}
|
|
29675
29676
|
switch (preset) {
|
|
29676
29677
|
case "Top Center Angled": {
|
|
29677
|
-
const angledOffset =
|
|
29678
|
+
const angledOffset = distance3 / Math.sqrt(2);
|
|
29678
29679
|
return {
|
|
29679
29680
|
position: [
|
|
29680
29681
|
defaultTarget.x,
|
|
@@ -29690,7 +29691,7 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
|
|
|
29690
29691
|
position: [
|
|
29691
29692
|
defaultTarget.x,
|
|
29692
29693
|
defaultTarget.y,
|
|
29693
|
-
defaultTarget.z +
|
|
29694
|
+
defaultTarget.z + distance3
|
|
29694
29695
|
],
|
|
29695
29696
|
target: targetVector,
|
|
29696
29697
|
up: [0, 0, 1]
|
|
@@ -29698,9 +29699,9 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
|
|
|
29698
29699
|
case "Top Left Corner":
|
|
29699
29700
|
return {
|
|
29700
29701
|
position: [
|
|
29701
|
-
defaultTarget.x -
|
|
29702
|
-
defaultTarget.y -
|
|
29703
|
-
defaultTarget.z +
|
|
29702
|
+
defaultTarget.x - distance3 * 0.6,
|
|
29703
|
+
defaultTarget.y - distance3 * 0.6,
|
|
29704
|
+
defaultTarget.z + distance3 * 0.6
|
|
29704
29705
|
],
|
|
29705
29706
|
target: targetVector,
|
|
29706
29707
|
up: [0, 0, 1]
|
|
@@ -29708,9 +29709,9 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
|
|
|
29708
29709
|
case "Top Right Corner":
|
|
29709
29710
|
return {
|
|
29710
29711
|
position: [
|
|
29711
|
-
defaultTarget.x +
|
|
29712
|
-
defaultTarget.y -
|
|
29713
|
-
defaultTarget.z +
|
|
29712
|
+
defaultTarget.x + distance3 * 0.6,
|
|
29713
|
+
defaultTarget.y - distance3 * 0.6,
|
|
29714
|
+
defaultTarget.z + distance3 * 0.6
|
|
29714
29715
|
],
|
|
29715
29716
|
target: targetVector,
|
|
29716
29717
|
up: [0, 0, 1]
|
|
@@ -29718,7 +29719,7 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
|
|
|
29718
29719
|
case "Left Sideview":
|
|
29719
29720
|
return {
|
|
29720
29721
|
position: [
|
|
29721
|
-
defaultTarget.x -
|
|
29722
|
+
defaultTarget.x - distance3,
|
|
29722
29723
|
defaultTarget.y,
|
|
29723
29724
|
defaultTarget.z
|
|
29724
29725
|
],
|
|
@@ -29728,7 +29729,7 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
|
|
|
29728
29729
|
case "Right Sideview":
|
|
29729
29730
|
return {
|
|
29730
29731
|
position: [
|
|
29731
|
-
defaultTarget.x +
|
|
29732
|
+
defaultTarget.x + distance3,
|
|
29732
29733
|
defaultTarget.y,
|
|
29733
29734
|
defaultTarget.z
|
|
29734
29735
|
],
|
|
@@ -29739,7 +29740,7 @@ var CameraControllerProvider = ({ children, defaultTarget, initialCameraPosition
|
|
|
29739
29740
|
return {
|
|
29740
29741
|
position: [
|
|
29741
29742
|
defaultTarget.x,
|
|
29742
|
-
defaultTarget.y -
|
|
29743
|
+
defaultTarget.y - distance3,
|
|
29743
29744
|
defaultTarget.z
|
|
29744
29745
|
],
|
|
29745
29746
|
target: targetVector,
|
|
@@ -30321,13 +30322,13 @@ import { useEffect as useEffect15, useRef as useRef7 } from "react";
|
|
|
30321
30322
|
import * as THREE14 from "three";
|
|
30322
30323
|
import { Text as TroikaText } from "troika-three-text";
|
|
30323
30324
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
30324
|
-
function computePointInFront(rotationVector,
|
|
30325
|
+
function computePointInFront(rotationVector, distance3) {
|
|
30325
30326
|
const quaternion = new THREE14.Quaternion().setFromEuler(
|
|
30326
30327
|
new THREE14.Euler(rotationVector.x, rotationVector.y, rotationVector.z)
|
|
30327
30328
|
);
|
|
30328
30329
|
const forwardVector = new THREE14.Vector3(0, 0, 1);
|
|
30329
30330
|
forwardVector.applyQuaternion(quaternion);
|
|
30330
|
-
const result = forwardVector.multiplyScalar(
|
|
30331
|
+
const result = forwardVector.multiplyScalar(distance3);
|
|
30331
30332
|
return result;
|
|
30332
30333
|
}
|
|
30333
30334
|
var OrientationCubeCanvas = () => {
|
|
@@ -32607,6 +32608,58 @@ import { su as su9 } from "@tscircuit/circuit-json-util";
|
|
|
32607
32608
|
// src/utils/soldermask-texture.ts
|
|
32608
32609
|
import * as THREE18 from "three";
|
|
32609
32610
|
import { su as su5 } from "@tscircuit/circuit-json-util";
|
|
32611
|
+
|
|
32612
|
+
// node_modules/@tscircuit/math-utils/dist/chunk-5N7UJNVK.js
|
|
32613
|
+
var getBoundsFromPoints = (points) => {
|
|
32614
|
+
if (points.length === 0) {
|
|
32615
|
+
return null;
|
|
32616
|
+
}
|
|
32617
|
+
let minX = points[0].x;
|
|
32618
|
+
let minY = points[0].y;
|
|
32619
|
+
let maxX = points[0].x;
|
|
32620
|
+
let maxY = points[0].y;
|
|
32621
|
+
for (let i = 1; i < points.length; i++) {
|
|
32622
|
+
const point2 = points[i];
|
|
32623
|
+
if (point2.x < minX) minX = point2.x;
|
|
32624
|
+
if (point2.y < minY) minY = point2.y;
|
|
32625
|
+
if (point2.x > maxX) maxX = point2.x;
|
|
32626
|
+
if (point2.y > maxY) maxY = point2.y;
|
|
32627
|
+
}
|
|
32628
|
+
return { minX, minY, maxX, maxY };
|
|
32629
|
+
};
|
|
32630
|
+
|
|
32631
|
+
// src/utils/outline-bounds.ts
|
|
32632
|
+
function calculateOutlineBounds(boardData) {
|
|
32633
|
+
if (boardData.outline && boardData.outline.length >= 3) {
|
|
32634
|
+
const bounds2 = getBoundsFromPoints(boardData.outline);
|
|
32635
|
+
return {
|
|
32636
|
+
...bounds2,
|
|
32637
|
+
width: bounds2.maxX - bounds2.minX,
|
|
32638
|
+
height: bounds2.maxY - bounds2.minY,
|
|
32639
|
+
centerX: (bounds2.minX + bounds2.maxX) / 2,
|
|
32640
|
+
centerY: (bounds2.minY + bounds2.maxY) / 2
|
|
32641
|
+
};
|
|
32642
|
+
}
|
|
32643
|
+
const boardWidth = boardData.width ?? 0;
|
|
32644
|
+
const boardHeight = boardData.height ?? 0;
|
|
32645
|
+
const boardCenterX = boardData.center?.x ?? 0;
|
|
32646
|
+
const boardCenterY = boardData.center?.y ?? 0;
|
|
32647
|
+
const bounds = {
|
|
32648
|
+
minX: boardCenterX - boardWidth / 2,
|
|
32649
|
+
maxX: boardCenterX + boardWidth / 2,
|
|
32650
|
+
minY: boardCenterY - boardHeight / 2,
|
|
32651
|
+
maxY: boardCenterY + boardHeight / 2
|
|
32652
|
+
};
|
|
32653
|
+
return {
|
|
32654
|
+
...bounds,
|
|
32655
|
+
width: boardWidth,
|
|
32656
|
+
height: boardHeight,
|
|
32657
|
+
centerX: boardCenterX,
|
|
32658
|
+
centerY: boardCenterY
|
|
32659
|
+
};
|
|
32660
|
+
}
|
|
32661
|
+
|
|
32662
|
+
// src/utils/soldermask-texture.ts
|
|
32610
32663
|
function createSoldermaskTextureForLayer({
|
|
32611
32664
|
layer,
|
|
32612
32665
|
circuitJson,
|
|
@@ -32614,9 +32667,14 @@ function createSoldermaskTextureForLayer({
|
|
|
32614
32667
|
soldermaskColor,
|
|
32615
32668
|
traceTextureResolution
|
|
32616
32669
|
}) {
|
|
32670
|
+
const boardOutlineBounds = calculateOutlineBounds(boardData);
|
|
32617
32671
|
const canvas = document.createElement("canvas");
|
|
32618
|
-
const canvasWidth = Math.floor(
|
|
32619
|
-
|
|
32672
|
+
const canvasWidth = Math.floor(
|
|
32673
|
+
boardOutlineBounds.width * traceTextureResolution
|
|
32674
|
+
);
|
|
32675
|
+
const canvasHeight = Math.floor(
|
|
32676
|
+
boardOutlineBounds.height * traceTextureResolution
|
|
32677
|
+
);
|
|
32620
32678
|
canvas.width = canvasWidth;
|
|
32621
32679
|
canvas.height = canvasHeight;
|
|
32622
32680
|
const ctx = canvas.getContext("2d");
|
|
@@ -32625,8 +32683,8 @@ function createSoldermaskTextureForLayer({
|
|
|
32625
32683
|
ctx.translate(0, canvasHeight);
|
|
32626
32684
|
ctx.scale(1, -1);
|
|
32627
32685
|
}
|
|
32628
|
-
const canvasXFromPcb = (pcbX) => (pcbX -
|
|
32629
|
-
const canvasYFromPcb = (pcbY) => (
|
|
32686
|
+
const canvasXFromPcb = (pcbX) => (pcbX - boardOutlineBounds.minX) * traceTextureResolution;
|
|
32687
|
+
const canvasYFromPcb = (pcbY) => (boardOutlineBounds.maxY - pcbY) * traceTextureResolution;
|
|
32630
32688
|
ctx.fillStyle = soldermaskColor;
|
|
32631
32689
|
if (boardData.outline && boardData.outline.length >= 3) {
|
|
32632
32690
|
ctx.beginPath();
|
|
@@ -33409,9 +33467,14 @@ function createSilkscreenTextureForLayer({
|
|
|
33409
33467
|
if (textsOnLayer.length === 0 && pathsOnLayer.length === 0 && linesOnLayer.length === 0 && rectsOnLayer.length === 0 && circlesOnLayer.length === 0 && fabricationNoteRectsOnLayer.length === 0 && noteLinesOnLayer.length === 0) {
|
|
33410
33468
|
return null;
|
|
33411
33469
|
}
|
|
33470
|
+
const boardOutlineBounds = calculateOutlineBounds(boardData);
|
|
33412
33471
|
const canvas = document.createElement("canvas");
|
|
33413
|
-
const canvasWidth = Math.floor(
|
|
33414
|
-
|
|
33472
|
+
const canvasWidth = Math.floor(
|
|
33473
|
+
boardOutlineBounds.width * traceTextureResolution
|
|
33474
|
+
);
|
|
33475
|
+
const canvasHeight = Math.floor(
|
|
33476
|
+
boardOutlineBounds.height * traceTextureResolution
|
|
33477
|
+
);
|
|
33415
33478
|
canvas.width = canvasWidth;
|
|
33416
33479
|
canvas.height = canvasHeight;
|
|
33417
33480
|
const ctx = canvas.getContext("2d");
|
|
@@ -33422,8 +33485,8 @@ function createSilkscreenTextureForLayer({
|
|
|
33422
33485
|
}
|
|
33423
33486
|
ctx.strokeStyle = silkscreenColor;
|
|
33424
33487
|
ctx.fillStyle = silkscreenColor;
|
|
33425
|
-
const canvasXFromPcb = (pcbX) => (pcbX -
|
|
33426
|
-
const canvasYFromPcb = (pcbY) => (
|
|
33488
|
+
const canvasXFromPcb = (pcbX) => (pcbX - boardOutlineBounds.minX) * traceTextureResolution;
|
|
33489
|
+
const canvasYFromPcb = (pcbY) => (boardOutlineBounds.maxY - pcbY) * traceTextureResolution;
|
|
33427
33490
|
linesOnLayer.forEach((lineEl) => {
|
|
33428
33491
|
const startXmm = parseDimensionToMm(lineEl.x1) ?? 0;
|
|
33429
33492
|
const startYmm = parseDimensionToMm(lineEl.y1) ?? 0;
|
|
@@ -33789,9 +33852,14 @@ function createTraceTextureForLayer({
|
|
|
33789
33852
|
(t) => t.route.some((p) => isWireRoutePoint(p) && p.layer === layer)
|
|
33790
33853
|
);
|
|
33791
33854
|
if (tracesOnLayer.length === 0) return null;
|
|
33855
|
+
const boardOutlineBounds = calculateOutlineBounds(boardData);
|
|
33792
33856
|
const canvas = document.createElement("canvas");
|
|
33793
|
-
const canvasWidth = Math.floor(
|
|
33794
|
-
|
|
33857
|
+
const canvasWidth = Math.floor(
|
|
33858
|
+
boardOutlineBounds.width * traceTextureResolution
|
|
33859
|
+
);
|
|
33860
|
+
const canvasHeight = Math.floor(
|
|
33861
|
+
boardOutlineBounds.height * traceTextureResolution
|
|
33862
|
+
);
|
|
33795
33863
|
canvas.width = canvasWidth;
|
|
33796
33864
|
canvas.height = canvasHeight;
|
|
33797
33865
|
const ctx = canvas.getContext("2d");
|
|
@@ -33817,8 +33885,8 @@ function createTraceTextureForLayer({
|
|
|
33817
33885
|
const pcbY = point2.y;
|
|
33818
33886
|
currentLineWidth = point2.width * traceTextureResolution;
|
|
33819
33887
|
ctx.lineWidth = currentLineWidth;
|
|
33820
|
-
const canvasX = (pcbX -
|
|
33821
|
-
const canvasY = (
|
|
33888
|
+
const canvasX = (pcbX - boardOutlineBounds.minX) * traceTextureResolution;
|
|
33889
|
+
const canvasY = (boardOutlineBounds.maxY - pcbY) * traceTextureResolution;
|
|
33822
33890
|
if (firstPoint) {
|
|
33823
33891
|
ctx.moveTo(canvasX, canvasY);
|
|
33824
33892
|
firstPoint = false;
|
|
@@ -33833,8 +33901,8 @@ function createTraceTextureForLayer({
|
|
|
33833
33901
|
ctx.globalCompositeOperation = "destination-out";
|
|
33834
33902
|
ctx.fillStyle = "black";
|
|
33835
33903
|
allPcbVias.forEach((via) => {
|
|
33836
|
-
const canvasX = (via.x -
|
|
33837
|
-
const canvasY = (
|
|
33904
|
+
const canvasX = (via.x - boardOutlineBounds.minX) * traceTextureResolution;
|
|
33905
|
+
const canvasY = (boardOutlineBounds.maxY - via.y) * traceTextureResolution;
|
|
33838
33906
|
const canvasRadius = via.outer_diameter / 2 * traceTextureResolution;
|
|
33839
33907
|
ctx.beginPath();
|
|
33840
33908
|
ctx.arc(canvasX, canvasY, canvasRadius, 0, 2 * Math.PI, false);
|
|
@@ -33842,8 +33910,8 @@ function createTraceTextureForLayer({
|
|
|
33842
33910
|
});
|
|
33843
33911
|
allPcbPlatedHoles.forEach((ph) => {
|
|
33844
33912
|
if (ph.layers.includes(layer) && ph.shape === "circle") {
|
|
33845
|
-
const canvasX = (ph.x -
|
|
33846
|
-
const canvasY = (
|
|
33913
|
+
const canvasX = (ph.x - boardOutlineBounds.minX) * traceTextureResolution;
|
|
33914
|
+
const canvasY = (boardOutlineBounds.maxY - ph.y) * traceTextureResolution;
|
|
33847
33915
|
const canvasRadius = ph.outer_diameter / 2 * traceTextureResolution;
|
|
33848
33916
|
ctx.beginPath();
|
|
33849
33917
|
ctx.arc(canvasX, canvasY, canvasRadius, 0, 2 * Math.PI, false);
|
|
@@ -34038,9 +34106,14 @@ function createCopperTextTextureForLayer({
|
|
|
34038
34106
|
if (textsOnLayer.length === 0) {
|
|
34039
34107
|
return null;
|
|
34040
34108
|
}
|
|
34109
|
+
const boardOutlineBounds = calculateOutlineBounds(boardData);
|
|
34041
34110
|
const canvas = document.createElement("canvas");
|
|
34042
|
-
const canvasWidth = Math.floor(
|
|
34043
|
-
|
|
34111
|
+
const canvasWidth = Math.floor(
|
|
34112
|
+
boardOutlineBounds.width * traceTextureResolution
|
|
34113
|
+
);
|
|
34114
|
+
const canvasHeight = Math.floor(
|
|
34115
|
+
boardOutlineBounds.height * traceTextureResolution
|
|
34116
|
+
);
|
|
34044
34117
|
canvas.width = canvasWidth;
|
|
34045
34118
|
canvas.height = canvasHeight;
|
|
34046
34119
|
const ctx = canvas.getContext("2d");
|
|
@@ -34051,8 +34124,8 @@ function createCopperTextTextureForLayer({
|
|
|
34051
34124
|
}
|
|
34052
34125
|
ctx.strokeStyle = copperColor;
|
|
34053
34126
|
ctx.fillStyle = copperColor;
|
|
34054
|
-
const canvasXFromPcb = (pcbX) => (pcbX -
|
|
34055
|
-
const canvasYFromPcb = (pcbY) => (
|
|
34127
|
+
const canvasXFromPcb = (pcbX) => (pcbX - boardOutlineBounds.minX) * traceTextureResolution;
|
|
34128
|
+
const canvasYFromPcb = (pcbY) => (boardOutlineBounds.maxY - pcbY) * traceTextureResolution;
|
|
34056
34129
|
textsOnLayer.forEach((textS) => {
|
|
34057
34130
|
const fontSize = typeof textS.font_size === "number" ? textS.font_size : 0.2;
|
|
34058
34131
|
const textStrokeWidth = Math.max(0.02, fontSize * 0.08) * traceTextureResolution;
|
|
@@ -34285,11 +34358,12 @@ function JscadBoardTextures({
|
|
|
34285
34358
|
useEffect22(() => {
|
|
34286
34359
|
if (!rootObject || !boardData || !textures) return;
|
|
34287
34360
|
const meshes = [];
|
|
34288
|
-
const
|
|
34361
|
+
const createTexturePlane2 = (texture, zOffset, isBottomLayer, name, usePolygonOffset = false, depthWrite = false) => {
|
|
34289
34362
|
if (!texture) return null;
|
|
34363
|
+
const boardOutlineBounds = calculateOutlineBounds(boardData);
|
|
34290
34364
|
const planeGeom = new THREE23.PlaneGeometry(
|
|
34291
|
-
|
|
34292
|
-
|
|
34365
|
+
boardOutlineBounds.width,
|
|
34366
|
+
boardOutlineBounds.height
|
|
34293
34367
|
);
|
|
34294
34368
|
const material = new THREE23.MeshBasicMaterial({
|
|
34295
34369
|
map: texture,
|
|
@@ -34301,7 +34375,11 @@ function JscadBoardTextures({
|
|
|
34301
34375
|
polygonOffsetUnits: usePolygonOffset ? -1 : 0
|
|
34302
34376
|
});
|
|
34303
34377
|
const mesh = new THREE23.Mesh(planeGeom, material);
|
|
34304
|
-
mesh.position.set(
|
|
34378
|
+
mesh.position.set(
|
|
34379
|
+
boardOutlineBounds.centerX,
|
|
34380
|
+
boardOutlineBounds.centerY,
|
|
34381
|
+
zOffset
|
|
34382
|
+
);
|
|
34305
34383
|
if (isBottomLayer) {
|
|
34306
34384
|
mesh.rotation.set(Math.PI, 0, 0);
|
|
34307
34385
|
}
|
|
@@ -34310,7 +34388,7 @@ function JscadBoardTextures({
|
|
|
34310
34388
|
};
|
|
34311
34389
|
const SURFACE_OFFSET = 1e-3;
|
|
34312
34390
|
if (visibility.topMask) {
|
|
34313
|
-
const topSoldermaskMesh =
|
|
34391
|
+
const topSoldermaskMesh = createTexturePlane2(
|
|
34314
34392
|
textures.topSoldermask,
|
|
34315
34393
|
pcbThickness / 2 + SURFACE_OFFSET,
|
|
34316
34394
|
false,
|
|
@@ -34323,7 +34401,7 @@ function JscadBoardTextures({
|
|
|
34323
34401
|
}
|
|
34324
34402
|
}
|
|
34325
34403
|
if (visibility.bottomMask) {
|
|
34326
|
-
const bottomSoldermaskMesh =
|
|
34404
|
+
const bottomSoldermaskMesh = createTexturePlane2(
|
|
34327
34405
|
textures.bottomSoldermask,
|
|
34328
34406
|
-pcbThickness / 2 - SURFACE_OFFSET,
|
|
34329
34407
|
true,
|
|
@@ -34336,7 +34414,7 @@ function JscadBoardTextures({
|
|
|
34336
34414
|
}
|
|
34337
34415
|
}
|
|
34338
34416
|
if (visibility.topCopper && visibility.topMask) {
|
|
34339
|
-
const topTraceWithMaskMesh =
|
|
34417
|
+
const topTraceWithMaskMesh = createTexturePlane2(
|
|
34340
34418
|
textures.topTraceWithMask,
|
|
34341
34419
|
pcbThickness / 2 + BOARD_SURFACE_OFFSET.traces + 4e-3,
|
|
34342
34420
|
false,
|
|
@@ -34348,7 +34426,7 @@ function JscadBoardTextures({
|
|
|
34348
34426
|
}
|
|
34349
34427
|
}
|
|
34350
34428
|
if (visibility.bottomCopper && visibility.bottomMask) {
|
|
34351
|
-
const bottomTraceWithMaskMesh =
|
|
34429
|
+
const bottomTraceWithMaskMesh = createTexturePlane2(
|
|
34352
34430
|
textures.bottomTraceWithMask,
|
|
34353
34431
|
-pcbThickness / 2 - BOARD_SURFACE_OFFSET.traces - 5e-3,
|
|
34354
34432
|
true,
|
|
@@ -34360,7 +34438,7 @@ function JscadBoardTextures({
|
|
|
34360
34438
|
}
|
|
34361
34439
|
}
|
|
34362
34440
|
if (visibility.topSilkscreen) {
|
|
34363
|
-
const topSilkscreenMesh =
|
|
34441
|
+
const topSilkscreenMesh = createTexturePlane2(
|
|
34364
34442
|
textures.topSilkscreen,
|
|
34365
34443
|
pcbThickness / 2 + SURFACE_OFFSET + 2e-3,
|
|
34366
34444
|
false,
|
|
@@ -34372,7 +34450,7 @@ function JscadBoardTextures({
|
|
|
34372
34450
|
}
|
|
34373
34451
|
}
|
|
34374
34452
|
if (visibility.bottomSilkscreen) {
|
|
34375
|
-
const bottomSilkscreenMesh =
|
|
34453
|
+
const bottomSilkscreenMesh = createTexturePlane2(
|
|
34376
34454
|
textures.bottomSilkscreen,
|
|
34377
34455
|
-pcbThickness / 2 - SURFACE_OFFSET - 2e-3,
|
|
34378
34456
|
true,
|
|
@@ -34384,7 +34462,7 @@ function JscadBoardTextures({
|
|
|
34384
34462
|
}
|
|
34385
34463
|
}
|
|
34386
34464
|
if (visibility.topCopper) {
|
|
34387
|
-
const topCopperTextMesh =
|
|
34465
|
+
const topCopperTextMesh = createTexturePlane2(
|
|
34388
34466
|
textures.topCopperText,
|
|
34389
34467
|
pcbThickness / 2 + BOARD_SURFACE_OFFSET.copper,
|
|
34390
34468
|
false,
|
|
@@ -34396,7 +34474,7 @@ function JscadBoardTextures({
|
|
|
34396
34474
|
}
|
|
34397
34475
|
}
|
|
34398
34476
|
if (visibility.bottomCopper) {
|
|
34399
|
-
const bottomCopperTextMesh =
|
|
34477
|
+
const bottomCopperTextMesh = createTexturePlane2(
|
|
34400
34478
|
textures.bottomCopperText,
|
|
34401
34479
|
-pcbThickness / 2 - BOARD_SURFACE_OFFSET.copper,
|
|
34402
34480
|
true,
|
|
@@ -34408,7 +34486,7 @@ function JscadBoardTextures({
|
|
|
34408
34486
|
}
|
|
34409
34487
|
}
|
|
34410
34488
|
if (visibility.boardBody) {
|
|
34411
|
-
const topPanelOutlinesMesh =
|
|
34489
|
+
const topPanelOutlinesMesh = createTexturePlane2(
|
|
34412
34490
|
textures.topPanelOutlines,
|
|
34413
34491
|
pcbThickness / 2 + SURFACE_OFFSET + 3e-3,
|
|
34414
34492
|
// Above silkscreen
|
|
@@ -34421,7 +34499,7 @@ function JscadBoardTextures({
|
|
|
34421
34499
|
meshes.push(topPanelOutlinesMesh);
|
|
34422
34500
|
rootObject.add(topPanelOutlinesMesh);
|
|
34423
34501
|
}
|
|
34424
|
-
const bottomPanelOutlinesMesh =
|
|
34502
|
+
const bottomPanelOutlinesMesh = createTexturePlane2(
|
|
34425
34503
|
textures.bottomPanelOutlines,
|
|
34426
34504
|
-pcbThickness / 2 - SURFACE_OFFSET - 3e-3,
|
|
34427
34505
|
// Below bottom silkscreen
|
|
@@ -34673,7 +34751,7 @@ import { useEffect as useEffect24, useMemo as useMemo22, useState as useState15
|
|
|
34673
34751
|
// src/hooks/useManifoldBoardBuilder.ts
|
|
34674
34752
|
import { useState as useState14, useEffect as useEffect23, useMemo as useMemo21, useRef as useRef9 } from "react";
|
|
34675
34753
|
import { su as su18 } from "@tscircuit/circuit-json-util";
|
|
34676
|
-
import * as
|
|
34754
|
+
import * as THREE30 from "three";
|
|
34677
34755
|
|
|
34678
34756
|
// src/utils/manifold/create-manifold-board.ts
|
|
34679
34757
|
var arePointsClockwise3 = (points) => {
|
|
@@ -34733,202 +34811,6 @@ function createManifoldBoard(Manifold, CrossSection, boardData, pcbThickness, ma
|
|
|
34733
34811
|
return { boardOp, outlineCrossSection };
|
|
34734
34812
|
}
|
|
34735
34813
|
|
|
34736
|
-
// src/utils/manifold/process-copper-pours.ts
|
|
34737
|
-
import * as THREE25 from "three";
|
|
34738
|
-
|
|
34739
|
-
// src/utils/manifold-mesh-to-three-geometry.ts
|
|
34740
|
-
import * as THREE24 from "three";
|
|
34741
|
-
function manifoldMeshToThreeGeometry(manifoldMesh) {
|
|
34742
|
-
const geometry = new THREE24.BufferGeometry();
|
|
34743
|
-
geometry.setAttribute(
|
|
34744
|
-
"position",
|
|
34745
|
-
new THREE24.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
|
|
34746
|
-
);
|
|
34747
|
-
geometry.setIndex(new THREE24.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
|
|
34748
|
-
if (manifoldMesh.runIndex && manifoldMesh.runIndex.length > 1 && manifoldMesh.runOriginalID) {
|
|
34749
|
-
for (let i = 0; i < manifoldMesh.runIndex.length - 1; i++) {
|
|
34750
|
-
const start = manifoldMesh.runIndex[i];
|
|
34751
|
-
const count3 = manifoldMesh.runIndex[i + 1] - start;
|
|
34752
|
-
geometry.addGroup(start, count3, 0);
|
|
34753
|
-
}
|
|
34754
|
-
} else {
|
|
34755
|
-
geometry.addGroup(0, manifoldMesh.triVerts.length, 0);
|
|
34756
|
-
}
|
|
34757
|
-
return geometry;
|
|
34758
|
-
}
|
|
34759
|
-
|
|
34760
|
-
// src/utils/manifold/process-copper-pours.ts
|
|
34761
|
-
var arePointsClockwise4 = (points) => {
|
|
34762
|
-
let area = 0;
|
|
34763
|
-
for (let i = 0; i < points.length; i++) {
|
|
34764
|
-
const j = (i + 1) % points.length;
|
|
34765
|
-
if (points[i] && points[j]) {
|
|
34766
|
-
area += points[i][0] * points[j][1];
|
|
34767
|
-
area -= points[j][0] * points[i][1];
|
|
34768
|
-
}
|
|
34769
|
-
}
|
|
34770
|
-
const signedArea = area / 2;
|
|
34771
|
-
return signedArea <= 0;
|
|
34772
|
-
};
|
|
34773
|
-
function segmentToPoints2(p1, p2, bulge, arcSegments) {
|
|
34774
|
-
if (!bulge || Math.abs(bulge) < 1e-9) {
|
|
34775
|
-
return [];
|
|
34776
|
-
}
|
|
34777
|
-
const theta = 4 * Math.atan(bulge);
|
|
34778
|
-
const dx = p2[0] - p1[0];
|
|
34779
|
-
const dy = p2[1] - p1[1];
|
|
34780
|
-
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
34781
|
-
if (dist < 1e-9) return [];
|
|
34782
|
-
const radius = Math.abs(dist / (2 * Math.sin(theta / 2)));
|
|
34783
|
-
const m = Math.sqrt(Math.max(0, radius * radius - dist / 2 * (dist / 2)));
|
|
34784
|
-
const midPoint = [(p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2];
|
|
34785
|
-
const ux = dx / dist;
|
|
34786
|
-
const uy = dy / dist;
|
|
34787
|
-
const nx = -uy;
|
|
34788
|
-
const ny = ux;
|
|
34789
|
-
const centerX = midPoint[0] + nx * m * Math.sign(bulge);
|
|
34790
|
-
const centerY = midPoint[1] + ny * m * Math.sign(bulge);
|
|
34791
|
-
const startAngle = Math.atan2(p1[1] - centerY, p1[0] - centerX);
|
|
34792
|
-
const points = [];
|
|
34793
|
-
const numSteps = Math.max(
|
|
34794
|
-
2,
|
|
34795
|
-
Math.ceil(arcSegments * Math.abs(theta) / (Math.PI * 2) * 4)
|
|
34796
|
-
);
|
|
34797
|
-
const angleStep = theta / numSteps;
|
|
34798
|
-
for (let i = 1; i < numSteps; i++) {
|
|
34799
|
-
const angle = startAngle + angleStep * i;
|
|
34800
|
-
points.push([
|
|
34801
|
-
centerX + radius * Math.cos(angle),
|
|
34802
|
-
centerY + radius * Math.sin(angle)
|
|
34803
|
-
]);
|
|
34804
|
-
}
|
|
34805
|
-
return points;
|
|
34806
|
-
}
|
|
34807
|
-
function ringToPoints2(ring2, arcSegments) {
|
|
34808
|
-
const allPoints = [];
|
|
34809
|
-
const vertices = ring2.vertices;
|
|
34810
|
-
for (let i = 0; i < vertices.length; i++) {
|
|
34811
|
-
const p1 = vertices[i];
|
|
34812
|
-
const p2 = vertices[(i + 1) % vertices.length];
|
|
34813
|
-
allPoints.push([p1.x, p1.y]);
|
|
34814
|
-
if (p1.bulge) {
|
|
34815
|
-
const arcPoints = segmentToPoints2(
|
|
34816
|
-
[p1.x, p1.y],
|
|
34817
|
-
[p2.x, p2.y],
|
|
34818
|
-
p1.bulge,
|
|
34819
|
-
arcSegments
|
|
34820
|
-
);
|
|
34821
|
-
allPoints.push(...arcPoints);
|
|
34822
|
-
}
|
|
34823
|
-
}
|
|
34824
|
-
return allPoints;
|
|
34825
|
-
}
|
|
34826
|
-
function processCopperPoursForManifold(Manifold, CrossSection, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardMaterial, holeUnion, boardClipVolume) {
|
|
34827
|
-
const copperPourGeoms = [];
|
|
34828
|
-
const copperPours = circuitJson.filter(
|
|
34829
|
-
(e) => e.type === "pcb_copper_pour"
|
|
34830
|
-
);
|
|
34831
|
-
for (const pour of copperPours) {
|
|
34832
|
-
const pourThickness = DEFAULT_SMT_PAD_THICKNESS;
|
|
34833
|
-
const layerSign = pour.layer === "bottom" ? -1 : 1;
|
|
34834
|
-
const zPos = layerSign * (pcbThickness / 2 + pourThickness / 2 + MANIFOLD_Z_OFFSET);
|
|
34835
|
-
let pourOp;
|
|
34836
|
-
if (pour.shape === "rect") {
|
|
34837
|
-
pourOp = Manifold.cube([pour.width, pour.height, pourThickness], true);
|
|
34838
|
-
manifoldInstancesForCleanup.push(pourOp);
|
|
34839
|
-
if (pour.rotation) {
|
|
34840
|
-
const rotatedOp = pourOp.rotate([0, 0, pour.rotation]);
|
|
34841
|
-
manifoldInstancesForCleanup.push(rotatedOp);
|
|
34842
|
-
pourOp = rotatedOp;
|
|
34843
|
-
}
|
|
34844
|
-
pourOp = pourOp.translate([pour.center.x, pour.center.y, zPos]);
|
|
34845
|
-
manifoldInstancesForCleanup.push(pourOp);
|
|
34846
|
-
} else if (pour.shape === "polygon") {
|
|
34847
|
-
if (pour.points.length < 3) continue;
|
|
34848
|
-
let pointsVec2 = pour.points.map((p) => [
|
|
34849
|
-
p.x,
|
|
34850
|
-
p.y
|
|
34851
|
-
]);
|
|
34852
|
-
if (arePointsClockwise4(pointsVec2)) {
|
|
34853
|
-
pointsVec2 = pointsVec2.reverse();
|
|
34854
|
-
}
|
|
34855
|
-
const crossSection = CrossSection.ofPolygons([pointsVec2]);
|
|
34856
|
-
manifoldInstancesForCleanup.push(crossSection);
|
|
34857
|
-
pourOp = Manifold.extrude(
|
|
34858
|
-
crossSection,
|
|
34859
|
-
pourThickness,
|
|
34860
|
-
0,
|
|
34861
|
-
// nDivisions
|
|
34862
|
-
0,
|
|
34863
|
-
// twistDegrees
|
|
34864
|
-
[1, 1],
|
|
34865
|
-
// scaleTop
|
|
34866
|
-
true
|
|
34867
|
-
// center extrusion
|
|
34868
|
-
).translate([0, 0, zPos]);
|
|
34869
|
-
manifoldInstancesForCleanup.push(pourOp);
|
|
34870
|
-
} else if (pour.shape === "brep") {
|
|
34871
|
-
const brepShape = pour.brep_shape;
|
|
34872
|
-
if (!brepShape || !brepShape.outer_ring) continue;
|
|
34873
|
-
let outerRingPoints = ringToPoints2(
|
|
34874
|
-
brepShape.outer_ring,
|
|
34875
|
-
SMOOTH_CIRCLE_SEGMENTS
|
|
34876
|
-
);
|
|
34877
|
-
if (arePointsClockwise4(outerRingPoints)) {
|
|
34878
|
-
outerRingPoints = outerRingPoints.reverse();
|
|
34879
|
-
}
|
|
34880
|
-
const polygons = [outerRingPoints];
|
|
34881
|
-
if (brepShape.inner_rings) {
|
|
34882
|
-
const innerRingsPoints = brepShape.inner_rings.map((ring2) => {
|
|
34883
|
-
let points = ringToPoints2(ring2, SMOOTH_CIRCLE_SEGMENTS);
|
|
34884
|
-
if (!arePointsClockwise4(points)) {
|
|
34885
|
-
points = points.reverse();
|
|
34886
|
-
}
|
|
34887
|
-
return points;
|
|
34888
|
-
});
|
|
34889
|
-
polygons.push(...innerRingsPoints);
|
|
34890
|
-
}
|
|
34891
|
-
const crossSection = CrossSection.ofPolygons(polygons);
|
|
34892
|
-
manifoldInstancesForCleanup.push(crossSection);
|
|
34893
|
-
pourOp = Manifold.extrude(
|
|
34894
|
-
crossSection,
|
|
34895
|
-
pourThickness,
|
|
34896
|
-
0,
|
|
34897
|
-
// nDivisions
|
|
34898
|
-
0,
|
|
34899
|
-
// twistDegrees
|
|
34900
|
-
[1, 1],
|
|
34901
|
-
// scaleTop
|
|
34902
|
-
true
|
|
34903
|
-
// center extrusion
|
|
34904
|
-
).translate([0, 0, zPos]);
|
|
34905
|
-
manifoldInstancesForCleanup.push(pourOp);
|
|
34906
|
-
}
|
|
34907
|
-
if (pourOp) {
|
|
34908
|
-
if (holeUnion) {
|
|
34909
|
-
const withHoles = pourOp.subtract(holeUnion);
|
|
34910
|
-
manifoldInstancesForCleanup.push(withHoles);
|
|
34911
|
-
pourOp = withHoles;
|
|
34912
|
-
}
|
|
34913
|
-
if (boardClipVolume) {
|
|
34914
|
-
const clipped = Manifold.intersection([pourOp, boardClipVolume]);
|
|
34915
|
-
manifoldInstancesForCleanup.push(clipped);
|
|
34916
|
-
pourOp = clipped;
|
|
34917
|
-
}
|
|
34918
|
-
const covered = pour.covered_with_solder_mask !== false;
|
|
34919
|
-
const pourColorArr = covered ? tracesMaterialColors[boardMaterial] ?? colors.fr4TracesWithoutMaskTan : colors.copper;
|
|
34920
|
-
const pourColor = new THREE25.Color(...pourColorArr);
|
|
34921
|
-
const threeGeom = manifoldMeshToThreeGeometry(pourOp.getMesh());
|
|
34922
|
-
copperPourGeoms.push({
|
|
34923
|
-
key: `coppour-${pour.pcb_copper_pour_id}`,
|
|
34924
|
-
geometry: threeGeom,
|
|
34925
|
-
color: pourColor
|
|
34926
|
-
});
|
|
34927
|
-
}
|
|
34928
|
-
}
|
|
34929
|
-
return { copperPourGeoms };
|
|
34930
|
-
}
|
|
34931
|
-
|
|
34932
34814
|
// src/utils/manifold/process-cutouts.ts
|
|
34933
34815
|
import { su as su13 } from "@tscircuit/circuit-json-util";
|
|
34934
34816
|
|
|
@@ -35008,7 +34890,7 @@ function createPadManifoldOp({
|
|
|
35008
34890
|
}
|
|
35009
34891
|
|
|
35010
34892
|
// src/utils/manifold/process-cutouts.ts
|
|
35011
|
-
var
|
|
34893
|
+
var arePointsClockwise4 = (points) => {
|
|
35012
34894
|
let area = 0;
|
|
35013
34895
|
for (let i = 0; i < points.length; i++) {
|
|
35014
34896
|
const j = (i + 1) % points.length;
|
|
@@ -35084,7 +34966,7 @@ function processCutoutsForManifold(Manifold, CrossSection, circuitJson, pcbThick
|
|
|
35084
34966
|
p.x,
|
|
35085
34967
|
p.y
|
|
35086
34968
|
]);
|
|
35087
|
-
if (
|
|
34969
|
+
if (arePointsClockwise4(pointsVec2)) {
|
|
35088
34970
|
pointsVec2 = pointsVec2.reverse();
|
|
35089
34971
|
}
|
|
35090
34972
|
const crossSection = CrossSection.ofPolygons([pointsVec2]);
|
|
@@ -35219,8 +35101,31 @@ function processNonPlatedHolesForManifold(Manifold, circuitJson, pcbThickness, m
|
|
|
35219
35101
|
|
|
35220
35102
|
// src/utils/manifold/process-plated-holes.ts
|
|
35221
35103
|
import { su as su15 } from "@tscircuit/circuit-json-util";
|
|
35222
|
-
import * as
|
|
35223
|
-
|
|
35104
|
+
import * as THREE25 from "three";
|
|
35105
|
+
|
|
35106
|
+
// src/utils/manifold-mesh-to-three-geometry.ts
|
|
35107
|
+
import * as THREE24 from "three";
|
|
35108
|
+
function manifoldMeshToThreeGeometry(manifoldMesh) {
|
|
35109
|
+
const geometry = new THREE24.BufferGeometry();
|
|
35110
|
+
geometry.setAttribute(
|
|
35111
|
+
"position",
|
|
35112
|
+
new THREE24.Float32BufferAttribute(manifoldMesh.vertProperties, 3)
|
|
35113
|
+
);
|
|
35114
|
+
geometry.setIndex(new THREE24.Uint32BufferAttribute(manifoldMesh.triVerts, 1));
|
|
35115
|
+
if (manifoldMesh.runIndex && manifoldMesh.runIndex.length > 1 && manifoldMesh.runOriginalID) {
|
|
35116
|
+
for (let i = 0; i < manifoldMesh.runIndex.length - 1; i++) {
|
|
35117
|
+
const start = manifoldMesh.runIndex[i];
|
|
35118
|
+
const count3 = manifoldMesh.runIndex[i + 1] - start;
|
|
35119
|
+
geometry.addGroup(start, count3, 0);
|
|
35120
|
+
}
|
|
35121
|
+
} else {
|
|
35122
|
+
geometry.addGroup(0, manifoldMesh.triVerts.length, 0);
|
|
35123
|
+
}
|
|
35124
|
+
return geometry;
|
|
35125
|
+
}
|
|
35126
|
+
|
|
35127
|
+
// src/utils/manifold/process-plated-holes.ts
|
|
35128
|
+
var arePointsClockwise5 = (points) => {
|
|
35224
35129
|
let area = 0;
|
|
35225
35130
|
for (let i = 0; i < points.length; i++) {
|
|
35226
35131
|
const j = (i + 1) % points.length;
|
|
@@ -35240,7 +35145,7 @@ var createEllipsePoints = (width10, height10, segments) => {
|
|
|
35240
35145
|
}
|
|
35241
35146
|
return points;
|
|
35242
35147
|
};
|
|
35243
|
-
var COPPER_COLOR = new
|
|
35148
|
+
var COPPER_COLOR = new THREE25.Color(...colors.copper);
|
|
35244
35149
|
var PLATED_HOLE_LIP_HEIGHT = 0.05;
|
|
35245
35150
|
function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume) {
|
|
35246
35151
|
const platedHoleBoardDrills = [];
|
|
@@ -35267,7 +35172,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
35267
35172
|
point2.x,
|
|
35268
35173
|
point2.y
|
|
35269
35174
|
]);
|
|
35270
|
-
if (
|
|
35175
|
+
if (arePointsClockwise5(points)) {
|
|
35271
35176
|
points = points.reverse();
|
|
35272
35177
|
}
|
|
35273
35178
|
const crossSection = CrossSection.ofPolygons([points]);
|
|
@@ -35312,7 +35217,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
35312
35217
|
const height10 = Math.max(baseHeight + sizeDelta, M);
|
|
35313
35218
|
if (holeShape === "oval") {
|
|
35314
35219
|
let points = createEllipsePoints(width10, height10, SMOOTH_CIRCLE_SEGMENTS);
|
|
35315
|
-
if (
|
|
35220
|
+
if (arePointsClockwise5(points)) {
|
|
35316
35221
|
points = points.reverse();
|
|
35317
35222
|
}
|
|
35318
35223
|
const crossSection = CrossSection.ofPolygons([points]);
|
|
@@ -35627,7 +35532,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
35627
35532
|
drillH,
|
|
35628
35533
|
SMOOTH_CIRCLE_SEGMENTS
|
|
35629
35534
|
);
|
|
35630
|
-
if (
|
|
35535
|
+
if (arePointsClockwise5(boardDrillPoints)) {
|
|
35631
35536
|
boardDrillPoints = boardDrillPoints.reverse();
|
|
35632
35537
|
}
|
|
35633
35538
|
const boardDrillCrossSection = CrossSection.ofPolygons([boardDrillPoints]);
|
|
@@ -35655,7 +35560,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
35655
35560
|
outerH,
|
|
35656
35561
|
SMOOTH_CIRCLE_SEGMENTS
|
|
35657
35562
|
);
|
|
35658
|
-
if (
|
|
35563
|
+
if (arePointsClockwise5(outerPoints)) {
|
|
35659
35564
|
outerPoints = outerPoints.reverse();
|
|
35660
35565
|
}
|
|
35661
35566
|
const outerCrossSection = CrossSection.ofPolygons([outerPoints]);
|
|
@@ -35674,7 +35579,7 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
35674
35579
|
holeH,
|
|
35675
35580
|
SMOOTH_CIRCLE_SEGMENTS
|
|
35676
35581
|
);
|
|
35677
|
-
if (
|
|
35582
|
+
if (arePointsClockwise5(innerPoints)) {
|
|
35678
35583
|
innerPoints = innerPoints.reverse();
|
|
35679
35584
|
}
|
|
35680
35585
|
const innerCrossSection = CrossSection.ofPolygons([innerPoints]);
|
|
@@ -35814,8 +35719,8 @@ function processPlatedHolesForManifold(Manifold, CrossSection, circuitJson, pcbT
|
|
|
35814
35719
|
|
|
35815
35720
|
// src/utils/manifold/process-smt-pads.ts
|
|
35816
35721
|
import { su as su16 } from "@tscircuit/circuit-json-util";
|
|
35817
|
-
import * as
|
|
35818
|
-
var COPPER_COLOR2 = new
|
|
35722
|
+
import * as THREE26 from "three";
|
|
35723
|
+
var COPPER_COLOR2 = new THREE26.Color(...colors.copper);
|
|
35819
35724
|
function processSmtPadsForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, holeUnion, boardClipVolume) {
|
|
35820
35725
|
const smtPadGeoms = [];
|
|
35821
35726
|
const smtPads = su16(circuitJson).pcb_smtpad.list();
|
|
@@ -35854,7 +35759,7 @@ function processSmtPadsForManifold(Manifold, circuitJson, pcbThickness, manifold
|
|
|
35854
35759
|
|
|
35855
35760
|
// src/utils/manifold/process-vias.ts
|
|
35856
35761
|
import { su as su17 } from "@tscircuit/circuit-json-util";
|
|
35857
|
-
import * as
|
|
35762
|
+
import * as THREE27 from "three";
|
|
35858
35763
|
|
|
35859
35764
|
// src/utils/via-geoms.ts
|
|
35860
35765
|
function createViaCopper2({
|
|
@@ -35907,7 +35812,7 @@ function createViaCopper2({
|
|
|
35907
35812
|
}
|
|
35908
35813
|
|
|
35909
35814
|
// src/utils/manifold/process-vias.ts
|
|
35910
|
-
var COPPER_COLOR3 = new
|
|
35815
|
+
var COPPER_COLOR3 = new THREE27.Color(...colors.copper);
|
|
35911
35816
|
function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldInstancesForCleanup, boardClipVolume) {
|
|
35912
35817
|
const viaBoardDrills = [];
|
|
35913
35818
|
const pcbVias = su17(circuitJson).pcb_via.list();
|
|
@@ -35958,6 +35863,397 @@ function processViasForManifold(Manifold, circuitJson, pcbThickness, manifoldIns
|
|
|
35958
35863
|
return { viaBoardDrills, viaCopperGeoms };
|
|
35959
35864
|
}
|
|
35960
35865
|
|
|
35866
|
+
// src/textures/create-copper-pour-texture-for-layer.ts
|
|
35867
|
+
import * as THREE28 from "three";
|
|
35868
|
+
import { CircuitToCanvasDrawer } from "circuit-to-canvas";
|
|
35869
|
+
function drawPolygon({
|
|
35870
|
+
ctx,
|
|
35871
|
+
points,
|
|
35872
|
+
canvasXFromPcb,
|
|
35873
|
+
canvasYFromPcb
|
|
35874
|
+
}) {
|
|
35875
|
+
if (points.length < 3) return;
|
|
35876
|
+
ctx.beginPath();
|
|
35877
|
+
points.forEach((point2, index2) => {
|
|
35878
|
+
const canvasX = canvasXFromPcb(point2[0]);
|
|
35879
|
+
const canvasY = canvasYFromPcb(point2[1]);
|
|
35880
|
+
if (index2 === 0) {
|
|
35881
|
+
ctx.moveTo(canvasX, canvasY);
|
|
35882
|
+
} else {
|
|
35883
|
+
ctx.lineTo(canvasX, canvasY);
|
|
35884
|
+
}
|
|
35885
|
+
});
|
|
35886
|
+
ctx.closePath();
|
|
35887
|
+
ctx.fill();
|
|
35888
|
+
}
|
|
35889
|
+
function drawBrepShape({
|
|
35890
|
+
ctx,
|
|
35891
|
+
pour,
|
|
35892
|
+
canvasXFromPcb,
|
|
35893
|
+
canvasYFromPcb
|
|
35894
|
+
}) {
|
|
35895
|
+
const brepShape = pour.brep_shape;
|
|
35896
|
+
if (!brepShape || !brepShape.outer_ring) return;
|
|
35897
|
+
const outerRingPoints = ringToPoints(brepShape.outer_ring, 32);
|
|
35898
|
+
if (outerRingPoints.length >= 3) {
|
|
35899
|
+
drawPolygon({
|
|
35900
|
+
ctx,
|
|
35901
|
+
points: outerRingPoints,
|
|
35902
|
+
canvasXFromPcb,
|
|
35903
|
+
canvasYFromPcb
|
|
35904
|
+
});
|
|
35905
|
+
}
|
|
35906
|
+
if (brepShape.inner_rings && brepShape.inner_rings.length > 0) {
|
|
35907
|
+
ctx.globalCompositeOperation = "destination-out";
|
|
35908
|
+
for (const innerRing of brepShape.inner_rings) {
|
|
35909
|
+
const innerRingPoints = ringToPoints(innerRing, 32);
|
|
35910
|
+
if (innerRingPoints.length >= 3) {
|
|
35911
|
+
drawPolygon({
|
|
35912
|
+
ctx,
|
|
35913
|
+
points: innerRingPoints,
|
|
35914
|
+
canvasXFromPcb,
|
|
35915
|
+
canvasYFromPcb
|
|
35916
|
+
});
|
|
35917
|
+
}
|
|
35918
|
+
}
|
|
35919
|
+
ctx.globalCompositeOperation = "source-over";
|
|
35920
|
+
}
|
|
35921
|
+
}
|
|
35922
|
+
function createCopperPourTextureForLayer({
|
|
35923
|
+
layer,
|
|
35924
|
+
circuitJson,
|
|
35925
|
+
boardData,
|
|
35926
|
+
traceTextureResolution = TRACE_TEXTURE_RESOLUTION
|
|
35927
|
+
}) {
|
|
35928
|
+
const copperPours = circuitJson.filter(
|
|
35929
|
+
(e) => e.type === "pcb_copper_pour"
|
|
35930
|
+
);
|
|
35931
|
+
const poursOnLayer = copperPours.filter((p) => p.layer === layer);
|
|
35932
|
+
if (poursOnLayer.length === 0) return null;
|
|
35933
|
+
const boardOutlineBounds = calculateOutlineBounds(boardData);
|
|
35934
|
+
const canvas = document.createElement("canvas");
|
|
35935
|
+
const canvasWidth = Math.floor(
|
|
35936
|
+
boardOutlineBounds.width * traceTextureResolution
|
|
35937
|
+
);
|
|
35938
|
+
const canvasHeight = Math.floor(
|
|
35939
|
+
boardOutlineBounds.height * traceTextureResolution
|
|
35940
|
+
);
|
|
35941
|
+
canvas.width = canvasWidth;
|
|
35942
|
+
canvas.height = canvasHeight;
|
|
35943
|
+
const ctx = canvas.getContext("2d");
|
|
35944
|
+
if (!ctx) return null;
|
|
35945
|
+
if (layer === "bottom") {
|
|
35946
|
+
ctx.translate(0, canvasHeight);
|
|
35947
|
+
ctx.scale(1, -1);
|
|
35948
|
+
}
|
|
35949
|
+
const canvasXFromPcb = (pcbX) => (pcbX - boardOutlineBounds.minX) * traceTextureResolution;
|
|
35950
|
+
const canvasYFromPcb = (pcbY) => (boardOutlineBounds.maxY - pcbY) * traceTextureResolution;
|
|
35951
|
+
const rectAndPolygonPours = poursOnLayer.filter(
|
|
35952
|
+
(pour) => pour.shape === "rect" || pour.shape === "polygon"
|
|
35953
|
+
);
|
|
35954
|
+
const brepPours = poursOnLayer.filter((pour) => pour.shape === "brep");
|
|
35955
|
+
if (rectAndPolygonPours.length > 0) {
|
|
35956
|
+
const drawer = new CircuitToCanvasDrawer(ctx);
|
|
35957
|
+
drawer.setCameraBounds({
|
|
35958
|
+
minX: boardOutlineBounds.minX,
|
|
35959
|
+
maxX: boardOutlineBounds.maxX,
|
|
35960
|
+
minY: boardOutlineBounds.minY,
|
|
35961
|
+
maxY: boardOutlineBounds.maxY
|
|
35962
|
+
});
|
|
35963
|
+
const coveredPours = rectAndPolygonPours.filter(
|
|
35964
|
+
(p) => p.covered_with_solder_mask !== false
|
|
35965
|
+
);
|
|
35966
|
+
const uncoveredPours = rectAndPolygonPours.filter(
|
|
35967
|
+
(p) => p.covered_with_solder_mask === false
|
|
35968
|
+
);
|
|
35969
|
+
const coveredColor = `rgb(${colors.fr4TracesWithMaskGreen.map((c) => c * 255).join(",")})`;
|
|
35970
|
+
const uncoveredColor = `rgb(${colors.copper.map((c) => c * 255).join(",")})`;
|
|
35971
|
+
if (coveredPours.length > 0) {
|
|
35972
|
+
drawer.configure({
|
|
35973
|
+
colorOverrides: {
|
|
35974
|
+
copper: {
|
|
35975
|
+
top: coveredColor,
|
|
35976
|
+
bottom: coveredColor,
|
|
35977
|
+
inner1: coveredColor,
|
|
35978
|
+
inner2: coveredColor,
|
|
35979
|
+
inner3: coveredColor,
|
|
35980
|
+
inner4: coveredColor,
|
|
35981
|
+
inner5: coveredColor,
|
|
35982
|
+
inner6: coveredColor
|
|
35983
|
+
}
|
|
35984
|
+
}
|
|
35985
|
+
});
|
|
35986
|
+
drawer.drawElements(coveredPours, { layers: [layer] });
|
|
35987
|
+
}
|
|
35988
|
+
if (uncoveredPours.length > 0) {
|
|
35989
|
+
drawer.configure({
|
|
35990
|
+
colorOverrides: {
|
|
35991
|
+
copper: {
|
|
35992
|
+
top: uncoveredColor,
|
|
35993
|
+
bottom: uncoveredColor,
|
|
35994
|
+
inner1: uncoveredColor,
|
|
35995
|
+
inner2: uncoveredColor,
|
|
35996
|
+
inner3: uncoveredColor,
|
|
35997
|
+
inner4: uncoveredColor,
|
|
35998
|
+
inner5: uncoveredColor,
|
|
35999
|
+
inner6: uncoveredColor
|
|
36000
|
+
}
|
|
36001
|
+
}
|
|
36002
|
+
});
|
|
36003
|
+
drawer.drawElements(uncoveredPours, { layers: [layer] });
|
|
36004
|
+
}
|
|
36005
|
+
}
|
|
36006
|
+
for (const pour of brepPours) {
|
|
36007
|
+
const covered = pour.covered_with_solder_mask !== false;
|
|
36008
|
+
const colorArr = covered ? colors.fr4TracesWithMaskGreen : colors.copper;
|
|
36009
|
+
const copperColor = `rgb(${colorArr[0] * 255}, ${colorArr[1] * 255}, ${colorArr[2] * 255})`;
|
|
36010
|
+
ctx.fillStyle = copperColor;
|
|
36011
|
+
drawBrepShape({ ctx, pour, canvasXFromPcb, canvasYFromPcb });
|
|
36012
|
+
}
|
|
36013
|
+
const texture = new THREE28.CanvasTexture(canvas);
|
|
36014
|
+
texture.generateMipmaps = true;
|
|
36015
|
+
texture.minFilter = THREE28.LinearMipmapLinearFilter;
|
|
36016
|
+
texture.magFilter = THREE28.LinearFilter;
|
|
36017
|
+
texture.anisotropy = 16;
|
|
36018
|
+
texture.needsUpdate = true;
|
|
36019
|
+
return texture;
|
|
36020
|
+
}
|
|
36021
|
+
|
|
36022
|
+
// src/textures/create-three-texture-meshes.ts
|
|
36023
|
+
import * as THREE29 from "three";
|
|
36024
|
+
function createTexturePlane(config, boardData) {
|
|
36025
|
+
const {
|
|
36026
|
+
texture,
|
|
36027
|
+
yOffset,
|
|
36028
|
+
isBottomLayer,
|
|
36029
|
+
textureType,
|
|
36030
|
+
usePolygonOffset = false,
|
|
36031
|
+
renderOrder = 0
|
|
36032
|
+
} = config;
|
|
36033
|
+
if (!texture) return null;
|
|
36034
|
+
const boardOutlineBounds = calculateOutlineBounds(boardData);
|
|
36035
|
+
const planeGeom = new THREE29.PlaneGeometry(
|
|
36036
|
+
boardOutlineBounds.width,
|
|
36037
|
+
boardOutlineBounds.height
|
|
36038
|
+
);
|
|
36039
|
+
const material = new THREE29.MeshBasicMaterial({
|
|
36040
|
+
map: texture,
|
|
36041
|
+
transparent: true,
|
|
36042
|
+
side: THREE29.DoubleSide,
|
|
36043
|
+
depthWrite: textureType === "panel-outlines",
|
|
36044
|
+
polygonOffset: usePolygonOffset,
|
|
36045
|
+
polygonOffsetFactor: usePolygonOffset ? -4 : 0,
|
|
36046
|
+
// Increased for better z-fighting prevention
|
|
36047
|
+
polygonOffsetUnits: usePolygonOffset ? -4 : 0
|
|
36048
|
+
});
|
|
36049
|
+
const mesh = new THREE29.Mesh(planeGeom, material);
|
|
36050
|
+
mesh.position.set(
|
|
36051
|
+
boardOutlineBounds.centerX,
|
|
36052
|
+
boardOutlineBounds.centerY,
|
|
36053
|
+
yOffset
|
|
36054
|
+
);
|
|
36055
|
+
if (isBottomLayer) {
|
|
36056
|
+
mesh.rotation.set(Math.PI, 0, 0);
|
|
36057
|
+
}
|
|
36058
|
+
mesh.name = `${isBottomLayer ? "bottom" : "top"}-${textureType}-texture-plane`;
|
|
36059
|
+
mesh.renderOrder = renderOrder;
|
|
36060
|
+
return mesh;
|
|
36061
|
+
}
|
|
36062
|
+
function createTextureMeshes(textures, boardData, pcbThickness) {
|
|
36063
|
+
const meshes = [];
|
|
36064
|
+
if (!textures || !boardData || pcbThickness === null) return meshes;
|
|
36065
|
+
const topTraceMesh = createTexturePlane(
|
|
36066
|
+
{
|
|
36067
|
+
texture: textures.topTrace,
|
|
36068
|
+
yOffset: pcbThickness / 2 + BOARD_SURFACE_OFFSET.traces,
|
|
36069
|
+
// Use consistent copper offset
|
|
36070
|
+
isBottomLayer: false,
|
|
36071
|
+
textureType: "trace",
|
|
36072
|
+
usePolygonOffset: false,
|
|
36073
|
+
renderOrder: 2
|
|
36074
|
+
// Render after soldermask
|
|
36075
|
+
},
|
|
36076
|
+
boardData
|
|
36077
|
+
);
|
|
36078
|
+
if (topTraceMesh) meshes.push(topTraceMesh);
|
|
36079
|
+
const topTraceWithMaskMesh = createTexturePlane(
|
|
36080
|
+
{
|
|
36081
|
+
texture: textures.topTraceWithMask,
|
|
36082
|
+
yOffset: pcbThickness / 2 + BOARD_SURFACE_OFFSET.traces,
|
|
36083
|
+
isBottomLayer: false,
|
|
36084
|
+
textureType: "trace-with-mask",
|
|
36085
|
+
usePolygonOffset: false,
|
|
36086
|
+
renderOrder: 2
|
|
36087
|
+
// Render after soldermask
|
|
36088
|
+
},
|
|
36089
|
+
boardData
|
|
36090
|
+
);
|
|
36091
|
+
if (topTraceWithMaskMesh) meshes.push(topTraceWithMaskMesh);
|
|
36092
|
+
const topSilkscreenMesh = createTexturePlane(
|
|
36093
|
+
{
|
|
36094
|
+
texture: textures.topSilkscreen,
|
|
36095
|
+
yOffset: pcbThickness / 2 + 3e-3,
|
|
36096
|
+
// Slightly above soldermask
|
|
36097
|
+
isBottomLayer: false,
|
|
36098
|
+
textureType: "silkscreen",
|
|
36099
|
+
usePolygonOffset: false,
|
|
36100
|
+
renderOrder: 3
|
|
36101
|
+
// Render after traces
|
|
36102
|
+
},
|
|
36103
|
+
boardData
|
|
36104
|
+
);
|
|
36105
|
+
if (topSilkscreenMesh) meshes.push(topSilkscreenMesh);
|
|
36106
|
+
const bottomTraceMesh = createTexturePlane(
|
|
36107
|
+
{
|
|
36108
|
+
texture: textures.bottomTrace,
|
|
36109
|
+
yOffset: -pcbThickness / 2 - BOARD_SURFACE_OFFSET.traces,
|
|
36110
|
+
// Use consistent copper offset
|
|
36111
|
+
isBottomLayer: true,
|
|
36112
|
+
textureType: "trace",
|
|
36113
|
+
usePolygonOffset: false,
|
|
36114
|
+
renderOrder: 2
|
|
36115
|
+
// Render after soldermask
|
|
36116
|
+
},
|
|
36117
|
+
boardData
|
|
36118
|
+
);
|
|
36119
|
+
if (bottomTraceMesh) meshes.push(bottomTraceMesh);
|
|
36120
|
+
const bottomTraceWithMaskMesh = createTexturePlane(
|
|
36121
|
+
{
|
|
36122
|
+
texture: textures.bottomTraceWithMask,
|
|
36123
|
+
yOffset: -pcbThickness / 2 - BOARD_SURFACE_OFFSET.traces,
|
|
36124
|
+
isBottomLayer: true,
|
|
36125
|
+
textureType: "trace-with-mask",
|
|
36126
|
+
usePolygonOffset: false,
|
|
36127
|
+
renderOrder: 2
|
|
36128
|
+
// Render after soldermask
|
|
36129
|
+
},
|
|
36130
|
+
boardData
|
|
36131
|
+
);
|
|
36132
|
+
if (bottomTraceWithMaskMesh) meshes.push(bottomTraceWithMaskMesh);
|
|
36133
|
+
const bottomSilkscreenMesh = createTexturePlane(
|
|
36134
|
+
{
|
|
36135
|
+
texture: textures.bottomSilkscreen,
|
|
36136
|
+
yOffset: -pcbThickness / 2 - 3e-3,
|
|
36137
|
+
isBottomLayer: true,
|
|
36138
|
+
textureType: "silkscreen",
|
|
36139
|
+
usePolygonOffset: false,
|
|
36140
|
+
renderOrder: 3
|
|
36141
|
+
// Render after traces
|
|
36142
|
+
},
|
|
36143
|
+
boardData
|
|
36144
|
+
);
|
|
36145
|
+
if (bottomSilkscreenMesh) meshes.push(bottomSilkscreenMesh);
|
|
36146
|
+
const topSoldermaskMesh = createTexturePlane(
|
|
36147
|
+
{
|
|
36148
|
+
texture: textures.topSoldermask,
|
|
36149
|
+
yOffset: pcbThickness / 2 + 1e-3,
|
|
36150
|
+
// Just above board surface
|
|
36151
|
+
isBottomLayer: false,
|
|
36152
|
+
textureType: "soldermask",
|
|
36153
|
+
usePolygonOffset: true,
|
|
36154
|
+
// Enable polygon offset
|
|
36155
|
+
renderOrder: 1
|
|
36156
|
+
// Render after board (renderOrder)
|
|
36157
|
+
},
|
|
36158
|
+
boardData
|
|
36159
|
+
);
|
|
36160
|
+
if (topSoldermaskMesh) meshes.push(topSoldermaskMesh);
|
|
36161
|
+
const bottomSoldermaskMesh = createTexturePlane(
|
|
36162
|
+
{
|
|
36163
|
+
texture: textures.bottomSoldermask,
|
|
36164
|
+
yOffset: -pcbThickness / 2 - 1e-3,
|
|
36165
|
+
// Just below board surface (bottom side)
|
|
36166
|
+
isBottomLayer: true,
|
|
36167
|
+
textureType: "soldermask",
|
|
36168
|
+
usePolygonOffset: true,
|
|
36169
|
+
// Enable polygon offset
|
|
36170
|
+
renderOrder: 1
|
|
36171
|
+
// Render after board (renderOrder)
|
|
36172
|
+
},
|
|
36173
|
+
boardData
|
|
36174
|
+
);
|
|
36175
|
+
if (bottomSoldermaskMesh) meshes.push(bottomSoldermaskMesh);
|
|
36176
|
+
const topCopperTextMesh = createTexturePlane(
|
|
36177
|
+
{
|
|
36178
|
+
texture: textures.topCopperText,
|
|
36179
|
+
yOffset: pcbThickness / 2 + BOARD_SURFACE_OFFSET.copper,
|
|
36180
|
+
isBottomLayer: false,
|
|
36181
|
+
textureType: "copper-text",
|
|
36182
|
+
usePolygonOffset: false,
|
|
36183
|
+
renderOrder: 2
|
|
36184
|
+
// Render after soldermask
|
|
36185
|
+
},
|
|
36186
|
+
boardData
|
|
36187
|
+
);
|
|
36188
|
+
if (topCopperTextMesh) meshes.push(topCopperTextMesh);
|
|
36189
|
+
const bottomCopperTextMesh = createTexturePlane(
|
|
36190
|
+
{
|
|
36191
|
+
texture: textures.bottomCopperText,
|
|
36192
|
+
yOffset: -pcbThickness / 2 - BOARD_SURFACE_OFFSET.copper,
|
|
36193
|
+
isBottomLayer: true,
|
|
36194
|
+
textureType: "copper-text",
|
|
36195
|
+
usePolygonOffset: false,
|
|
36196
|
+
renderOrder: 2
|
|
36197
|
+
// Render after soldermask
|
|
36198
|
+
},
|
|
36199
|
+
boardData
|
|
36200
|
+
);
|
|
36201
|
+
if (bottomCopperTextMesh) meshes.push(bottomCopperTextMesh);
|
|
36202
|
+
const topCopperMesh = createTexturePlane(
|
|
36203
|
+
{
|
|
36204
|
+
texture: textures.topCopper,
|
|
36205
|
+
yOffset: pcbThickness / 2 + BOARD_SURFACE_OFFSET.copper,
|
|
36206
|
+
isBottomLayer: false,
|
|
36207
|
+
textureType: "copper",
|
|
36208
|
+
usePolygonOffset: false,
|
|
36209
|
+
renderOrder: 2
|
|
36210
|
+
// Render after soldermask
|
|
36211
|
+
},
|
|
36212
|
+
boardData
|
|
36213
|
+
);
|
|
36214
|
+
if (topCopperMesh) meshes.push(topCopperMesh);
|
|
36215
|
+
const bottomCopperMesh = createTexturePlane(
|
|
36216
|
+
{
|
|
36217
|
+
texture: textures.bottomCopper,
|
|
36218
|
+
yOffset: -pcbThickness / 2 - BOARD_SURFACE_OFFSET.copper,
|
|
36219
|
+
isBottomLayer: true,
|
|
36220
|
+
textureType: "copper",
|
|
36221
|
+
usePolygonOffset: false,
|
|
36222
|
+
renderOrder: 2
|
|
36223
|
+
// Render after soldermask
|
|
36224
|
+
},
|
|
36225
|
+
boardData
|
|
36226
|
+
);
|
|
36227
|
+
if (bottomCopperMesh) meshes.push(bottomCopperMesh);
|
|
36228
|
+
const topPanelOutlinesMesh = createTexturePlane(
|
|
36229
|
+
{
|
|
36230
|
+
texture: textures.topPanelOutlines,
|
|
36231
|
+
yOffset: pcbThickness / 2 + 4e-3,
|
|
36232
|
+
// Above silkscreen
|
|
36233
|
+
isBottomLayer: false,
|
|
36234
|
+
textureType: "panel-outlines",
|
|
36235
|
+
usePolygonOffset: false,
|
|
36236
|
+
renderOrder: 4
|
|
36237
|
+
},
|
|
36238
|
+
boardData
|
|
36239
|
+
);
|
|
36240
|
+
if (topPanelOutlinesMesh) meshes.push(topPanelOutlinesMesh);
|
|
36241
|
+
const bottomPanelOutlinesMesh = createTexturePlane(
|
|
36242
|
+
{
|
|
36243
|
+
texture: textures.bottomPanelOutlines,
|
|
36244
|
+
yOffset: -pcbThickness / 2 - 4e-3,
|
|
36245
|
+
// Below bottom silkscreen
|
|
36246
|
+
isBottomLayer: true,
|
|
36247
|
+
textureType: "panel-outlines",
|
|
36248
|
+
usePolygonOffset: false,
|
|
36249
|
+
renderOrder: 4
|
|
36250
|
+
},
|
|
36251
|
+
boardData
|
|
36252
|
+
);
|
|
36253
|
+
if (bottomPanelOutlinesMesh) meshes.push(bottomPanelOutlinesMesh);
|
|
36254
|
+
return meshes;
|
|
36255
|
+
}
|
|
36256
|
+
|
|
35961
36257
|
// src/hooks/useManifoldBoardBuilder.ts
|
|
35962
36258
|
var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
35963
36259
|
const [geoms, setGeoms] = useState14(null);
|
|
@@ -36027,7 +36323,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
36027
36323
|
manifoldInstancesForCleanup.current = [];
|
|
36028
36324
|
let boardManifold = null;
|
|
36029
36325
|
const currentGeoms = {};
|
|
36030
|
-
const
|
|
36326
|
+
const layerTextureMap = {};
|
|
36031
36327
|
try {
|
|
36032
36328
|
const currentPcbThickness = boardData.thickness || 1.6;
|
|
36033
36329
|
setPcbThickness(currentPcbThickness);
|
|
@@ -36126,7 +36422,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
36126
36422
|
{
|
|
36127
36423
|
key: "plated-holes-union",
|
|
36128
36424
|
geometry: cutPlatedGeom,
|
|
36129
|
-
color: new
|
|
36425
|
+
color: new THREE30.Color(
|
|
36130
36426
|
colors.copper[0],
|
|
36131
36427
|
colors.copper[1],
|
|
36132
36428
|
colors.copper[2]
|
|
@@ -36156,7 +36452,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
36156
36452
|
const matColorArray = boardMaterialColors[boardData.material] ?? colors.fr4Tan;
|
|
36157
36453
|
currentGeoms.board = {
|
|
36158
36454
|
geometry: finalBoardGeom,
|
|
36159
|
-
color: new
|
|
36455
|
+
color: new THREE30.Color(
|
|
36160
36456
|
matColorArray[0],
|
|
36161
36457
|
matColorArray[1],
|
|
36162
36458
|
matColorArray[2]
|
|
@@ -36174,28 +36470,17 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
36174
36470
|
boardClipVolume
|
|
36175
36471
|
);
|
|
36176
36472
|
currentGeoms.smtPads = smtPadGeoms;
|
|
36177
|
-
const { copperPourGeoms } = processCopperPoursForManifold(
|
|
36178
|
-
Manifold,
|
|
36179
|
-
CrossSection,
|
|
36180
|
-
circuitJson,
|
|
36181
|
-
currentPcbThickness,
|
|
36182
|
-
manifoldInstancesForCleanup.current,
|
|
36183
|
-
boardData.material,
|
|
36184
|
-
holeUnion,
|
|
36185
|
-
boardClipVolume
|
|
36186
|
-
);
|
|
36187
|
-
currentGeoms.copperPours = copperPourGeoms;
|
|
36188
36473
|
setGeoms(currentGeoms);
|
|
36189
36474
|
const traceColorWithoutMaskArr = colors.fr4TracesWithoutMaskTan;
|
|
36190
36475
|
const traceColorWithoutMask = `rgb(${Math.round(traceColorWithoutMaskArr[0] * 255)}, ${Math.round(traceColorWithoutMaskArr[1] * 255)}, ${Math.round(traceColorWithoutMaskArr[2] * 255)})`;
|
|
36191
|
-
|
|
36476
|
+
layerTextureMap.topTrace = createTraceTextureForLayer({
|
|
36192
36477
|
layer: "top",
|
|
36193
36478
|
circuitJson,
|
|
36194
36479
|
boardData,
|
|
36195
36480
|
traceColor: traceColorWithoutMask,
|
|
36196
36481
|
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
36197
36482
|
});
|
|
36198
|
-
|
|
36483
|
+
layerTextureMap.bottomTrace = createTraceTextureForLayer({
|
|
36199
36484
|
layer: "bottom",
|
|
36200
36485
|
circuitJson,
|
|
36201
36486
|
boardData,
|
|
@@ -36204,14 +36489,14 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
36204
36489
|
});
|
|
36205
36490
|
const traceColorWithMaskArr = colors.fr4TracesWithMaskGreen;
|
|
36206
36491
|
const traceColorWithMask = `rgb(${Math.round(traceColorWithMaskArr[0] * 255)}, ${Math.round(traceColorWithMaskArr[1] * 255)}, ${Math.round(traceColorWithMaskArr[2] * 255)})`;
|
|
36207
|
-
|
|
36492
|
+
layerTextureMap.topTraceWithMask = createTraceTextureForLayer({
|
|
36208
36493
|
layer: "top",
|
|
36209
36494
|
circuitJson,
|
|
36210
36495
|
boardData,
|
|
36211
36496
|
traceColor: traceColorWithMask,
|
|
36212
36497
|
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
36213
36498
|
});
|
|
36214
|
-
|
|
36499
|
+
layerTextureMap.bottomTraceWithMask = createTraceTextureForLayer({
|
|
36215
36500
|
layer: "bottom",
|
|
36216
36501
|
circuitJson,
|
|
36217
36502
|
boardData,
|
|
@@ -36219,14 +36504,14 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
36219
36504
|
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
36220
36505
|
});
|
|
36221
36506
|
const silkscreenColor = "rgb(255,255,255)";
|
|
36222
|
-
|
|
36507
|
+
layerTextureMap.topSilkscreen = createSilkscreenTextureForLayer({
|
|
36223
36508
|
layer: "top",
|
|
36224
36509
|
circuitJson,
|
|
36225
36510
|
boardData,
|
|
36226
36511
|
silkscreenColor,
|
|
36227
36512
|
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
36228
36513
|
});
|
|
36229
|
-
|
|
36514
|
+
layerTextureMap.bottomSilkscreen = createSilkscreenTextureForLayer({
|
|
36230
36515
|
layer: "bottom",
|
|
36231
36516
|
circuitJson,
|
|
36232
36517
|
boardData,
|
|
@@ -36235,14 +36520,14 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
36235
36520
|
});
|
|
36236
36521
|
const soldermaskColorArr = soldermaskColors[boardData.material] ?? colors.fr4SolderMaskGreen;
|
|
36237
36522
|
const soldermaskColor = `rgb(${Math.round(soldermaskColorArr[0] * 255)}, ${Math.round(soldermaskColorArr[1] * 255)}, ${Math.round(soldermaskColorArr[2] * 255)})`;
|
|
36238
|
-
|
|
36523
|
+
layerTextureMap.topSoldermask = createSoldermaskTextureForLayer({
|
|
36239
36524
|
layer: "top",
|
|
36240
36525
|
circuitJson,
|
|
36241
36526
|
boardData,
|
|
36242
36527
|
soldermaskColor,
|
|
36243
36528
|
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
36244
36529
|
});
|
|
36245
|
-
|
|
36530
|
+
layerTextureMap.bottomSoldermask = createSoldermaskTextureForLayer({
|
|
36246
36531
|
layer: "bottom",
|
|
36247
36532
|
circuitJson,
|
|
36248
36533
|
boardData,
|
|
@@ -36251,33 +36536,45 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
36251
36536
|
});
|
|
36252
36537
|
const copperColorArr = colors.copper;
|
|
36253
36538
|
const copperColor = `rgb(${Math.round(copperColorArr[0] * 255)}, ${Math.round(copperColorArr[1] * 255)}, ${Math.round(copperColorArr[2] * 255)})`;
|
|
36254
|
-
|
|
36539
|
+
layerTextureMap.topCopperText = createCopperTextTextureForLayer({
|
|
36255
36540
|
layer: "top",
|
|
36256
36541
|
circuitJson,
|
|
36257
36542
|
boardData,
|
|
36258
36543
|
copperColor,
|
|
36259
36544
|
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
36260
36545
|
});
|
|
36261
|
-
|
|
36546
|
+
layerTextureMap.bottomCopperText = createCopperTextTextureForLayer({
|
|
36262
36547
|
layer: "bottom",
|
|
36263
36548
|
circuitJson,
|
|
36264
36549
|
boardData,
|
|
36265
36550
|
copperColor,
|
|
36266
36551
|
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
36267
36552
|
});
|
|
36268
|
-
|
|
36553
|
+
layerTextureMap.topPanelOutlines = createPanelOutlineTextureForLayer({
|
|
36269
36554
|
layer: "top",
|
|
36270
36555
|
circuitJson,
|
|
36271
36556
|
panelData: boardData,
|
|
36272
36557
|
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
36273
36558
|
});
|
|
36274
|
-
|
|
36559
|
+
layerTextureMap.bottomPanelOutlines = createPanelOutlineTextureForLayer({
|
|
36275
36560
|
layer: "bottom",
|
|
36276
36561
|
circuitJson,
|
|
36277
36562
|
panelData: boardData,
|
|
36278
36563
|
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
36279
36564
|
});
|
|
36280
|
-
|
|
36565
|
+
layerTextureMap.topCopper = createCopperPourTextureForLayer({
|
|
36566
|
+
layer: "top",
|
|
36567
|
+
circuitJson,
|
|
36568
|
+
boardData,
|
|
36569
|
+
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
36570
|
+
});
|
|
36571
|
+
layerTextureMap.bottomCopper = createCopperPourTextureForLayer({
|
|
36572
|
+
layer: "bottom",
|
|
36573
|
+
circuitJson,
|
|
36574
|
+
boardData,
|
|
36575
|
+
traceTextureResolution: TRACE_TEXTURE_RESOLUTION
|
|
36576
|
+
});
|
|
36577
|
+
setTextures(layerTextureMap);
|
|
36281
36578
|
} catch (e) {
|
|
36282
36579
|
console.error("Error processing geometry with Manifold in hook:", e);
|
|
36283
36580
|
setError(
|
|
@@ -36305,11 +36602,11 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson) => {
|
|
|
36305
36602
|
};
|
|
36306
36603
|
|
|
36307
36604
|
// src/utils/manifold/create-three-geometry-meshes.ts
|
|
36308
|
-
import * as
|
|
36605
|
+
import * as THREE32 from "three";
|
|
36309
36606
|
|
|
36310
36607
|
// src/utils/create-board-material.ts
|
|
36311
|
-
import * as
|
|
36312
|
-
var DEFAULT_SIDE =
|
|
36608
|
+
import * as THREE31 from "three";
|
|
36609
|
+
var DEFAULT_SIDE = THREE31.DoubleSide;
|
|
36313
36610
|
var createBoardMaterial = ({
|
|
36314
36611
|
material,
|
|
36315
36612
|
color,
|
|
@@ -36317,7 +36614,7 @@ var createBoardMaterial = ({
|
|
|
36317
36614
|
isFaux = false
|
|
36318
36615
|
}) => {
|
|
36319
36616
|
if (material === "fr4") {
|
|
36320
|
-
return new
|
|
36617
|
+
return new THREE31.MeshPhysicalMaterial({
|
|
36321
36618
|
color,
|
|
36322
36619
|
side,
|
|
36323
36620
|
metalness: 0,
|
|
@@ -36331,7 +36628,7 @@ var createBoardMaterial = ({
|
|
|
36331
36628
|
flatShading: true
|
|
36332
36629
|
});
|
|
36333
36630
|
}
|
|
36334
|
-
return new
|
|
36631
|
+
return new THREE31.MeshStandardMaterial({
|
|
36335
36632
|
color,
|
|
36336
36633
|
side,
|
|
36337
36634
|
flatShading: true,
|
|
@@ -36347,12 +36644,12 @@ function createGeometryMeshes(geoms) {
|
|
|
36347
36644
|
const meshes = [];
|
|
36348
36645
|
if (!geoms) return meshes;
|
|
36349
36646
|
if (geoms.board && geoms.board.geometry) {
|
|
36350
|
-
const mesh = new
|
|
36647
|
+
const mesh = new THREE32.Mesh(
|
|
36351
36648
|
geoms.board.geometry,
|
|
36352
36649
|
createBoardMaterial({
|
|
36353
36650
|
material: geoms.board.material,
|
|
36354
36651
|
color: geoms.board.color,
|
|
36355
|
-
side:
|
|
36652
|
+
side: THREE32.DoubleSide,
|
|
36356
36653
|
isFaux: geoms.board.isFaux
|
|
36357
36654
|
})
|
|
36358
36655
|
);
|
|
@@ -36362,11 +36659,11 @@ function createGeometryMeshes(geoms) {
|
|
|
36362
36659
|
const createMeshesFromArray = (geomArray) => {
|
|
36363
36660
|
if (geomArray) {
|
|
36364
36661
|
geomArray.forEach((comp) => {
|
|
36365
|
-
const mesh = new
|
|
36662
|
+
const mesh = new THREE32.Mesh(
|
|
36366
36663
|
comp.geometry,
|
|
36367
|
-
new
|
|
36664
|
+
new THREE32.MeshStandardMaterial({
|
|
36368
36665
|
color: comp.color,
|
|
36369
|
-
side:
|
|
36666
|
+
side: THREE32.DoubleSide,
|
|
36370
36667
|
flatShading: true,
|
|
36371
36668
|
// Consistent with board
|
|
36372
36669
|
polygonOffset: true,
|
|
@@ -36382,164 +36679,6 @@ function createGeometryMeshes(geoms) {
|
|
|
36382
36679
|
createMeshesFromArray(geoms.platedHoles);
|
|
36383
36680
|
createMeshesFromArray(geoms.smtPads);
|
|
36384
36681
|
createMeshesFromArray(geoms.vias);
|
|
36385
|
-
createMeshesFromArray(geoms.copperPours);
|
|
36386
|
-
return meshes;
|
|
36387
|
-
}
|
|
36388
|
-
|
|
36389
|
-
// src/utils/manifold/create-three-texture-meshes.ts
|
|
36390
|
-
import * as THREE32 from "three";
|
|
36391
|
-
function createTextureMeshes(textures, boardData, pcbThickness) {
|
|
36392
|
-
const meshes = [];
|
|
36393
|
-
if (!textures || !boardData || pcbThickness === null) return meshes;
|
|
36394
|
-
const createTexturePlane = (texture, yOffset, isBottomLayer, keySuffix, usePolygonOffset = false, renderOrder = 0) => {
|
|
36395
|
-
if (!texture) return null;
|
|
36396
|
-
const planeGeom = new THREE32.PlaneGeometry(boardData.width, boardData.height);
|
|
36397
|
-
const material = new THREE32.MeshBasicMaterial({
|
|
36398
|
-
map: texture,
|
|
36399
|
-
transparent: true,
|
|
36400
|
-
side: THREE32.DoubleSide,
|
|
36401
|
-
depthWrite: keySuffix === "panel-outlines",
|
|
36402
|
-
polygonOffset: usePolygonOffset,
|
|
36403
|
-
polygonOffsetFactor: usePolygonOffset ? -4 : 0,
|
|
36404
|
-
// Increased for better z-fighting prevention
|
|
36405
|
-
polygonOffsetUnits: usePolygonOffset ? -4 : 0
|
|
36406
|
-
});
|
|
36407
|
-
const mesh = new THREE32.Mesh(planeGeom, material);
|
|
36408
|
-
mesh.position.set(boardData.center.x, boardData.center.y, yOffset);
|
|
36409
|
-
if (isBottomLayer) {
|
|
36410
|
-
mesh.rotation.set(Math.PI, 0, 0);
|
|
36411
|
-
}
|
|
36412
|
-
mesh.name = `${isBottomLayer ? "bottom" : "top"}-${keySuffix}-texture-plane`;
|
|
36413
|
-
mesh.renderOrder = renderOrder;
|
|
36414
|
-
return mesh;
|
|
36415
|
-
};
|
|
36416
|
-
const topTraceMesh = createTexturePlane(
|
|
36417
|
-
textures.topTrace,
|
|
36418
|
-
pcbThickness / 2 + BOARD_SURFACE_OFFSET.traces,
|
|
36419
|
-
// Use consistent copper offset
|
|
36420
|
-
false,
|
|
36421
|
-
"trace",
|
|
36422
|
-
false,
|
|
36423
|
-
2
|
|
36424
|
-
// Render after soldermask
|
|
36425
|
-
);
|
|
36426
|
-
if (topTraceMesh) meshes.push(topTraceMesh);
|
|
36427
|
-
const topTraceWithMaskMesh = createTexturePlane(
|
|
36428
|
-
textures.topTraceWithMask,
|
|
36429
|
-
pcbThickness / 2 + BOARD_SURFACE_OFFSET.traces,
|
|
36430
|
-
false,
|
|
36431
|
-
"trace-with-mask",
|
|
36432
|
-
false,
|
|
36433
|
-
2
|
|
36434
|
-
// Render after soldermask
|
|
36435
|
-
);
|
|
36436
|
-
if (topTraceWithMaskMesh) meshes.push(topTraceWithMaskMesh);
|
|
36437
|
-
const topSilkscreenMesh = createTexturePlane(
|
|
36438
|
-
textures.topSilkscreen,
|
|
36439
|
-
pcbThickness / 2 + 3e-3,
|
|
36440
|
-
// Slightly above soldermask
|
|
36441
|
-
false,
|
|
36442
|
-
"silkscreen",
|
|
36443
|
-
false,
|
|
36444
|
-
3
|
|
36445
|
-
// Render after traces
|
|
36446
|
-
);
|
|
36447
|
-
if (topSilkscreenMesh) meshes.push(topSilkscreenMesh);
|
|
36448
|
-
const bottomTraceMesh = createTexturePlane(
|
|
36449
|
-
textures.bottomTrace,
|
|
36450
|
-
-pcbThickness / 2 - BOARD_SURFACE_OFFSET.traces,
|
|
36451
|
-
// Use consistent copper offset
|
|
36452
|
-
true,
|
|
36453
|
-
"trace",
|
|
36454
|
-
false,
|
|
36455
|
-
2
|
|
36456
|
-
// Render after soldermask
|
|
36457
|
-
);
|
|
36458
|
-
if (bottomTraceMesh) meshes.push(bottomTraceMesh);
|
|
36459
|
-
const bottomTraceWithMaskMesh = createTexturePlane(
|
|
36460
|
-
textures.bottomTraceWithMask,
|
|
36461
|
-
-pcbThickness / 2 - BOARD_SURFACE_OFFSET.traces,
|
|
36462
|
-
true,
|
|
36463
|
-
"trace-with-mask",
|
|
36464
|
-
false,
|
|
36465
|
-
2
|
|
36466
|
-
// Render after soldermask
|
|
36467
|
-
);
|
|
36468
|
-
if (bottomTraceWithMaskMesh) meshes.push(bottomTraceWithMaskMesh);
|
|
36469
|
-
const bottomSilkscreenMesh = createTexturePlane(
|
|
36470
|
-
textures.bottomSilkscreen,
|
|
36471
|
-
-pcbThickness / 2 - 3e-3,
|
|
36472
|
-
true,
|
|
36473
|
-
"silkscreen",
|
|
36474
|
-
false,
|
|
36475
|
-
3
|
|
36476
|
-
// Render after traces
|
|
36477
|
-
);
|
|
36478
|
-
if (bottomSilkscreenMesh) meshes.push(bottomSilkscreenMesh);
|
|
36479
|
-
const topSoldermaskMesh = createTexturePlane(
|
|
36480
|
-
textures.topSoldermask,
|
|
36481
|
-
pcbThickness / 2 + 1e-3,
|
|
36482
|
-
// Just above board surface
|
|
36483
|
-
false,
|
|
36484
|
-
"soldermask",
|
|
36485
|
-
true,
|
|
36486
|
-
// Enable polygon offset
|
|
36487
|
-
1
|
|
36488
|
-
// Render after board (renderOrder)
|
|
36489
|
-
);
|
|
36490
|
-
if (topSoldermaskMesh) meshes.push(topSoldermaskMesh);
|
|
36491
|
-
const bottomSoldermaskMesh = createTexturePlane(
|
|
36492
|
-
textures.bottomSoldermask,
|
|
36493
|
-
-pcbThickness / 2 - 1e-3,
|
|
36494
|
-
// Just below board surface (bottom side)
|
|
36495
|
-
true,
|
|
36496
|
-
"soldermask",
|
|
36497
|
-
true,
|
|
36498
|
-
// Enable polygon offset
|
|
36499
|
-
1
|
|
36500
|
-
// Render after board (renderOrder)
|
|
36501
|
-
);
|
|
36502
|
-
if (bottomSoldermaskMesh) meshes.push(bottomSoldermaskMesh);
|
|
36503
|
-
const topCopperTextMesh = createTexturePlane(
|
|
36504
|
-
textures.topCopperText,
|
|
36505
|
-
pcbThickness / 2 + BOARD_SURFACE_OFFSET.copper,
|
|
36506
|
-
false,
|
|
36507
|
-
"copper-text",
|
|
36508
|
-
false,
|
|
36509
|
-
2
|
|
36510
|
-
// Render after soldermask
|
|
36511
|
-
);
|
|
36512
|
-
if (topCopperTextMesh) meshes.push(topCopperTextMesh);
|
|
36513
|
-
const bottomCopperTextMesh = createTexturePlane(
|
|
36514
|
-
textures.bottomCopperText,
|
|
36515
|
-
-pcbThickness / 2 - BOARD_SURFACE_OFFSET.copper,
|
|
36516
|
-
true,
|
|
36517
|
-
"copper-text",
|
|
36518
|
-
false,
|
|
36519
|
-
2
|
|
36520
|
-
// Render after soldermask
|
|
36521
|
-
);
|
|
36522
|
-
if (bottomCopperTextMesh) meshes.push(bottomCopperTextMesh);
|
|
36523
|
-
const topPanelOutlinesMesh = createTexturePlane(
|
|
36524
|
-
textures.topPanelOutlines,
|
|
36525
|
-
pcbThickness / 2 + 4e-3,
|
|
36526
|
-
// Above silkscreen
|
|
36527
|
-
false,
|
|
36528
|
-
"panel-outlines",
|
|
36529
|
-
false,
|
|
36530
|
-
4
|
|
36531
|
-
);
|
|
36532
|
-
if (topPanelOutlinesMesh) meshes.push(topPanelOutlinesMesh);
|
|
36533
|
-
const bottomPanelOutlinesMesh = createTexturePlane(
|
|
36534
|
-
textures.bottomPanelOutlines,
|
|
36535
|
-
-pcbThickness / 2 - 4e-3,
|
|
36536
|
-
// Below bottom silkscreen
|
|
36537
|
-
true,
|
|
36538
|
-
"panel-outlines",
|
|
36539
|
-
false,
|
|
36540
|
-
4
|
|
36541
|
-
);
|
|
36542
|
-
if (bottomPanelOutlinesMesh) meshes.push(bottomPanelOutlinesMesh);
|
|
36543
36682
|
return meshes;
|
|
36544
36683
|
}
|
|
36545
36684
|
|
|
@@ -36567,8 +36706,6 @@ var BoardMeshes = ({
|
|
|
36567
36706
|
}
|
|
36568
36707
|
} else if (mesh.name.includes("plated_hole") || mesh.name.includes("via")) {
|
|
36569
36708
|
shouldShow = visibility.topCopper || visibility.bottomCopper;
|
|
36570
|
-
} else if (mesh.name.includes("copper_pour")) {
|
|
36571
|
-
shouldShow = visibility.topCopper || visibility.bottomCopper;
|
|
36572
36709
|
}
|
|
36573
36710
|
if (shouldShow) {
|
|
36574
36711
|
rootObject.add(mesh);
|
|
@@ -36596,6 +36733,10 @@ var BoardMeshes = ({
|
|
|
36596
36733
|
shouldShow = visibility.topCopper;
|
|
36597
36734
|
} else if (mesh.name.includes("bottom-copper-text")) {
|
|
36598
36735
|
shouldShow = visibility.bottomCopper;
|
|
36736
|
+
} else if (mesh.name.includes("top-copper")) {
|
|
36737
|
+
shouldShow = visibility.topCopper;
|
|
36738
|
+
} else if (mesh.name.includes("bottom-copper")) {
|
|
36739
|
+
shouldShow = visibility.bottomCopper;
|
|
36599
36740
|
} else if (mesh.name.includes("panel-outlines")) {
|
|
36600
36741
|
shouldShow = visibility.boardBody;
|
|
36601
36742
|
}
|
|
@@ -38108,7 +38249,7 @@ var oppositeAlignmentMap = {
|
|
|
38108
38249
|
start: "end",
|
|
38109
38250
|
end: "start"
|
|
38110
38251
|
};
|
|
38111
|
-
function
|
|
38252
|
+
function clamp2(start, value, end) {
|
|
38112
38253
|
return max(start, min(value, end));
|
|
38113
38254
|
}
|
|
38114
38255
|
function evaluate(value, param) {
|
|
@@ -38461,7 +38602,7 @@ var arrow = (options) => ({
|
|
|
38461
38602
|
const min$1 = minPadding;
|
|
38462
38603
|
const max2 = clientSize - arrowDimensions[length2] - maxPadding;
|
|
38463
38604
|
const center = clientSize / 2 - arrowDimensions[length2] / 2 + centerToReference;
|
|
38464
|
-
const offset4 =
|
|
38605
|
+
const offset4 = clamp2(min$1, center, max2);
|
|
38465
38606
|
const shouldAddOffset = !middlewareData.arrow && getAlignment(placement) != null && center !== offset4 && rects.reference[length2] / 2 - (center < min$1 ? minPadding : maxPadding) - arrowDimensions[length2] / 2 < 0;
|
|
38466
38607
|
const alignmentOffset = shouldAddOffset ? center < min$1 ? center - min$1 : center - max2 : 0;
|
|
38467
38608
|
return {
|
|
@@ -38758,14 +38899,14 @@ var shift = function(options) {
|
|
|
38758
38899
|
const maxSide = mainAxis === "y" ? "bottom" : "right";
|
|
38759
38900
|
const min2 = mainAxisCoord + overflow[minSide];
|
|
38760
38901
|
const max2 = mainAxisCoord - overflow[maxSide];
|
|
38761
|
-
mainAxisCoord =
|
|
38902
|
+
mainAxisCoord = clamp2(min2, mainAxisCoord, max2);
|
|
38762
38903
|
}
|
|
38763
38904
|
if (checkCrossAxis) {
|
|
38764
38905
|
const minSide = crossAxis === "y" ? "top" : "left";
|
|
38765
38906
|
const maxSide = crossAxis === "y" ? "bottom" : "right";
|
|
38766
38907
|
const min2 = crossAxisCoord + overflow[minSide];
|
|
38767
38908
|
const max2 = crossAxisCoord - overflow[maxSide];
|
|
38768
|
-
crossAxisCoord =
|
|
38909
|
+
crossAxisCoord = clamp2(min2, crossAxisCoord, max2);
|
|
38769
38910
|
}
|
|
38770
38911
|
const limitedCoords = limiter.fn({
|
|
38771
38912
|
...state,
|
|
@@ -40470,7 +40611,7 @@ RovingFocusGroup.displayName = GROUP_NAME;
|
|
|
40470
40611
|
var RovingFocusGroupImpl = React34.forwardRef((props, forwardedRef) => {
|
|
40471
40612
|
const {
|
|
40472
40613
|
__scopeRovingFocusGroup,
|
|
40473
|
-
orientation,
|
|
40614
|
+
orientation: orientation2,
|
|
40474
40615
|
loop = false,
|
|
40475
40616
|
dir,
|
|
40476
40617
|
currentTabStopId: currentTabStopIdProp,
|
|
@@ -40505,7 +40646,7 @@ var RovingFocusGroupImpl = React34.forwardRef((props, forwardedRef) => {
|
|
|
40505
40646
|
RovingFocusProvider,
|
|
40506
40647
|
{
|
|
40507
40648
|
scope: __scopeRovingFocusGroup,
|
|
40508
|
-
orientation,
|
|
40649
|
+
orientation: orientation2,
|
|
40509
40650
|
dir: direction,
|
|
40510
40651
|
loop,
|
|
40511
40652
|
currentTabStopId,
|
|
@@ -40526,7 +40667,7 @@ var RovingFocusGroupImpl = React34.forwardRef((props, forwardedRef) => {
|
|
|
40526
40667
|
Primitive.div,
|
|
40527
40668
|
{
|
|
40528
40669
|
tabIndex: isTabbingBackOut || focusableItemsCount === 0 ? -1 : 0,
|
|
40529
|
-
"data-orientation":
|
|
40670
|
+
"data-orientation": orientation2,
|
|
40530
40671
|
...groupProps,
|
|
40531
40672
|
ref: composedRefs,
|
|
40532
40673
|
style: { outline: "none", ...props.style },
|
|
@@ -40642,10 +40783,10 @@ function getDirectionAwareKey(key, dir) {
|
|
|
40642
40783
|
if (dir !== "rtl") return key;
|
|
40643
40784
|
return key === "ArrowLeft" ? "ArrowRight" : key === "ArrowRight" ? "ArrowLeft" : key;
|
|
40644
40785
|
}
|
|
40645
|
-
function getFocusIntent(event,
|
|
40786
|
+
function getFocusIntent(event, orientation2, dir) {
|
|
40646
40787
|
const key = getDirectionAwareKey(event.key, dir);
|
|
40647
|
-
if (
|
|
40648
|
-
if (
|
|
40788
|
+
if (orientation2 === "vertical" && ["ArrowLeft", "ArrowRight"].includes(key)) return void 0;
|
|
40789
|
+
if (orientation2 === "horizontal" && ["ArrowUp", "ArrowDown"].includes(key)) return void 0;
|
|
40649
40790
|
return MAP_KEY_TO_FOCUS_INTENT[key];
|
|
40650
40791
|
}
|
|
40651
40792
|
function focusFirst2(candidates, preventScroll = false) {
|