AnasSarkiz/magnetic-shutter-remote-r8

A USB‑C rechargeable battery-powered ESP32‑C3 wireless controller with Li‑ion charging, protected 3.3‑V buck‑boost regulation, thermal/safety monitoring, status LEDs, buttons, programming UART, crystal clock, and 2.4‑GHz antenna matching network.

Version
0.4.0-prototype
License
unset
Stars
0

scripts/partition-pcb-models.ts

import type { CadComponent } from "circuit-json";

type CadComponentId = CadComponent["cad_component_id"];

/** Package measured native meshes; geometry and board-world poses are unchanged. */
export function partitionPcbModels({
	models,
	boardBytes,
	fragmentCount,
	maxModelsPerFragment,
	maxFragmentBytes,
}: {
	models: { cadComponentId: CadComponentId; bytes: number }[];
	boardBytes: number;
	fragmentCount: number;
	maxModelsPerFragment: number;
	maxFragmentBytes: number;
}): CadComponentId[][] {
	if (models.length > fragmentCount * maxModelsPerFragment)
		throw new Error("Fitted models exceed fragment capacity");
	if (
		new Set(models.map((model) => model.cadComponentId)).size !== models.length
	)
		throw new Error("Duplicate fitted CAD identity");
	const fragments = Array.from({ length: fragmentCount }, (_, index) => ({
		ids: [] as CadComponentId[],
		bytes: index === 0 ? boardBytes : 0,
	}));
	for (const model of [...models].sort((a, b) => b.bytes - a.bytes)) {
		const fragment = fragments
			.filter((fragment) => fragment.ids.length < maxModelsPerFragment)
			.sort((a, b) => a.bytes - b.bytes)[0];
		if (!fragment || fragment.bytes + model.bytes > maxFragmentBytes)
			throw new Error(
				`Native CAD cannot fit upload bound: ${model.cadComponentId}`,
			);
		fragment.ids.push(model.cadComponentId);
		fragment.bytes += model.bytes;
	}
	return fragments.map((fragment) => fragment.ids);
}