102 lines
3.7 KiB
JavaScript
102 lines
3.7 KiB
JavaScript
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;
|