Files
Aislo/B07_DesignDetail/openwebcad/src/integration/dxf-clip.ts
T

50 lines
1.9 KiB
TypeScript

/**
* 오토캐드 → 웹 CAD 붙여넣기 — 순수 부분.
* 오토캐드 기본 명령(WBLOCK · DXFOUT)으로 저장한 파일을 끌어다 놓거나 DXF 글을 Ctrl+V 하면,
* 서버(`/api/projects/dxf-clip` · `/file`)가 돌려준 JSON 을 여기서 현재 도면에 맞춘다.
* DOM · 상태를 안 만지는 것만 둔다(시험이 바로 부름) — 잇기는 `dxf-clip-paste.ts`.
*/
import type { Layer } from '../App.types.ts';
import type { JsonEntity } from '../entities/Entity';
/** DXF 글인가 — 그룹 코드 0 다음 줄이 SECTION 으로 시작(앞 공백 · CRLF 허용). */
export function isDxfText(text: string): boolean {
return /^\s*0\s*\r?\n\s*SECTION\b/.test(text);
}
export interface ClipLayer {
name: string;
color: string | null;
}
/**
* 서버 엔티티(layerId = DXF 도면층 이름)를 현재 도면에 붙일 모양으로 —
* 같은 이름 도면층이 있으면 그 층 · 없으면 새 층(DXF 층 색) · id 는 모두 새로(두 번 붙여도 안 겹침).
*/
export function prepareClip(
entities: JsonEntity[],
clipLayers: ClipLayer[],
existing: Layer[]
): { entities: JsonEntity[]; newLayers: Layer[] } {
const idByName = new Map(existing.map((layer) => [layer.name, layer.id]));
const newLayers: Layer[] = [];
const colorByName = new Map(clipLayers.map((layer) => [layer.name, layer.color]));
const layerIdOf = (name: string): string => {
let id = idByName.get(name);
if (!id) {
id = crypto.randomUUID();
idByName.set(name, id);
const color = colorByName.get(name);
newLayers.push({ id, name, isVisible: true, isLocked: false, ...(color ? { color } : {}) });
}
return id;
};
const renew = (entity: JsonEntity): JsonEntity => ({
...entity,
id: crypto.randomUUID(),
layerId: layerIdOf(String(entity.layerId ?? '0')),
...(entity.children ? { children: entity.children.map(renew) } : {}),
});
return { entities: entities.map(renew), newLayers };
}