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;
});