diff --git a/packages/clay/src/core/Elements/Element/index.ts b/packages/clay/src/core/Elements/Element/index.ts index ffc55a0..145559b 100644 --- a/packages/clay/src/core/Elements/Element/index.ts +++ b/packages/clay/src/core/Elements/Element/index.ts @@ -108,7 +108,7 @@ export abstract class ClayElement extends ClayObject { * Adds a new subtraction to this element. * @param subtraction the element that will be subtracted from this element. */ - addSubtraction(subtraction: ClayElement) { + async addSubtraction(subtraction: ClayElement) { if (!(subtraction.attributes instanceof IFC.IfcFeatureElementSubtraction)) { throw new Error( "Only elements with attributes of type IfcFeatureElementSubtraction can be used to subtract", @@ -129,19 +129,19 @@ export abstract class ClayElement extends ClayObject { const id = subtraction.attributes.expressID; this.subtractions.set(id, voids); - this.model.update(); + await this.model.update(); } /** * Removes an existing subtraction from this element. * @param subtraction the element whose subtraction will be removed from this element. */ - removeSubtraction(subtraction: ClayElement) { + async removeSubtraction(subtraction: ClayElement) { const id = subtraction.attributes.expressID; const found = this.subtractions.get(id); if (!found) return; this.model.delete(found); - this.model.update(); + await this.model.update(); } protected ifcToThreeGeometry(data: WEBIFC.IfcGeometry) { diff --git a/packages/clay/src/core/Model/index.ts b/packages/clay/src/core/Model/index.ts index ceb6f8e..88e1524 100644 --- a/packages/clay/src/core/Model/index.ts +++ b/packages/clay/src/core/Model/index.ts @@ -6,6 +6,11 @@ import { ClayElementType } from "../Elements"; * Object that represents an IFC model and manages all its data. */ export class Model { + wasm = { + path: "", + absolute: false, + }; + /** * Opaque material of the model. All models have just 1 shared opaque and transparent material. */ @@ -19,20 +24,24 @@ export class Model { opacity: 0.2, }); - /** - * The core of our libraries. It contains our IFC parser and geometry engine. - */ - ifcAPI = new WEBIFC.IfcAPI(); - /** * Types created within this model. */ types = new Map(); + private _ifcAPI = new WEBIFC.IfcAPI(); + private _context?: WEBIFC.IFC4X3.IfcRepresentationContext; private _modelID?: number; + /** + * The core of our libraries. It contains our IFC parser and geometry engine. + */ + get ifcAPI() { + return this._ifcAPI; + } + /** * The ID that identifies this IFC file. */ @@ -57,8 +66,14 @@ export class Model { * Initializes the library, allowing it to create and edit IFC data. */ async init() { - await this.ifcAPI.Init(); - this._modelID = this.ifcAPI.CreateModel({ schema: WEBIFC.Schemas.IFC4X3 }); + this._ifcAPI.SetWasmPath(this.wasm.path, this.wasm.absolute); + await this._ifcAPI.Init(); + this._modelID = this._ifcAPI.CreateModel( + { schema: WEBIFC.Schemas.IFC4X3 }, + { + TAPE_SIZE: 5000000, // 5MB + }, + ); this._context = new WEBIFC.IFC4X3.IfcRepresentationContext( new WEBIFC.IFC4X3.IfcLabel("Default"), new WEBIFC.IFC4X3.IfcLabel("Model"), @@ -70,7 +85,7 @@ export class Model { * @param item the object to create or override. */ set(item: WEBIFC.IfcLineObject) { - this.ifcAPI.WriteLine(this.modelID, item); + this._ifcAPI.WriteLine(this.modelID, item); } /** @@ -88,7 +103,7 @@ export class Model { let foundItem: WEBIFC.IfcLineObject; if (item instanceof WEBIFC.Handle) { - foundItem = this.ifcAPI.GetLine(this.modelID, item.value); + foundItem = this._ifcAPI.GetLine(this.modelID, item.value); } else { foundItem = item; } @@ -103,7 +118,7 @@ export class Model { } } - this.ifcAPI.DeleteLine(this.modelID, foundItem.expressID); + this._ifcAPI.DeleteLine(this.modelID, foundItem.expressID); } /** @@ -115,7 +130,7 @@ export class Model { throw new Error("Item not found!"); } if (item instanceof WEBIFC.Handle) { - return this.ifcAPI.GetLine(this.modelID, item.value) as T; + return this._ifcAPI.GetLine(this.modelID, item.value) as T; } return item; } @@ -123,14 +138,19 @@ export class Model { /** * Updates a model. Necessary for applying new boolean operations. */ - update() { + async update() { + console.log("hey") if (this._modelID === undefined) { throw new Error("Malformed model!"); } // TODO: Fix memory leak - const model = this.ifcAPI.SaveModel(this._modelID); - this.ifcAPI.CloseModel(this._modelID); - this._modelID++; - this.ifcAPI.OpenModel(model); + const model = this._ifcAPI.SaveModel(this._modelID); + + this._ifcAPI.Dispose(); + this._ifcAPI = null as any; + this._ifcAPI = new WEBIFC.IfcAPI(); + + await this.init(); + this._modelID = this._ifcAPI.OpenModel(model); } } diff --git a/packages/clay/src/elements/Walls/SimpleWall/example.ts b/packages/clay/src/elements/Walls/SimpleWall/example.ts index aecc822..99995aa 100644 --- a/packages/clay/src/elements/Walls/SimpleWall/example.ts +++ b/packages/clay/src/elements/Walls/SimpleWall/example.ts @@ -29,14 +29,14 @@ const grids = components.get(OBC.Grids); grids.create(world); const model = new CLAY.Model(); -model.ifcAPI.SetWasmPath("https://unpkg.com/web-ifc@0.0.59/", true); +model.wasm = { path: "https://unpkg.com/web-ifc@0.0.59/", absolute: true }; await model.init(); const simpleWallType = new CLAY.SimpleWallType(model); - +// const wall1 = simpleWallType.addInstance(); world.scene.three.add(...wall1.meshes); -// wall.startPoint = new THREE.Vector2(1, 1); +wall1.startPoint = new THREE.Vector2(1, 1); wall1.endPoint = new THREE.Vector2(3, 0); wall1.update(true); wall1.meshes[0].setColorAt(0, new THREE.Color(1, 0, 0)); @@ -65,7 +65,7 @@ simpleWallType.addCorner({ priority: "start", }); -simpleWallType.updateCorners(); +await simpleWallType.updateCorners(); world.camera.controls.fitToSphere(wall1.meshes[0], false); @@ -74,7 +74,7 @@ const opening = simpleOpeningType.addInstance(); // scene.add(...opening.meshes); // console.log(simpleOpeningType); -wall1.addSubtraction(opening, true); +await wall1.addSubtraction(opening, true); wall1.update(true); // Stats diff --git a/packages/clay/src/elements/Walls/SimpleWall/index.ts b/packages/clay/src/elements/Walls/SimpleWall/index.ts index e5687d7..ccfea05 100644 --- a/packages/clay/src/elements/Walls/SimpleWall/index.ts +++ b/packages/clay/src/elements/Walls/SimpleWall/index.ts @@ -1,5 +1,5 @@ import { v4 as uuidv4 } from "uuid"; -import { IFC4X3, IFC4X3 as IFC } from "web-ifc"; +import { IFC4X3 as IFC } from "web-ifc"; import { Model, DynamicClayElementType } from "../../../core"; import { SimpleWall } from "./src"; import { @@ -11,7 +11,7 @@ import { ClippingPlaneType } from "../../Openings"; export * from "./src"; export class SimpleWallType extends DynamicClayElementType { - attributes: IFC4X3.IfcWallType; + attributes: IFC.IfcWallType; width = 0.2; @@ -36,14 +36,16 @@ export class SimpleWallType extends DynamicClayElementType { null, IFC.IfcWallTypeEnum.STANDARD, ); + + this.model.set(this.attributes); } addCorner(config: WallCornerConfig) { this._cornerer.add(config); } - updateCorners(ids?: Iterable) { - this._cornerer.update(ids); + async updateCorners(ids?: Iterable) { + await this._cornerer.update(ids); } protected createElement() { diff --git a/packages/clay/src/elements/Walls/SimpleWall/src/simple-wall-cornerer.ts b/packages/clay/src/elements/Walls/SimpleWall/src/simple-wall-cornerer.ts index cdf973b..3d7938a 100644 --- a/packages/clay/src/elements/Walls/SimpleWall/src/simple-wall-cornerer.ts +++ b/packages/clay/src/elements/Walls/SimpleWall/src/simple-wall-cornerer.ts @@ -36,19 +36,19 @@ export class SimpleWallCornerer { corners.set(id2, { ...config, to, priority, offset }); } - update(ids: Iterable = this.list.keys()) { + async update(ids: Iterable = this.list.keys()) { for (const id of ids) { const corners = this.list.get(id); if (!corners) { continue; } for (const [, corner] of corners) { - this.extend(corner); + await this.extend(corner); } } } - extend(corner: WallCorner) { + async extend(corner: WallCorner) { const { wall1, wall2, to, priority, offset } = corner; // Strategy: there are 2 cases // A) Both points of the wall are on one side of this wall @@ -112,7 +112,7 @@ export class SimpleWallCornerer { if (corner.cut && corner.cutDirection) { const planeCut = wall1.planes.get(corner.cut, corner.cutDirection); - wall2.addSubtraction(planeCut); + await wall2.addSubtraction(planeCut); } const extended = extendStart ? wall2.startPoint : wall2.endPoint; diff --git a/packages/clay/src/elements/Walls/SimpleWall/src/simple-wall.ts b/packages/clay/src/elements/Walls/SimpleWall/src/simple-wall.ts index c21f5fb..af3c4a5 100644 --- a/packages/clay/src/elements/Walls/SimpleWall/src/simple-wall.ts +++ b/packages/clay/src/elements/Walls/SimpleWall/src/simple-wall.ts @@ -131,22 +131,22 @@ export class SimpleWall extends ClayElement { super.update(updateGeometry); } - addSubtraction(element: ClayElement, nest = false) { + async addSubtraction(element: ClayElement, nest = false) { if (this.subtractions.has(element.attributes.expressID)) { return; } - super.addSubtraction(element); + await super.addSubtraction(element); if (nest) { this._nester.add(element); } this.updateGeometryID(); } - removeSubtraction(element: ClayElement) { + async removeSubtraction(element: ClayElement) { if (!this.subtractions.has(element.attributes.expressID)) { return; } - super.removeSubtraction(element); + await super.removeSubtraction(element); this._nester.delete(element); this.updateGeometryID(); }