const express = require('express'); const authenticate = require('../middleware/auth'); const multer = require('multer'); const { parseString } = require('dxf-parser'); const router = express.Router(); const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 10 * 1024 * 1024 } }); // Upload DXF file -> parse and return JSON representation (Fabric.js compatible) router.post('/import', authenticate, upload.single('file'), async (req, res) => { try { if (!req.file) { return res.status(400).json({ error: 'No file uploaded' }); } const dxfContent = req.file.buffer.toString('utf-8'); console.log('DXF file size:', dxfContent.length); const parsed = parseString(dxfContent); // Convert parsed entities to Fabric.js objects (simplified) const fabricObjects = []; if (parsed && parsed.entities) { parsed.entities.forEach(entity => { const type = entity.type; if (type === 'LINE') { fabricObjects.push({ type: 'line', x1: entity.start.x, y1: entity.start.y, x2: entity.end.x, y2: entity.end.y, stroke: '#000', strokeWidth: 1, }); } else if (type === 'CIRCLE') { fabricObjects.push({ type: 'circle', left: entity.center.x - entity.radius, top: entity.center.y - entity.radius, radius: entity.radius, fill: 'transparent', stroke: '#000', }); } else if (type === 'ARC') { // simplified arc handling fabricObjects.push({ type: 'path', path: `M ${entity.center.x} ${entity.center.y}`, // placeholder stroke: '#000', strokeWidth: 1, }); } else if (type === 'POLYLINE' || type === 'LWPOLYLINE') { // convert vertices to polygon if (entity.vertices && entity.vertices.length >= 2) { const points = entity.vertices.map(v => ({ x: v.x, y: v.y })); fabricObjects.push({ type: 'polygon', points, stroke: '#000', strokeWidth: 1, fill: 'transparent', }); } } }); } res.json({ objects: fabricObjects }); } catch (err) { console.error('DXF import error:', err); res.status(500).json({ error: 'Failed to parse DXF file: ' + err.message }); } }); // Export canvas JSON to DXF string router.post('/export', authenticate, (req, res) => { try { const { objects } = req.body; if (!objects || !Array.isArray(objects)) { return res.status(400).json({ error: 'Invalid objects array' }); } // Build DXF content let dxf = '0\nSECTION\n2\nHEADER\n0\nENDSEC\n'; dxf += '0\nSECTION\n2\nTABLES\n0\nENDSEC\n'; dxf += '0\nSECTION\n2\nBLOCKS\n0\nENDSEC\n'; dxf += '0\nSECTION\n2\nENTITIES\n'; objects.forEach(obj => { if (obj.type === 'line') { dxf += `0\nLINE\n8\n0\n10\n${obj.x1}\n20\n${obj.y1}\n11\n${obj.x2}\n21\n${obj.y2}\n`; } else if (obj.type === 'circle') { const cx = obj.left + obj.radius; const cy = obj.top + obj.radius; dxf += `0\nCIRCLE\n8\n0\n10\n${cx}\n20\n${cy}\n40\n${obj.radius}\n`; } else if (obj.type === 'polygon') { // LWPOLYLINE dxf += `0\nLWPOLYLINE\n8\n0\n90\n${obj.points.length}\n`; obj.points.forEach((pt, i) => { dxf += `10\n${pt.x}\n20\n${pt.y}\n`; }); } }); dxf += '0\nENDSEC\n0\nEOF\n'; res.setHeader('Content-Type', 'application/dxf'); res.setHeader('Content-Disposition', 'attachment; filename=drawing.dxf'); res.send(dxf); } catch (err) { console.error('DXF export error:', err); res.status(500).json({ error: 'Export failed' }); } }); module.exports = router;