import fs from "fs"; import path from "path"; import { boundsFromPoints, extractPolylineVertices, first, num, parseDxfText, pointsFromLWPolyline, readDxfText, } from "./lib/dxf_basic_parser.mjs"; function parseArgs(argv) { const out = {}; for (let i = 0; i < argv.length; i += 1) { const token = argv[i]; if (!token.startsWith("--")) continue; const key = token.slice(2); const value = argv[i + 1]; if (!value || value.startsWith("--")) continue; out[key] = value; i += 1; } return out; } function normalizeLayer(layerName) { return String(layerName || "0") .trim() .toUpperCase() .replace(/[^A-Z0-9_]/g, "_"); } function representativePoint(entity, entities, index) { if (entity.type === "INSERT") return { point: { x: num(entity, 10), y: num(entity, 20) }, nextIndex: index }; if (entity.type === "LINE") { const x1 = num(entity, 10); const y1 = num(entity, 20); const x2 = num(entity, 11); const y2 = num(entity, 21); return { point: { x: (x1 + x2) / 2, y: (y1 + y2) / 2 }, nextIndex: index }; } if (entity.type === "CIRCLE" || entity.type === "ARC") { return { point: { x: num(entity, 10), y: num(entity, 20) }, nextIndex: index }; } if (entity.type === "LWPOLYLINE") { const points = pointsFromLWPolyline(entity); const box = boundsFromPoints(points); return { point: box ? { x: box.cx, y: box.cy } : null, nextIndex: index }; } if (entity.type === "POLYLINE") { const parsed = extractPolylineVertices(entities, index); const box = boundsFromPoints(parsed.points); return { point: box ? { x: box.cx, y: box.cy } : null, nextIndex: parsed.nextIndex }; } return { point: null, nextIndex: index }; } function buildLayerPositionKeys(dxfPath, cellSize) { const dxfText = readDxfText(dxfPath); const { entities, headerBounds } = parseDxfText(dxfText); const minX = Number.isFinite(headerBounds.minX) ? headerBounds.minX : 0; const minY = Number.isFinite(headerBounds.minY) ? headerBounds.minY : 0; const items = []; const sequenceByLayer = new Map(); for (let i = 0; i < entities.length; i += 1) { const entity = entities[i]; const layerRaw = first(entity, 8) ?? "0"; const layer = normalizeLayer(layerRaw); const extracted = representativePoint(entity, entities, i); i = extracted.nextIndex; if (!extracted.point) continue; const col = Math.floor((extracted.point.x - minX) / cellSize); const row = Math.floor((extracted.point.y - minY) / cellSize); const seq = (sequenceByLayer.get(layer) ?? 0) + 1; sequenceByLayer.set(layer, seq); const key = `${layer}::R${row}C${col}::${String(seq).padStart(4, "0")}`; items.push({ key, layer, sourceLayer: layerRaw, type: entity.type, x: Number(extracted.point.x.toFixed(3)), y: Number(extracted.point.y.toFixed(3)), grid: { row, col }, }); } const byLayer = {}; for (const item of items) byLayer[item.layer] = (byLayer[item.layer] ?? 0) + 1; return { meta: { source: path.basename(dxfPath), generatedAt: new Date().toISOString(), cellSize, entityCount: entities.length, keyedItemCount: items.length, bounds: headerBounds, }, byLayer, items, }; } const args = parseArgs(process.argv.slice(2)); const scriptDir = path.dirname(new URL(import.meta.url).pathname); const dxfPath = path.resolve(args.input ?? path.join(scriptDir, "center.dxf")); const outputPath = path.resolve(args.output ?? path.join(scriptDir, "layer_position_keys.json")); const cellSize = Number(args.cell ?? 2000); const result = buildLayerPositionKeys(dxfPath, Number.isFinite(cellSize) && cellSize > 0 ? cellSize : 2000); fs.writeFileSync(outputPath, `${JSON.stringify(result, null, 2)}\n`, "utf8"); console.log(`saved: ${outputPath}`);