krishnax12/watchy-eink-smartwatch
Unfinished prototype (not production-ready): 4 native DRC errors, 2 display-flex intersections, and missing antenna radiator copper remain
- Version
- 1.2.7
- License
- MIT
- Stars
- 1
scripts/render-u5-fit.cjs
const fs = require("node:fs");
const { Resvg } = require("@resvg/resvg-js");
async function main() {
const occt = await require("occt-import-js")();
const result = occt.ReadStepFile(
fs.readFileSync("assets/SOT-23-6.step"),
null,
);
if (!result.success) throw new Error("Could not load SOT-23-6 model");
const triangles = [];
for (const mesh of result.meshes) {
const vertices = mesh.attributes.position.array;
for (let index = 0; index < mesh.index.array.length; index += 3) {
const points = mesh.index.array
.slice(index, index + 3)
.map((vertex) => vertices.slice(vertex * 3, vertex * 3 + 3));
const face = mesh.brep_faces.find(
(face) => index / 3 >= face.first && index / 3 <= face.last,
);
const color = face?.color ?? mesh.color ?? [0.3, 0.3, 0.3];
triangles.push({
points,
color,
z: points.reduce((sum, point) => sum + point[2], 0) / 3,
});
}
}
const scale = 130;
const project = ([x, y]) => `${400 + x * scale},${350 - y * scale}`;
const paths = triangles
.sort((a, b) => a.z - b.z)
.map(
({ points, color }) =>
`<polygon points="${points.map(project).join(" ")}" fill="rgb(${color.map((channel) => Math.round(channel * 255)).join(",")})"/>`,
)
.join("");
const pads = [
[-1.15, 0.95],
[-1.15, 0],
[-1.15, -0.95],
[1.15, -0.95],
[1.15, 0],
[1.15, 0.95],
]
.map(
([x, y], index) =>
`<rect x="${400 + (x - 0.6) * scale}" y="${350 - (y + 0.3) * scale}" width="${1.2 * scale}" height="${0.6 * scale}" fill="none" stroke="#efb22d" stroke-width="3"/><text x="${400 + (x < 0 ? -2 : 2) * scale}" y="${356 - y * scale}" text-anchor="middle" fill="white" font-size="18">${index + 1}</text>`,
)
.join("");
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="800" height="650"><rect width="800" height="650" fill="#18252b"/><text x="35" y="45" fill="white" font-size="24">U5: SOT-23-6 STEP over recommended lands</text><text x="35" y="75" fill="#efb22d" font-size="17">Yellow: 1.20 × 0.60 mm pads; 0.95 mm pitch</text>${paths}${pads}<text x="35" y="605" fill="white" font-size="16">Top projection; generic CAD, not manufacturer-certified</text></svg>`;
fs.writeFileSync("reports/u5-model-footprint-fit.svg", svg);
fs.writeFileSync(
"reports/u5-model-footprint-fit.png",
new Resvg(svg).render().asPng(),
);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});