Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/ifc importer #19

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
358 changes: 341 additions & 17 deletions resources/openbim-clay.js

Large diffs are not rendered by default.

108 changes: 57 additions & 51 deletions resources/rollup-extensions.mjs
Original file line number Diff line number Diff line change
@@ -1,56 +1,62 @@
// Source: https://github.com/rollup/rollup/issues/1052
import { basename, dirname, isAbsolute, resolve } from 'path';
import * as fs from 'fs';

function isFile ( file ) {
try {
return fs.statSync( file ).isFile();
} catch ( err ) {
return false;
}
import { basename, dirname, isAbsolute, resolve } from "path";
import * as fs from "fs";

function isFile(file) {
try {
return fs.statSync(file).isFile();
} catch (err) {
return false;
}
}

function addExtensionIfNecessary ( file, extensions ) {
try {
const name = basename( file );
const files = fs.readdirSync( dirname( file ) );

if ( ~files.indexOf( name ) && isFile( file ) ) return file;
for ( const ext of extensions ) {
if ( ~files.indexOf( `${name}${ext}` ) && isFile( `${file}${ext}` ) ) {
return `${file}${ext}`;
}
}
} catch ( err ) {
// noop
}

return null;
function addExtensionIfNecessary(file, extensions) {
try {
const name = basename(file);
const files = fs.readdirSync(dirname(file));

if (~files.indexOf(name) && isFile(file)) return file;
for (const ext of extensions) {
if (~files.indexOf(`${name}${ext}`) && isFile(`${file}${ext}`)) {
return `${file}${ext}`;
}
}
} catch (err) {
// noop
}

return null;
}

export default function extensions ({extensions}) {
if (!extensions || !extensions.length) {
throw new Error( `Must specify { extensions: [..] } as non-empty array!` );
}

return {
name: 'extensions',

resolveId ( importee, importer ) {
// absolute paths are left untouched
if ( isAbsolute( importee ) ) {
return addExtensionIfNecessary( resolve( importee ), extensions );
}

// if this is the entry point, resolve against cwd
if ( importer === undefined ) {
return addExtensionIfNecessary( resolve( process.cwd(), importee ), extensions );
}

// external modules are skipped at this stage
if ( importee[0] !== '.' ) return null;

return addExtensionIfNecessary( resolve( dirname( importer ), importee ), extensions );
}
};
}
export default function extensions({ extensions }) {
if (!extensions || !extensions.length) {
throw new Error(`Must specify { extensions: [..] } as non-empty array!`);
}

return {
name: "extensions",

resolveId(importee, importer) {
// absolute paths are left untouched
if (isAbsolute(importee)) {
return addExtensionIfNecessary(resolve(importee), extensions);
}

// if this is the entry point, resolve against cwd
if (importer === undefined) {
return addExtensionIfNecessary(
resolve(process.cwd(), importee),
extensions
);
}

// external modules are skipped at this stage
if (importee[0] !== ".") return null;

return addExtensionIfNecessary(
resolve(dirname(importer), importee),
extensions
);
},
};
}
81 changes: 81 additions & 0 deletions src/IO/IfcImporter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// import { IFC4X3 as IFC } from "web-ifc-three";
// import * as WEBIFC from "web-ifc";
// import * as THREE from "three";
// import { ClayGeometry } from "../Geometry";
// import { Model } from "../base";
// import { IfcUtils } from "../utils/ifc-utils";


// class IfcImporter {
// constructor(model: Model) {

// }

// async loadIfcFile(file: File): Promise<void> {
// const data = await this.parseIfcFile(file);

// this.generateObjects(data);
// }


// private async parseIfcFile(file: File): Promise<any> {

// const ifcApi = new WEBIFC.IfcAPI();

// // initialize the library
// await ifcApi.Init();


// const ifcLoader = new WEBIFC.IfcLoader();



// ifcApi.LoadIfc(filePath);

// // Set a callback when the WASM is loaded
// ifcAPI.SetWasmLoadedCallback(() => {
// // Get all IFC elements
// const allElements = ifcAPI.GetAllElements();

// // Extract GUIDs
// const guids: string[] = [];
// allElements.forEach(element => {
// if (element.guid) {
// guids.push(element.guid);
// }
// });

// resolve(guids);
// });
// }


// // const ifcParser = new THREE.
// // ifcParser.load('example.ifc', (ifcData) => {
// // // Convert IFC data to THREE.js objects
// // const threeObjects = convertIFCDataToThreeObjects(ifcData);
// }



// private generateObjects(data: any): void {

// data.forEach((elementData: any) => {

// // Create all of objects separately to edit in the future
// if (elementData.type === 'wall') {
// // const wall = new Wall();

// } else if (elementData.type === 'slab') {
// // const slab = new Slab();

// }

// });
// }
// }





2 changes: 2 additions & 0 deletions src/base/clay-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export abstract class ClayObject {

abstract attributes: WEBIFC.IfcLineObject;

abstract import(model:Model, id:number) : void;

abstract update(): void;

protected constructor(model: Model) {
Expand Down
22 changes: 21 additions & 1 deletion src/base/model.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import * as THREE from "three";
import * as WEBIFC from "web-ifc";
import { IfcLineObject } from "web-ifc";
import { ElementType } from "../elements/Elements/ElementType";

export class Model {
material = new THREE.MeshLambertMaterial();

typeMap = new Map<string, ElementType>();

materialT = new THREE.MeshLambertMaterial({
transparent: true,
opacity: 0.2,

});

ifcAPI = new WEBIFC.IfcAPI();


private _context?: WEBIFC.IFC4X3.IfcRepresentationContext;

private _modelID?: number;
Expand Down Expand Up @@ -71,16 +76,31 @@ export class Model {
this.ifcAPI.DeleteLine(this.modelID, foundItem.expressID);
}

get<T extends WEBIFC.IfcLineObject>(item: WEBIFC.Handle<T> | T | null) {
get<T extends WEBIFC.IfcLineObject>(
item: WEBIFC.Handle<T> | T | number | null
) {
if (item === null) {
throw new Error("Item not found!");
}
if (item instanceof WEBIFC.Handle) {
return this.ifcAPI.GetLine(this.modelID, item.value) as T;
}
if (typeof item === "number") {
return this.ifcAPI.GetLine(this.modelID, item) as T;
}
return item;
}

import(data:Uint8Array)
{
if (this._modelID === undefined) {
throw new Error("Malformed model!");
}
this.ifcAPI.CloseModel(this._modelID);
this._modelID++;
this.ifcAPI.OpenModel(data);
}

update() {
if (this._modelID === undefined) {
throw new Error("Malformed model!");
Expand Down
52 changes: 52 additions & 0 deletions src/elements/Elements/Element/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,28 @@ export abstract class Element extends ClayObject {
this.type = type;
}

// static import(importedModel: Model, id: number): Element | undefined {
// const element = importedModel.get(id);

// let importedElement;
// if (element instanceof IFC.IfcWallStandardCase) {
// const wallType = SimpleWallType.import(element, importedModel);

// if (wallType) {
// importedElement = wallType.addInstance();
// const representations = importedModel.get(element.Representation);
// for (const represent of representations.Representations) {
// const foundRep = importedModel.get(represent);
// const extrusion = importedModel.get(
// foundRep.Items[0]
// ) as IFC.IfcExtrudedAreaSolid;
// importedElement.importProperties(importedModel, extrusion);
// }
// }
// }
// return importedElement;
// }

update(updateGeometry = false) {
this.updateIfcElement();
const modelID = this.model.modelID;
Expand Down Expand Up @@ -150,4 +172,34 @@ export abstract class Element extends ClayObject {
geometry.setIndex(Array.from(index));
return geometry as FRAGS.IndexedGeometry;
}

static getElevation(model: Model, elementId: number): number {
let elevation = 0;

const relationshipIDs = model.ifcAPI.GetLineIDsWithType(
model.modelID,
WEBIFC.IFCRELCONTAINEDINSPATIALSTRUCTURE
);

for (const id of relationshipIDs) {
const rel = model.get(id) as IFC.IfcRelContainedInSpatialStructure;

const relatedElemnts = rel.RelatedElements;

for (const relElement of relatedElemnts) {
const relatedElement = model.get(relElement);

if (relatedElement.expressID === elementId) {
const structure = model.get(
rel.RelatingStructure
) as IFC.IfcBuildingStorey;
if (structure && structure.Elevation) {
elevation = structure.Elevation.value;
break;
}
}
}
}
return elevation;
}
}
Loading