55 lines
1.9 KiB
JavaScript
55 lines
1.9 KiB
JavaScript
|
|
/**
|
||
|
|
* Regenerates realisticToothAssets.ts from FDI_*.svg files in public/.
|
||
|
|
* Usage (from frontend/): node scripts/extract-tooth-svgs.mjs
|
||
|
|
*/
|
||
|
|
import fs from 'node:fs';
|
||
|
|
import path from 'node:path';
|
||
|
|
|
||
|
|
const dir = path.resolve('public');
|
||
|
|
const files = fs.readdirSync(dir).filter((f) => /^FDI_\d{2}\.svg$/i.test(f));
|
||
|
|
const out = {};
|
||
|
|
|
||
|
|
for (const file of files.sort()) {
|
||
|
|
const id = file.match(/FDI_(\d{2})/i)?.[1];
|
||
|
|
if (!id) continue;
|
||
|
|
const xml = fs.readFileSync(path.join(dir, file), 'utf8');
|
||
|
|
const vb = xml.match(/viewBox="([^"]+)"/)?.[1];
|
||
|
|
const toothG = xml.match(/<g id="tooth-\d+"[^>]*>/)?.[0] ?? '';
|
||
|
|
const transform = toothG.match(/transform="([^"]+)"/)?.[1];
|
||
|
|
const rootD = xml.match(/id="root-path"[\s\S]*?d="([^"]+)"/)?.[1];
|
||
|
|
const crownD = xml.match(/id="crown-path"[\s\S]*?d="([^"]+)"/)?.[1];
|
||
|
|
if (!vb || !rootD || !crownD) throw new Error(`Failed to parse ${file}`);
|
||
|
|
out[id] = {
|
||
|
|
viewBox: vb,
|
||
|
|
...(transform ? { groupTransform: transform } : {}),
|
||
|
|
crown: crownD,
|
||
|
|
roots: [rootD],
|
||
|
|
};
|
||
|
|
console.log(id, transform ? 'mirrored' : 'plain');
|
||
|
|
}
|
||
|
|
|
||
|
|
const ts = `import type { FdiToothId } from '@/types/treatment';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Realistic buccal-view assets from public/FDI_*.svg.
|
||
|
|
* Upper (1x/2x): root-up. Lower (3x/4x): crown-up.
|
||
|
|
* Left chart side (Q1/Q4) includes horizontal flip via groupTransform.
|
||
|
|
*/
|
||
|
|
export interface RealisticToothAsset {
|
||
|
|
viewBox: string;
|
||
|
|
/** Applied inside the svg (e.g. Q1/Q4 mirror baked in source files). */
|
||
|
|
groupTransform?: string;
|
||
|
|
crown: string;
|
||
|
|
roots: string[];
|
||
|
|
}
|
||
|
|
|
||
|
|
export const REALISTIC_TOOTH_ASSETS: Partial<Record<FdiToothId, RealisticToothAsset>> = ${JSON.stringify(out, null, 2)};
|
||
|
|
|
||
|
|
export function getRealisticToothAsset(fdi: FdiToothId): RealisticToothAsset | null {
|
||
|
|
return REALISTIC_TOOTH_ASSETS[fdi] ?? null;
|
||
|
|
}
|
||
|
|
`;
|
||
|
|
|
||
|
|
fs.writeFileSync(path.resolve('src/components/treatment/realisticToothAssets.ts'), ts);
|
||
|
|
console.log('Wrote realisticToothAssets.ts for', Object.keys(out).length, 'teeth');
|