diff --git a/packages/chili-builder/src/appBuilder.ts b/packages/chili-builder/src/appBuilder.ts index 7d34b2ce..f51d54d3 100644 --- a/packages/chili-builder/src/appBuilder.ts +++ b/packages/chili-builder/src/appBuilder.ts @@ -2,6 +2,7 @@ import { Application, CommandService, EditEventHandler, EditorService, HotkeyService } from "chili"; import { + DefaultDataExchange, I18n, IDataExchange, IDocument, @@ -12,7 +13,6 @@ import { IVisualFactory, IWindow, Logger, - VisualNode, } from "chili-core"; import { IAdditionalModule } from "./additionalModule"; @@ -103,20 +103,7 @@ export class AppBuilder { } initDataExchange(): IDataExchange { - return { - importFormats(): string[] { - return ["chili3d"]; - }, - exportFormats(): string[] { - return ["chili3d"]; - }, - import(document: IDocument, files: FileList | File[]): Promise { - return Promise.reject("not implemented"); - }, - export(type: string, nodes: VisualNode[]): Promise { - return Promise.reject("not implemented"); - }, - }; + return new DefaultDataExchange(); } private ensureNecessary() { diff --git a/packages/chili-core/src/dataExchange.ts b/packages/chili-core/src/dataExchange.ts index 5b6ad292..471e964d 100644 --- a/packages/chili-core/src/dataExchange.ts +++ b/packages/chili-core/src/dataExchange.ts @@ -1,7 +1,8 @@ // Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license. import { IDocument } from "./document"; -import { VisualNode } from "./model"; +import { PubSub } from "./foundation"; +import { EditableShapeNode, NodeLinkedList, ShapeNode, VisualNode } from "./model"; export interface IDataExchange { importFormats(): string[]; @@ -9,3 +10,50 @@ export interface IDataExchange { import(document: IDocument, files: FileList | File[]): Promise; export(type: string, nodes: VisualNode[]): Promise; } + +export class DefaultDataExchange implements IDataExchange { + importFormats(): string[] { + return [".step", ".stp", ".iges", ".igs"]; + } + + exportFormats(): string[] { + return [".step", ".iges"]; + } + + async import(document: IDocument, files: FileList | File[]): Promise { + for (const file of files) { + let content = new Uint8Array(await file.arrayBuffer()); + let factory = document.application.shapeFactory.converter.convertFromIGES; + if (file.name.endsWith(".step") || file.name.endsWith(".stp")) { + factory = document.application.shapeFactory.converter.convertFromSTEP; + } + let shape = factory(content); + if (!shape.isOk) { + PubSub.default.pub("showToast", "toast.read.error"); + return; + } + let shapes = shape.value.map((x, i) => { + return new EditableShapeNode(document, `Imported ${i}`, x); + }); + let nodeList = new NodeLinkedList(document, file.name); + document.addNode(nodeList); + nodeList.add(...shapes); + document.visual.update(); + } + } + + async export(type: string, nodes: VisualNode[]): Promise { + let shapes = nodes.map((x) => (x as ShapeNode).shape.value); + let factory = nodes[0].document.application.shapeFactory.converter.convertToIGES; + if (type === ".step") { + factory = nodes[0].document.application.shapeFactory.converter.convertToSTEP; + } + let shapeString = factory(...shapes); + if (!shapeString.isOk) { + PubSub.default.pub("showToast", "toast.converter.error"); + return undefined; + } + + return [shapeString.value]; + } +}