from fastapi import FastAPI, UploadFile, File from fastapi.responses import JSONResponse, FileResponse from fastapi.middleware.cors import CORSMiddleware import os app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) @app.get("/") def serve_frontend(): return FileResponse("index.html") @app.post("/parse") async def parse_file(file: UploadFile = File(...)): content = await file.read() return JSONResponse(content=parse_dcm_assembly(content)) def parse_dcm_assembly(file_bytes): lines = file_bytes.decode("utf-8").splitlines() blocks, current = [], [] for line in lines: if line.startswith("CLASS"): if current: blocks.append(current) current = [] current.append(line.strip()) if current: blocks.append(current) parts, geometry, constraints = [], {}, [] plane_map, tag_to_plane, label_map = {}, {}, {} for block in blocks: head = block[0] if "CLASS SET " in head: part, members = {}, [] for line in block: if "DCM3_TEXT_LABEL" in line: part['name'] = line.split("DCM3_TEXT_LABEL", 1)[1].strip() elif "FMEMBER TAGS" in line: members = list(map(int, line.split()[2:])) if 'name' in part: part['member_tags'] = members parts.append(part) elif "CLASS PLANE " in head: pid = int(head.split()[-1]) base, norm = None, None for line in block: if "FBASE_POINT" in line: base = tuple(map(float, line.split()[1:])) elif "FNORMAL" in line: norm = tuple(map(float, line.split()[1:])) if base and norm: plane_map[pid] = {'base_point': base, 'normal': norm} elif "CLASS WORK_PLANE " in head: wid = int(head.split()[-1]) tag, label = None, None for line in block: if "FMY_PLANE TAG" in line: tag = int(line.split()[-1]) elif "DCM3_TEXT_LABEL" in line: label = line.split("DCM3_TEXT_LABEL", 1)[1].strip() if tag: tag_to_plane[wid] = tag label_map[wid] = label elif "CLASS CONSTRAINT " in head: con = {} for line in block: if "FEND_1 TAG" in line: con['from'] = int(line.split()[-1]) elif "FEND_2 TAG" in line: con['to'] = int(line.split()[-1]) elif "DCM3_TEXT_LABEL" in line: con['label'] = line.split("DCM3_TEXT_LABEL", 1)[1].strip() if con: constraints.append(con) for wid, pid in tag_to_plane.items(): if pid in plane_map: geometry[wid] = {**plane_map[pid], 'label': label_map.get(wid)} return { "parts": parts, "geometry": geometry, "constraints": constraints }