From 2c76b8b935116ceaf1071f28b1a3cabd6043d8f9 Mon Sep 17 00:00:00 2001 From: Tom Beach Date: Tue, 12 Nov 2024 14:15:18 +0000 Subject: [PATCH] Fixes --- src/cpp/parsing/IfcLoader.cpp | 78 +++++++++++------------------- src/cpp/parsing/IfcLoader.h | 2 +- src/cpp/web-ifc-wasm.cpp | 5 -- src/ts/web-ifc-api.ts | 2 - tests/functional/WebIfcApi.spec.ts | 18 +++---- 5 files changed, 35 insertions(+), 70 deletions(-) diff --git a/src/cpp/parsing/IfcLoader.cpp b/src/cpp/parsing/IfcLoader.cpp index 061fceb0..04a7c6ea 100644 --- a/src/cpp/parsing/IfcLoader.cpp +++ b/src/cpp/parsing/IfcLoader.cpp @@ -21,6 +21,7 @@ namespace webifc::parsing { IfcLoader::IfcLoader(uint32_t tapeSize, uint32_t memoryLimit,uint32_t lineWriterBuffer, const schema::IfcSchemaManager &schemaManager) :_lineWriterBuffer(lineWriterBuffer), _schemaManager(schemaManager) { _tokenStream = new IfcTokenStream(tapeSize,memoryLimit/tapeSize); + _maxExpressId=0; } const std::vector IfcLoader::GetExpressIDsWithType(const uint32_t type) const @@ -218,7 +219,6 @@ namespace webifc::parsing { void IfcLoader::ParseLines() { - uint32_t maxExpressId = 0; uint32_t currentIfcType = 0; uint32_t currentExpressID = 0; uint32_t currentTapeOffset = 0; @@ -241,8 +241,8 @@ namespace webifc::parsing { else if (currentExpressID != 0) { _ifcTypeToExpressID[currentIfcType].push_back(currentExpressID); - maxExpressId = std::max(maxExpressId, currentExpressID); - _lines[currentExpressID-1]=l; + _maxExpressId = std::max(_maxExpressId, currentExpressID); + _lines[currentExpressID]=l; currentExpressID = 0; } currentIfcType = 0; @@ -284,31 +284,28 @@ namespace webifc::parsing { uint32_t IfcLoader::GetMaxExpressId() const { - return _lines.size(); + return _maxExpressId; } bool IfcLoader::IsValidExpressID(const uint32_t expressID) const { - if (expressID == 0 || expressID > _lines.size() || !_lines.contains(expressID-1)) return false; + if (expressID == 0 || expressID > _maxExpressId || !_lines.contains(expressID)) return false; else return true; } uint32_t IfcLoader::GetLineType(const uint32_t expressID) const { - if (expressID == 0 || expressID > _lines.size()) { + if (expressID == 0 || expressID > _maxExpressId || !_lines.contains(expressID)) { spdlog::error("[GetLineType()] Attempt to Access Invalid ExpressID {}", expressID); return 0; } - return _lines.at(expressID-1)->ifcType; + return _lines.at(expressID)->ifcType; } IfcLoader::~IfcLoader() { delete _tokenStream; - for (size_t i=0; i < _lines.size();i++) { - if (!_lines.contains(i)) continue; - delete _lines[i]; - } + for (const auto & [key, value] : _lines) delete value; for (size_t i=0; i < _headerLines.size();i++) delete _headerLines[i]; _lines.clear(); _headerLines.clear(); @@ -316,7 +313,8 @@ namespace webifc::parsing { void IfcLoader::MoveToLineArgument(const uint32_t expressID, const uint32_t argumentIndex) const { - _tokenStream->MoveTo(_lines.at(expressID-1)->tapeOffset); + if (!_lines.contains(expressID)) return; + _tokenStream->MoveTo(_lines.at(expressID)->tapeOffset); ArgumentOffset(argumentIndex); } @@ -385,15 +383,13 @@ namespace webifc::parsing { uint32_t IfcLoader::GetCurrentLineExpressID() const { if (_lines.size()==0) return 0; - uint32_t pos = _tokenStream->GetReadOffset(); uint32_t prevLine = 0; - for (size_t i=0; i < _lines.size();i++) - { - if (!_lines.contains(i)) continue; - if (_lines.at(i)->tapeOffset > pos) break; - prevLine = i; + uint32_t pos = _tokenStream->GetReadOffset(); + for (const auto & [key, value] : _lines) { + if (value->tapeOffset > pos) break; + prevLine = key; } - return prevLine+1; + return prevLine; } uint32_t IfcLoader::GetRefArgument() const @@ -420,17 +416,12 @@ namespace webifc::parsing { void IfcLoader::RemoveLine(const uint32_t expressID) { - _lines[expressID-1]->ifcType = 0; - } - - void IfcLoader::ExtendLineStorage(uint32_t lineStorageSize) - { - _lines.reserve(_lines.size()+lineStorageSize); + _lines.erase(expressID); } void IfcLoader::UpdateLineTape(const uint32_t expressID, const uint32_t type, const uint32_t start) { - if (expressID > _lines.size()) + if (!_lines.contains(expressID)) { // create line object IfcLine * line = new IfcLine(); @@ -438,10 +429,11 @@ namespace webifc::parsing { line->ifcType = type; line->tapeOffset = start; //place in vector - _lines[expressID-1]=line; + _lines[expressID]=line; _ifcTypeToExpressID[type].push_back(expressID); + if (expressID > _maxExpressId) _maxExpressId=expressID; - } else _lines[expressID-1]->tapeOffset = start; + } else _lines[expressID]->tapeOffset = start; } void IfcLoader::AddHeaderLineTape(const uint32_t type, const uint32_t start) @@ -653,8 +645,10 @@ namespace webifc::parsing { void IfcLoader::MoveToArgumentOffset(const uint32_t expressID, const uint32_t argumentIndex) const { - _tokenStream->MoveTo(_lines.at(expressID-1)->tapeOffset); - ArgumentOffset(argumentIndex); + if (_lines.contains(expressID)) { + _tokenStream->MoveTo(_lines.at(expressID)->tapeOffset); + ArgumentOffset(argumentIndex); + } } void IfcLoader::StepBack() const { @@ -680,30 +674,14 @@ namespace webifc::parsing { std::vector IfcLoader::GetAllLines() const { std::vector expressIDs; - auto numLines = GetMaxExpressId(); - for (uint32_t i = 1; i <= numLines; i++) - { - if (!IsValidExpressID(i)) continue; - expressIDs.push_back(i); - } + std::transform( _lines.begin(), _lines.end(), std::back_inserter( expressIDs ), [](auto &kv){ return kv.first;} ); return expressIDs; } uint32_t IfcLoader::GetNextExpressID(uint32_t expressId) const { - uint32_t currentId = expressId; - bool cont = true; - uint32_t maxId = GetMaxExpressId(); - - while(cont) - { - if(currentId > maxId) - { - cont = false; - continue; - } - currentId++; - cont = !(IsValidExpressID(currentId)); - } + uint32_t currentId = expressId+1; + while(!_lines.contains(currentId)) currentId++; return currentId; } + } \ No newline at end of file diff --git a/src/cpp/parsing/IfcLoader.h b/src/cpp/parsing/IfcLoader.h index a1c6aff6..bb9a9ec5 100644 --- a/src/cpp/parsing/IfcLoader.h +++ b/src/cpp/parsing/IfcLoader.h @@ -61,7 +61,6 @@ namespace webifc::parsing void RemoveLine(const uint32_t expressID); void PushDouble(double input); void PushInt(int input); - void ExtendLineStorage(uint32_t lineStorageSize); uint32_t GetNextExpressID(uint32_t expressId) const; template void Push(T input) { @@ -74,6 +73,7 @@ namespace webifc::parsing uint32_t ifcType; uint32_t tapeOffset; }; + uint32_t _maxExpressId; const uint32_t _lineWriterBuffer; const schema::IfcSchemaManager &_schemaManager; IfcTokenStream * _tokenStream; diff --git a/src/cpp/web-ifc-wasm.cpp b/src/cpp/web-ifc-wasm.cpp index 2b0ae8f6..d15bd979 100644 --- a/src/cpp/web-ifc-wasm.cpp +++ b/src/cpp/web-ifc-wasm.cpp @@ -321,10 +321,6 @@ bool ValidateExpressID(uint32_t modelID, uint32_t expressId) { return manager.IsModelOpen(modelID) ? manager.GetIfcLoader(modelID)->IsValidExpressID(expressId) : false; } -void ExtendLineStorage(uint32_t modelID, uint32_t lineStorageSize) { - if (manager.IsModelOpen(modelID)) manager.GetIfcLoader(modelID)->ExtendLineStorage(lineStorageSize); -} - uint32_t GetNextExpressID(uint32_t modelID, uint32_t expressId) { return manager.IsModelOpen(modelID) ? manager.GetIfcLoader(modelID)->GetNextExpressID(expressId) : 0; } @@ -824,7 +820,6 @@ EMSCRIPTEN_BINDINGS(my_module) { emscripten::register_vector("DoubleVector"); - emscripten::function("ExtendLineStorage", &ExtendLineStorage); emscripten::function("LoadAllGeometry", &LoadAllGeometry); emscripten::function("GetAllCrossSections", &GetAllCrossSections); emscripten::function("GetAllAlignments", &GetAllAlignments); diff --git a/src/ts/web-ifc-api.ts b/src/ts/web-ifc-api.ts index 6e1c5844..e371f317 100644 --- a/src/ts/web-ifc-api.ts +++ b/src/ts/web-ifc-api.ts @@ -587,7 +587,6 @@ export class IfcAPI { * @param lineObject array of line object to write */ WriteLines(modelID: number, lineObjects: Array) { - this.wasmModule.ExtendLineStorage(modelID,lineObjects.length); for (let lineObject of lineObjects) this.WriteLine(modelID,lineObject); } @@ -676,7 +675,6 @@ export class IfcAPI { /** @ignore */ WriteRawLinesData(modelID: number, data: Array) { - this.wasmModule.ExtendLineStorage(modelID,data.length); for (let rawLine of data) this.wasmModule.WriteLine(modelID, rawLine.ID, rawLine.type, rawLine.arguments); } diff --git a/tests/functional/WebIfcApi.spec.ts b/tests/functional/WebIfcApi.spec.ts index 7ed78404..fcfb7bde 100644 --- a/tests/functional/WebIfcApi.spec.ts +++ b/tests/functional/WebIfcApi.spec.ts @@ -426,28 +426,22 @@ describe('WebIfcApi known failures', () => { describe('some use cases', () => { test("can write a new property value and read it back in", async () => { - async function getFirstStorey(api:any, mId:any) { - const storeyIds = await api.GetLineIDsWithType(mId, WebIFC.IFCBUILDINGSTOREY); - expect(storeyIds.size()).toBe(2); - const storeyId = storeyIds.get(0); - const storey = await api.properties.getItemProperties(mId, storeyId); - return [storey, storeyId]; - } - let [storey, storeyId] = await getFirstStorey(ifcApi, modelID); + + let storey = await ifcApi.properties.getItemProperties(modelID, 138); const newStoreyName = 'Nivel 1 - Editado' storey.LongName.value = newStoreyName; ifcApi.WriteLine(modelID, storey); - storey = await ifcApi.properties.getItemProperties(modelID, storeyId); + storey = await ifcApi.properties.getItemProperties(modelID, 138); expect(storey.LongName.value).toBe(newStoreyName); const writtenData = await ifcApi.SaveModel(modelID); let modelId = ifcApi.OpenModel(writtenData); - [storey, storeyId] = await getFirstStorey(ifcApi, modelId); + storey = await ifcApi.properties.getItemProperties(modelId, 138); expect(storey.LongName.value).toBe(newStoreyName); - }); - + }) }) + describe('creating ifc', () => { test('can create new ifc model', () => { let createdID = ifcApi.CreateModel({schema: WebIFC.Schemas.IFC2X3});