feat: add DXF (R12) and SVG exporters

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
immortaly007andClaude Opus 5.5 committed 2026-10-15 14:39:29 +02:00
1 parent b142c4f766
commit 8d597e856e
4 files changed
+119

No files matched your search

+24
View File
@@ -0,0 +1,24 @@
import { formatMm, shapeSize } from './geometry';
import type { Shape } from './types';
/** Minimal ASCII DXF R12: one closed POLYLINE per ring, units mm, Y axis up. */
export function toDxf(shapeMm: Shape): string {
const { height } = shapeSize(shapeMm);
const out: (string | number)[] = [
0, 'SECTION', 2, 'HEADER',
9, '$ACADVER', 1, 'AC1009',
9, '$INSUNITS', 70, 4,
0, 'ENDSEC',
0, 'SECTION', 2, 'ENTITIES',
];
for (const ring of [shapeMm.outer, ...shapeMm.holes]) {
out.push(0, 'POLYLINE', 8, '0', 66, 1, 70, 1, 10, '0.0', 20, '0.0', 30, '0.0');
for (const p of ring) {
out.push(0, 'VERTEX', 8, '0', 10, formatMm(p.x), 20, formatMm(height - p.y), 30, '0.0');
}
out.push(0, 'SEQEND', 8, '0');
}
out.push(0, 'ENDSEC', 0, 'EOF');
// RDWorks is a Windows tool; CRLF is the most widely accepted DXF line ending.
return out.join('\r\n') + '\r\n';
}
+20
View File
@@ -0,0 +1,20 @@
import { formatMm, shapeSize } from './geometry';
import type { Point, Shape } from './types';
export function toSvg(shapeMm: Shape): string {
const { width, height } = shapeSize(shapeMm);
const w = formatMm(width);
const h = formatMm(height);
const d = [shapeMm.outer, ...shapeMm.holes].map(ringPath).join(' ');
return [
'<?xml version="1.0" encoding="UTF-8"?>',
`<svg xmlns="http://www.w3.org/2000/svg" width="${w}mm" height="${h}mm" viewBox="0 0 ${w} ${h}">`,
` <path d="${d}" fill="none" fill-rule="evenodd" stroke="#ff0000" stroke-width="0.1"/>`,
'</svg>',
'',
].join('\n');
}
function ringPath(ring: Point[]): string {
return 'M' + ring.map((p) => `${formatMm(p.x)},${formatMm(p.y)}`).join(' L') + ' Z';
}