Open MadsHolten opened 2 years ago
Hello, I also came across "IFCCURVEBOUNDEDPLANE" geometry not being handled properly. I am parsing the geometry in a simple dedicated worker:
import { IfcAPI, Vector } from 'web-ifc/web-ifc-api';
interface UserInputModel {
name: string;
buffer: ArrayBuffer;
}
class IFCLoader {
readonly data: { [item: number]: any } = {};
private api = new IfcAPI();
constructor() {
this.api.SetWasmPath('/', true);
}
async loadIFC(name: string, buffer: ArrayBuffer) {
await this.api.Init();
console.log(this.api);
const bufferui8 = new Uint8Array(buffer);
console.log(`Loading IFC model ${name} with size ${bufferui8.length}`);
const modelID = this.api.OpenModel(bufferui8);
console.log(`Loading model ID: ${modelID}`);
const lines = this.api.GetAllLines(modelID);
this.getAllItemsFromLines(modelID, lines);
}
private getAllItemsFromLines(modelID: number, lines: Vector<number>) {
for (let i = 0; i < lines.size(); i++) {
this.saveProperties(modelID, lines, i);
}
}
private saveProperties(modelID: number, lines: Vector<number>, index: number) {
const itemID = lines.get(index);
console.log(`Loading item ID: ${itemID}`);
const props = this.api.GetLine(modelID, itemID);
props.type = props.__proto__.constructor.name;
this.data[itemID] = props;
}
}
export function parseIFC(models: UserInputModel[]) {
console.log(`Loading ${models.length} models`);
models.forEach(async (model) => {
if (model.name.endsWith('.ifc')) {
console.log(`Loading IFC model ${model.name}`);
const ifcLoader = new IFCLoader();
await ifcLoader.loadIFC(model.name, model.buffer);
console.log(ifcLoader.data);
}
});
}
self.onmessage = (e) => {
parseIFC(e.data);
};
The error I get follows:
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'map')
at 2827736869 (web-ifc-api.js:11318:115)
at IfcAPI2.GetLine (web-ifc-api.js:62076:83)
at IFCLoader.saveProperties (IFC.worker.ts?type=module&worker_file:33:28)
at IFCLoader.getAllItemsFromLines (IFC.worker.ts?type=module&worker_file:26:9)
at IFCLoader.loadIFC (IFC.worker.ts?type=module&worker_file:21:5)
at async IFC.worker.ts?type=module&worker_file:45:13
Any way I could help fixing this?
To elaborate: the typical line in .ifc
file that fails to load looks like this:
#1929=IFCCURVEBOUNDEDPLANE(#1928,#1926,$);
as the last parameter is $
, it doesn't translate to anything with the .map
attribute.
Yes - this is for some reason being processed as a mandatory field here - not optional so something is wrong. I will take a look
This should be fixed now! Please let me know if it is not
Just to understand correctly. Does this mean that Space boundary geometries (IFCRELSPACEBOUNDARY) are now being processed? If so, that's great news!
So my understanding is reading in IFCRELSPACEBOUNDARY was broken (which it was) so you should be able to read it in without errors
✅ Successfully pulled 7d06a61069be6033e06c7e6114daa9c335047051 and built it locally, after parsing a file that was previously causing problems, no errors occurred, thank you.
Would be nice to update the package on NPM so we can just update the dependency, until then we'll be using the local build.
Unfortunately I am still having problems with surface geometries of type IFCCURVEBOUNDEDPLANE and IFCSURFACEOFLINEAREXTRUSION. You can test with the below example that will fetch my demo model that contains space boundaries.
const { IfcAPI, IFCCURVEBOUNDEDPLANE, IFCSURFACEOFLINEAREXTRUSION} = require("../../dist/web-ifc-api-node.js");
console.log("Hello surface geometries!");
const ifcapi = new IfcAPI();
async function loadFile(fileURL) {
// load model data as a string
const res = await fetch(fileURL);
const arrayBuffer = await res.arrayBuffer();
const ifcData = Buffer.from( new Uint8Array(arrayBuffer) );
await ifcapi.Init();
const modelID = ifcapi.OpenModel(ifcData);
console.log(`Loaded modelID ${modelID}`);
// Get geometries of type IFCCURVEBOUNDEDPLANE
const cbps = ifcapi.GetLineIDsWithType(modelID, IFCCURVEBOUNDEDPLANE);
console.log(`Found ${cbps.size()} IFCCURVEBOUNDEDPLANEs`);
const cbpsGeometries = getFlatMeshes(modelID, cbps);
// Get geometries of type IFCSURFACEOFLINEAREXTRUSION
const soles = ifcapi.GetLineIDsWithType(modelID, IFCSURFACEOFLINEAREXTRUSION);
console.log(`Found ${soles.size()} IFCSURFACEOFLINEAREXTRUSIONs`);
const solesGeometries = getFlatMeshes(modelID, soles);
console.log(cbpsGeometries);
console.log(solesGeometries);
ifcapi.CloseModel(modelID);
console.log(`Closed model`);
}
function getFlatMeshes(modelID, items) {
let geometries = {};
for (let i = 0; i < items.size(); i++) {
const expressId = items.get(i);
const flatMesh = ifcapi.GetFlatMesh(modelID, expressId);
geometries[expressId] = [];
for (let j = 0; j < flatMesh.geometries.size(); j++) {
const geometry = ifcapi.GetGeometry(modelID, flatMesh.geometries.get(j).geometryExpressID);
const geometryVertexArray = ifcapi.GetVertexArray(geometry.GetVertexData(), geometry.GetVertexDataSize());
const geometryIndexData = ifcapi.GetIndexArray(geometry.GetIndexData(), geometry.GetIndexDataSize());
geometries[expressId].push({geometryVertexArray, geometryIndexData});
}
}
return geometries;
}
loadFile("https://raw.githubusercontent.com/MadsHolten/BOT-Duplex-house/master/Model%20files/IFC/Duplex.ifc");
I ran it from examples/nodejs both in the current main and in https://github.com/IFCjs/web-ifc/commit/7d06a61069be6033e06c7e6114daa9c335047051. Both throw "ERROR: unexpected mesh type"
Can you give me the exact error? It may be we can now parse that IFC entity but do not have the geometric decoding for it yet
I don't get more than ERROR: unexpected mesh type. Although I get it for every single element. How can I get more detailed logs?
Sorry I found it now it is actually IFCCURVEBOUNDEDPLANE that we do not support right now. I'll re-open this
I'm getting the same error with IfcRelSpaceBoundaries but with IfcFaceSurface, that is another IfcRepresentatonItem subclass, as geometric representation.
When I try to access the space boundaries' geometries I get an error "unexpected mesh type". I have tested the same model in ifcopenshell for Python where I am able to get the space boundaries, export them to STL and view them in ThreeJS.
Tested with web-ifc version 0.0.35
As I traverse through the relations I can see that the boundaries are represented by IfcSurfaceOfLinearExtrusion and IfcCurveBoundedPlane